<commit_before>/*
 * Copyright (c) 2011 Matt Jibson <matt.jibson@gmail.com>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package fft

import (
	"math"
	"runtime"
	"testing"

	"github.com/mjibson/go-dsp/dsputils"
)

const (
	sqrt2_2 = math.Sqrt2 / 2
)

type fftTest struct {
	in  []float64
	out []complex128
}

var fftTests = []fftTest{
	// impulse responses
	{
		[]float64{1},
		[]complex128{complex(1, 0)},
	},
	{
		[]float64{1, 0},
		[]complex128{complex(1, 0), complex(1, 0)},
	},
	{
		[]float64{1, 0, 0, 0},
		[]complex128{complex(1, 0), complex(1, 0), complex(1, 0), complex(1, 0)},
	},
	{
		[]float64{1, 0, 0, 0, 0, 0, 0, 0},
		[]complex128{
			complex(1, 0),
			complex(1, 0),
			complex(1, 0),
			complex(1, 0),
			complex(1, 0),
			complex(1, 0),
			complex(1, 0),
			complex(1, 0)},
	},

	// shifted impulse response
	{
		[]float64{0, 1},
		[]complex128{complex(1, 0), complex(-1, 0)},
	},
	{
		[]float64{0, 1, 0, 0},
		[]complex128{complex(1, 0), complex(0, -1), complex(-1, 0), complex(0, 1)},
	},
	{
		[]float64{0, 1, 0, 0, 0, 0, 0, 0},
		[]complex128{
			complex(1, 0),
			complex(sqrt2_2, -sqrt2_2),
			complex(0, -1),
			complex(-sqrt2_2, -sqrt2_2),
			complex(-1, 0),
			complex(-sqrt2_2, sqrt2_2),
			complex(0, 1),
			complex(sqrt2_2, sqrt2_2)},
	},

	// other
	{
		[]float64{1, 2, 3, 4},
		[]complex128{
			complex(10, 0),
			complex(-2, 2),
			complex(-2, 0),
			complex(-2, -2)},
	},
	{
		[]float64{1, 3, 5, 7},
		[]complex128{
			complex(16, 0),
			complex(-4, 4),
			complex(-4, 0),
			complex(-4, -4)},
	},
	{
		[]float64{1, 2, 3, 4, 5, 6, 7, 8},
		[]complex128{
			complex(36, 0),
			complex(-4, 9.65685425),
			complex(-4, 4),
			complex(-4, 1.65685425),
			complex(-4, 0),
			complex(-4, -1.65685425),
			complex(-4, -4),
			complex(-4, -9.65685425)},
	},

	// non power of 2 lengths
	{
		[]float64{1, 0, 0, 0, 0},
		[]complex128{
			complex(1, 0),
			complex(1, 0),
			complex(1, 0),
			complex(1, 0),
			complex(1, 0)},
	},
	{
		[]float64{1, 2, 3},
		[]complex128{
			complex(6, 0),
			complex(-1.5, 0.8660254),
			complex(-1.5, -0.8660254)},
	},
	{
		[]float64{1, 1, 1},
		[]complex128{
			complex(3, 0),
			complex(0, 0),
			complex(0, 0)},
	},
}

type fft2Test struct {
	in  [][]float64
	out [][]complex128
}

var fft2Tests = []fft2Test{
	{
		[][]float64{{1, 2, 3}, {3, 4, 5}},
		[][]complex128{
			{complex(18, 0), complex(-3, 1.73205081), complex(-3, -1.73205081)},
			{complex(-6, 0), complex(0, 0), complex(0, 0)}},
	},
	{
		[][]float64{{0.1, 0.2, 0.3, 0.4, 0.5}, {1, 2, 3, 4, 5}, {3, 2, 1, 0, -1}},
		[][]complex128{
			{complex(21.5, 0), complex(-0.25, 0.34409548), complex(-0.25, 0.08122992), complex(-0.25, -0.08122992), complex(-0.25, -0.34409548)},
			{complex(-8.5, -8.66025404), complex(5.70990854, 4.6742225), complex(1.15694356, 4.41135694), complex(-1.65694356, 4.24889709), complex(-6.20990854, 3.98603154)},
			{complex(-8.5, 8.66025404), complex(-6.20990854, -3.98603154), complex(-1.65694356, -4.24889709), complex(1.15694356, -4.41135694), complex(5.70990854, -4.6742225)}},
	},
}

type fftnTest struct {
	in  []float64
	dim []int
	out []complex128
}

var fftnTests = []fftnTest{
	{
		[]float64{4, 2, 3, 8, 5, 6, 7, 2, 13, 24, 13, 17},
		[]int{2, 2, 3},
		[]complex128{
			complex(104, 0), complex(12.5, 14.72243186), complex(12.5, -14.72243186),
			complex(-42, 0), complex(-10.5, 6.06217783), complex(-10.5, -6.06217783),

			complex(-48, 0), complex(-4.5, -11.25833025), complex(-4.5, 11.25833025),
			complex(22, 0), complex(8.5, -6.06217783), complex(8.5, 6.06217783)},
	},
}

type reverseBitsTest struct {
	in  uint
	sz  uint
	out uint
}

var reverseBitsTests = []reverseBitsTest{
	{0, 1, 0},
	{1, 2, 2},
	{1, 4, 8},
	{2, 4, 4},
	{3, 4, 12},
}

func TestFFT(t *testing.T) {
	for _, ft := range fftTests {
		v := FFTReal(ft.in)
		if !dsputils.PrettyCloseC(v, ft.out) {
			t.Error("FFT error\ninput:", ft.in, "\noutput:", v, "\nexpected:", ft.out)
		}

		vi := IFFT(ft.out)
		if !dsputils.PrettyCloseC(vi, dsputils.ToComplex(ft.in)) {
			t.Error("IFFT error\ninput:", ft.out, "\noutput:", vi, "\nexpected:", dsputils.ToComplex(ft.in))
		}
	}
}

func TestFFT2(t *testing.T) {
	for _, ft := range fft2Tests {
		v := FFT2Real(ft.in)
		if !dsputils.PrettyClose2(v, ft.out) {
			t.Error("FFT2 error\ninput:", ft.in, "\noutput:", v, "\nexpected:", ft.out)
		}

		vi := IFFT2(ft.out)
		if !dsputils.PrettyClose2(vi, dsputils.ToComplex2(ft.in)) {
			t.Error("IFFT2 error\ninput:", ft.out, "\noutput:", vi, "\nexpected:", dsputils.ToComplex2(ft.in))
		}
	}
}

func TestFFTN(t *testing.T) {
	for _, ft := range fftnTests {
		m := dsputils.MakeMatrix(dsputils.ToComplex(ft.in), ft.dim)
		o := dsputils.MakeMatrix(ft.out, ft.dim)
		v := FFTN(m)
		if !v.PrettyClose(o) {
			t.Error("FFTN error\ninput:", m, "\noutput:", v, "\nexpected:", o)
		}

		vi := IFFTN(o)
		if !vi.PrettyClose(m) {
			t.Error("IFFTN error\ninput:", o, "\noutput:", vi, "\nexpected:", m)
		}
	}
}

func TestReverseBits(t *testing.T) {
	for _, rt := range reverseBitsTests {
		v := reverseBits(rt.in, rt.sz)

		if v != rt.out {
			t.Error("reverse bits error\ninput:", rt.in, "\nsize:", rt.sz, "\noutput:", v, "\nexpected:", rt.out)
		}
	}
}

func TestFFTMulti(t *testing.T) {
	N := 1 << 8
	a := make([]complex128, N)
	for i := 0; i < N; i++ {
		a[i] = complex(float64(i)/float64(N), 0)
	}

	FFT(a)
}

// run with: go test -test.bench="."
func BenchmarkFFT(b *testing.B) {
	b.StopTimer()

	runtime.GOMAXPROCS(runtime.NumCPU())

	N := 1 << 20
	a := make([]complex128, N)
	for i := 0; i < N; i++ {
		a[i] = complex(float64(i)/float64(N), 0)
	}

	EnsureRadix2Factors(N)

	b.StartTimer()

	for i := 0; i < b.N; i++ {
		FFT(a)
	}
}
<commit_msg>Added example usage of FFTReal.<commit_after>/*
 * Copyright (c) 2011 Matt Jibson <matt.jibson@gmail.com>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package fft

import (
	"fmt"
	"math"
	"math/cmplx"
	"runtime"
	"testing"

	"github.com/mjibson/go-dsp/dsputils"
)

const (
	sqrt2_2 = math.Sqrt2 / 2
)

type fftTest struct {
	in  []float64
	out []complex128
}

var fftTests = []fftTest{
	// impulse responses
	{
		[]float64{1},
		[]complex128{complex(1, 0)},
	},
	{
		[]float64{1, 0},
		[]complex128{complex(1, 0), complex(1, 0)},
	},
	{
		[]float64{1, 0, 0, 0},
		[]complex128{complex(1, 0), complex(1, 0), complex(1, 0), complex(1, 0)},
	},
	{
		[]float64{1, 0, 0, 0, 0, 0, 0, 0},
		[]complex128{
			complex(1, 0),
			complex(1, 0),
			complex(1, 0),
			complex(1, 0),
			complex(1, 0),
			complex(1, 0),
			complex(1, 0),
			complex(1, 0)},
	},

	// shifted impulse response
	{
		[]float64{0, 1},
		[]complex128{complex(1, 0), complex(-1, 0)},
	},
	{
		[]float64{0, 1, 0, 0},
		[]complex128{complex(1, 0), complex(0, -1), complex(-1, 0), complex(0, 1)},
	},
	{
		[]float64{0, 1, 0, 0, 0, 0, 0, 0},
		[]complex128{
			complex(1, 0),
			complex(sqrt2_2, -sqrt2_2),
			complex(0, -1),
			complex(-sqrt2_2, -sqrt2_2),
			complex(-1, 0),
			complex(-sqrt2_2, sqrt2_2),
			complex(0, 1),
			complex(sqrt2_2, sqrt2_2)},
	},

	// other
	{
		[]float64{1, 2, 3, 4},
		[]complex128{
			complex(10, 0),
			complex(-2, 2),
			complex(-2, 0),
			complex(-2, -2)},
	},
	{
		[]float64{1, 3, 5, 7},
		[]complex128{
			complex(16, 0),
			complex(-4, 4),
			complex(-4, 0),
			complex(-4, -4)},
	},
	{
		[]float64{1, 2, 3, 4, 5, 6, 7, 8},
		[]complex128{
			complex(36, 0),
			complex(-4, 9.65685425),
			complex(-4, 4),
			complex(-4, 1.65685425),
			complex(-4, 0),
			complex(-4, -1.65685425),
			complex(-4, -4),
			complex(-4, -9.65685425)},
	},

	// non power of 2 lengths
	{
		[]float64{1, 0, 0, 0, 0},
		[]complex128{
			complex(1, 0),
			complex(1, 0),
			complex(1, 0),
			complex(1, 0),
			complex(1, 0)},
	},
	{
		[]float64{1, 2, 3},
		[]complex128{
			complex(6, 0),
			complex(-1.5, 0.8660254),
			complex(-1.5, -0.8660254)},
	},
	{
		[]float64{1, 1, 1},
		[]complex128{
			complex(3, 0),
			complex(0, 0),
			complex(0, 0)},
	},
}

type fft2Test struct {
	in  [][]float64
	out [][]complex128
}

var fft2Tests = []fft2Test{
	{
		[][]float64{{1, 2, 3}, {3, 4, 5}},
		[][]complex128{
			{complex(18, 0), complex(-3, 1.73205081), complex(-3, -1.73205081)},
			{complex(-6, 0), complex(0, 0), complex(0, 0)}},
	},
	{
		[][]float64{{0.1, 0.2, 0.3, 0.4, 0.5}, {1, 2, 3, 4, 5}, {3, 2, 1, 0, -1}},
		[][]complex128{
			{complex(21.5, 0), complex(-0.25, 0.34409548), complex(-0.25, 0.08122992), complex(-0.25, -0.08122992), complex(-0.25, -0.34409548)},
			{complex(-8.5, -8.66025404), complex(5.70990854, 4.6742225), complex(1.15694356, 4.41135694), complex(-1.65694356, 4.24889709), complex(-6.20990854, 3.98603154)},
			{complex(-8.5, 8.66025404), complex(-6.20990854, -3.98603154), complex(-1.65694356, -4.24889709), complex(1.15694356, -4.41135694), complex(5.70990854, -4.6742225)}},
	},
}

type fftnTest struct {
	in  []float64
	dim []int
	out []complex128
}

var fftnTests = []fftnTest{
	{
		[]float64{4, 2, 3, 8, 5, 6, 7, 2, 13, 24, 13, 17},
		[]int{2, 2, 3},
		[]complex128{
			complex(104, 0), complex(12.5, 14.72243186), complex(12.5, -14.72243186),
			complex(-42, 0), complex(-10.5, 6.06217783), complex(-10.5, -6.06217783),

			complex(-48, 0), complex(-4.5, -11.25833025), complex(-4.5, 11.25833025),
			complex(22, 0), complex(8.5, -6.06217783), complex(8.5, 6.06217783)},
	},
}

type reverseBitsTest struct {
	in  uint
	sz  uint
	out uint
}

var reverseBitsTests = []reverseBitsTest{
	{0, 1, 0},
	{1, 2, 2},
	{1, 4, 8},
	{2, 4, 4},
	{3, 4, 12},
}

func TestFFT(t *testing.T) {
	for _, ft := range fftTests {
		v := FFTReal(ft.in)
		if !dsputils.PrettyCloseC(v, ft.out) {
			t.Error("FFT error\ninput:", ft.in, "\noutput:", v, "\nexpected:", ft.out)
		}

		vi := IFFT(ft.out)
		if !dsputils.PrettyCloseC(vi, dsputils.ToComplex(ft.in)) {
			t.Error("IFFT error\ninput:", ft.out, "\noutput:", vi, "\nexpected:", dsputils.ToComplex(ft.in))
		}
	}
}

func TestFFT2(t *testing.T) {
	for _, ft := range fft2Tests {
		v := FFT2Real(ft.in)
		if !dsputils.PrettyClose2(v, ft.out) {
			t.Error("FFT2 error\ninput:", ft.in, "\noutput:", v, "\nexpected:", ft.out)
		}

		vi := IFFT2(ft.out)
		if !dsputils.PrettyClose2(vi, dsputils.ToComplex2(ft.in)) {
			t.Error("IFFT2 error\ninput:", ft.out, "\noutput:", vi, "\nexpected:", dsputils.ToComplex2(ft.in))
		}
	}
}

func TestFFTN(t *testing.T) {
	for _, ft := range fftnTests {
		m := dsputils.MakeMatrix(dsputils.ToComplex(ft.in), ft.dim)
		o := dsputils.MakeMatrix(ft.out, ft.dim)
		v := FFTN(m)
		if !v.PrettyClose(o) {
			t.Error("FFTN error\ninput:", m, "\noutput:", v, "\nexpected:", o)
		}

		vi := IFFTN(o)
		if !vi.PrettyClose(m) {
			t.Error("IFFTN error\ninput:", o, "\noutput:", vi, "\nexpected:", m)
		}
	}
}

func TestReverseBits(t *testing.T) {
	for _, rt := range reverseBitsTests {
		v := reverseBits(rt.in, rt.sz)

		if v != rt.out {
			t.Error("reverse bits error\ninput:", rt.in, "\nsize:", rt.sz, "\noutput:", v, "\nexpected:", rt.out)
		}
	}
}

func TestFFTMulti(t *testing.T) {
	N := 1 << 8
	a := make([]complex128, N)
	for i := 0; i < N; i++ {
		a[i] = complex(float64(i)/float64(N), 0)
	}

	FFT(a)
}

// run with: go test -test.bench="."
func BenchmarkFFT(b *testing.B) {
	b.StopTimer()

	runtime.GOMAXPROCS(runtime.NumCPU())

	N := 1 << 20
	a := make([]complex128, N)
	for i := 0; i < N; i++ {
		a[i] = complex(float64(i)/float64(N), 0)
	}

	EnsureRadix2Factors(N)

	b.StartTimer()

	for i := 0; i < b.N; i++ {
		FFT(a)
	}
}

// This example is adapted from Richard Lyon's "Understanding Digital Signal Processing," section 3.1.1.
func ExampleFFTReal() {
	numSamples := 8

	// Equation 3-10.
	x := func(n int) float64 {
		wave0 := math.Sin(2.0 * math.Pi * float64(n) / 8.0)
		wave1 := 0.5 * math.Sin(2*math.Pi*float64(n)/4.0+3.0*math.Pi/4.0)
		return wave0 + wave1
	}

	// Discretize our function by sampling at 8 points.
	a := make([]float64, numSamples)
	for i := 0; i < numSamples; i++ {
		a[i] = x(i)
	}

	X := FFTReal(a)

	// Print the magnitude and phase at each frequencey.
	for i := 0; i < numSamples; i++ {
		r, θ := cmplx.Polar(X[i])
		θ *= 360.0 / (2 * math.Pi)
		if dsputils.Float64Equal(r, 0) {
			θ = 0 // (When the magnitude is close to 0, the angle is meaningless)
		}
		fmt.Printf("X(%d) = %.1f ∠ %.1f°\n", i, r, θ)
	}

	// Output:
	// X(0) = 0.0 ∠ 0.0°
	// X(1) = 4.0 ∠ -90.0°
	// X(2) = 2.0 ∠ 45.0°
	// X(3) = 0.0 ∠ 0.0°
	// X(4) = 0.0 ∠ 0.0°
	// X(5) = 0.0 ∠ 0.0°
	// X(6) = 2.0 ∠ -45.0°
	// X(7) = 4.0 ∠ 90.0°
}
<|endoftext|>


<commit_before>/*
Copyright 2014 The Kubernetes Authors All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package api_test

import (
	"encoding/json"

	"math/rand"
	"reflect"
	"testing"

	"github.com/davecgh/go-spew/spew"
	"k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/api/latest"
	"k8s.io/kubernetes/pkg/api/meta"
	"k8s.io/kubernetes/pkg/api/testapi"
	apitesting "k8s.io/kubernetes/pkg/api/testing"
	"k8s.io/kubernetes/pkg/runtime"
	"k8s.io/kubernetes/pkg/util"

	_ "k8s.io/kubernetes/pkg/expapi"
	_ "k8s.io/kubernetes/pkg/expapi/v1"

	flag "github.com/spf13/pflag"
)

var fuzzIters = flag.Int("fuzz-iters", 20, "How many fuzzing iterations to do.")

func fuzzInternalObject(t *testing.T, forVersion string, item runtime.Object, seed int64) runtime.Object {
	apitesting.FuzzerFor(t, forVersion, rand.NewSource(seed)).Fuzz(item)

	j, err := meta.TypeAccessor(item)
	if err != nil {
		t.Fatalf("Unexpected error %v for %#v", err, item)
	}
	j.SetKind("")
	j.SetAPIVersion("")

	return item
}

func roundTrip(t *testing.T, codec runtime.Codec, item runtime.Object) {
	printer := spew.ConfigState{DisableMethods: true}

	name := reflect.TypeOf(item).Elem().Name()
	data, err := codec.Encode(item)
	if err != nil {
		t.Errorf("%v: %v (%s)", name, err, printer.Sprintf("%#v", item))
		return
	}

	obj2, err := codec.Decode(data)
	if err != nil {
		t.Errorf("0: %v: %v\nCodec: %v\nData: %s\nSource: %#v", name, err, codec, string(data), printer.Sprintf("%#v", item))
		return
	}
	if !api.Semantic.DeepEqual(item, obj2) {
		t.Errorf("1: %v: diff: %v\nCodec: %v\nData: %s\nSource: %#v\nFinal: %#v", name, util.ObjectGoPrintDiff(item, obj2), codec, string(data), printer.Sprintf("%#v", item), printer.Sprintf("%#v", obj2))
		return
	}

	obj3 := reflect.New(reflect.TypeOf(item).Elem()).Interface().(runtime.Object)
	err = codec.DecodeInto(data, obj3)
	if err != nil {
		t.Errorf("2: %v: %v", name, err)
		return
	}
	if !api.Semantic.DeepEqual(item, obj3) {
		t.Errorf("3: %v: diff: %v\nCodec: %v", name, util.ObjectDiff(item, obj3), codec)
		return
	}
}

// roundTripSame verifies the same source object is tested in all API versions.
func roundTripSame(t *testing.T, item runtime.Object, except ...string) {
	set := util.NewStringSet(except...)
	seed := rand.Int63()
	fuzzInternalObject(t, "", item, seed)
	version := testapi.Version()
	if !set.Has(version) {
		fuzzInternalObject(t, version, item, seed)
		roundTrip(t, testapi.Codec(), item)
	}
}

// For debugging problems
func TestSpecificKind(t *testing.T) {
	api.Scheme.Log(t)
	defer api.Scheme.Log(nil)

	kind := "PodList"
	item, err := api.Scheme.New("", kind)
	if err != nil {
		t.Errorf("Couldn't make a %v? %v", kind, err)
		return
	}
	roundTripSame(t, item)
}

func TestList(t *testing.T) {
	api.Scheme.Log(t)
	defer api.Scheme.Log(nil)

	kind := "List"
	item, err := api.Scheme.New("", kind)
	if err != nil {
		t.Errorf("Couldn't make a %v? %v", kind, err)
		return
	}
	roundTripSame(t, item)
}

var nonRoundTrippableTypes = util.NewStringSet("ThirdPartyResource")
var nonInternalRoundTrippableTypes = util.NewStringSet("List", "ListOptions", "PodExecOptions", "PodAttachOptions")
var nonRoundTrippableTypesByVersion = map[string][]string{}

func TestRoundTripTypes(t *testing.T) {
	// api.Scheme.Log(t)
	// defer api.Scheme.Log(nil)

	for kind := range api.Scheme.KnownTypes("") {
		if nonRoundTrippableTypes.Has(kind) {
			continue
		}
		// Try a few times, since runTest uses random values.
		for i := 0; i < *fuzzIters; i++ {
			item, err := api.Scheme.New("", kind)
			if err != nil {
				t.Fatalf("Couldn't make a %v? %v", kind, err)
			}
			if _, err := meta.TypeAccessor(item); err != nil {
				t.Fatalf("%q is not a TypeMeta and cannot be tested - add it to nonRoundTrippableTypes: %v", kind, err)
			}
			roundTripSame(t, item, nonRoundTrippableTypesByVersion[kind]...)
			if !nonInternalRoundTrippableTypes.Has(kind) {
				roundTrip(t, api.Codec, fuzzInternalObject(t, "", item, rand.Int63()))
			}
		}
	}
}

func TestEncode_Ptr(t *testing.T) {
	grace := int64(30)
	pod := &api.Pod{
		ObjectMeta: api.ObjectMeta{
			Labels: map[string]string{"name": "foo"},
		},
		Spec: api.PodSpec{
			RestartPolicy: api.RestartPolicyAlways,
			DNSPolicy:     api.DNSClusterFirst,

			TerminationGracePeriodSeconds: &grace,
		},
	}
	obj := runtime.Object(pod)
	data, err := latest.Codec.Encode(obj)
	obj2, err2 := latest.Codec.Decode(data)
	if err != nil || err2 != nil {
		t.Fatalf("Failure: '%v' '%v'", err, err2)
	}
	if _, ok := obj2.(*api.Pod); !ok {
		t.Fatalf("Got wrong type")
	}
	if !api.Semantic.DeepEqual(obj2, pod) {
		t.Errorf("Expected:\n %#v,\n Got:\n %#v", pod, obj2)
	}
}

func TestBadJSONRejection(t *testing.T) {
	badJSONMissingKind := []byte(`{ }`)
	if _, err := latest.Codec.Decode(badJSONMissingKind); err == nil {
		t.Errorf("Did not reject despite lack of kind field: %s", badJSONMissingKind)
	}
	badJSONUnknownType := []byte(`{"kind": "bar"}`)
	if _, err1 := latest.Codec.Decode(badJSONUnknownType); err1 == nil {
		t.Errorf("Did not reject despite use of unknown type: %s", badJSONUnknownType)
	}
	/*badJSONKindMismatch := []byte(`{"kind": "Pod"}`)
	if err2 := DecodeInto(badJSONKindMismatch, &Minion{}); err2 == nil {
		t.Errorf("Kind is set but doesn't match the object type: %s", badJSONKindMismatch)
	}*/
}

const benchmarkSeed = 100

func BenchmarkEncode(b *testing.B) {
	pod := api.Pod{}
	apiObjectFuzzer := apitesting.FuzzerFor(nil, "", rand.NewSource(benchmarkSeed))
	apiObjectFuzzer.Fuzz(&pod)
	for i := 0; i < b.N; i++ {
		latest.Codec.Encode(&pod)
	}
}

// BenchmarkEncodeJSON provides a baseline for regular JSON encode performance
func BenchmarkEncodeJSON(b *testing.B) {
	pod := api.Pod{}
	apiObjectFuzzer := apitesting.FuzzerFor(nil, "", rand.NewSource(benchmarkSeed))
	apiObjectFuzzer.Fuzz(&pod)
	for i := 0; i < b.N; i++ {
		json.Marshal(&pod)
	}
}

func BenchmarkDecode(b *testing.B) {
	pod := api.Pod{}
	apiObjectFuzzer := apitesting.FuzzerFor(nil, "", rand.NewSource(benchmarkSeed))
	apiObjectFuzzer.Fuzz(&pod)
	data, _ := latest.Codec.Encode(&pod)
	for i := 0; i < b.N; i++ {
		latest.Codec.Decode(data)
	}
}

func BenchmarkDecodeInto(b *testing.B) {
	pod := api.Pod{}
	apiObjectFuzzer := apitesting.FuzzerFor(nil, "", rand.NewSource(benchmarkSeed))
	apiObjectFuzzer.Fuzz(&pod)
	data, _ := latest.Codec.Encode(&pod)
	for i := 0; i < b.N; i++ {
		obj := api.Pod{}
		latest.Codec.DecodeInto(data, &obj)
	}
}

// BenchmarkDecodeJSON provides a baseline for regular JSON decode performance
func BenchmarkDecodeJSON(b *testing.B) {
	pod := api.Pod{}
	apiObjectFuzzer := apitesting.FuzzerFor(nil, "", rand.NewSource(benchmarkSeed))
	apiObjectFuzzer.Fuzz(&pod)
	data, _ := latest.Codec.Encode(&pod)
	for i := 0; i < b.N; i++ {
		obj := api.Pod{}
		json.Unmarshal(data, &obj)
	}
}
<commit_msg>Serialization_test quick fix (remove exapi)<commit_after>/*
Copyright 2014 The Kubernetes Authors All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package api_test

import (
	"encoding/json"

	"math/rand"
	"reflect"
	"testing"

	"github.com/davecgh/go-spew/spew"
	"k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/api/latest"
	"k8s.io/kubernetes/pkg/api/meta"
	"k8s.io/kubernetes/pkg/api/testapi"
	apitesting "k8s.io/kubernetes/pkg/api/testing"
	"k8s.io/kubernetes/pkg/runtime"
	"k8s.io/kubernetes/pkg/util"

	// TODO: enable when exapi problems are fixed #13083
	//_ "k8s.io/kubernetes/pkg/expapi"
	//_ "k8s.io/kubernetes/pkg/expapi/v1"

	flag "github.com/spf13/pflag"
)

var fuzzIters = flag.Int("fuzz-iters", 20, "How many fuzzing iterations to do.")

func fuzzInternalObject(t *testing.T, forVersion string, item runtime.Object, seed int64) runtime.Object {
	apitesting.FuzzerFor(t, forVersion, rand.NewSource(seed)).Fuzz(item)

	j, err := meta.TypeAccessor(item)
	if err != nil {
		t.Fatalf("Unexpected error %v for %#v", err, item)
	}
	j.SetKind("")
	j.SetAPIVersion("")

	return item
}

func roundTrip(t *testing.T, codec runtime.Codec, item runtime.Object) {
	printer := spew.ConfigState{DisableMethods: true}

	name := reflect.TypeOf(item).Elem().Name()
	data, err := codec.Encode(item)
	if err != nil {
		t.Errorf("%v: %v (%s)", name, err, printer.Sprintf("%#v", item))
		return
	}

	obj2, err := codec.Decode(data)
	if err != nil {
		t.Errorf("0: %v: %v\nCodec: %v\nData: %s\nSource: %#v", name, err, codec, string(data), printer.Sprintf("%#v", item))
		return
	}
	if !api.Semantic.DeepEqual(item, obj2) {
		t.Errorf("1: %v: diff: %v\nCodec: %v\nData: %s\nSource: %#v\nFinal: %#v", name, util.ObjectGoPrintDiff(item, obj2), codec, string(data), printer.Sprintf("%#v", item), printer.Sprintf("%#v", obj2))
		return
	}

	obj3 := reflect.New(reflect.TypeOf(item).Elem()).Interface().(runtime.Object)
	err = codec.DecodeInto(data, obj3)
	if err != nil {
		t.Errorf("2: %v: %v", name, err)
		return
	}
	if !api.Semantic.DeepEqual(item, obj3) {
		t.Errorf("3: %v: diff: %v\nCodec: %v", name, util.ObjectDiff(item, obj3), codec)
		return
	}
}

// roundTripSame verifies the same source object is tested in all API versions.
func roundTripSame(t *testing.T, item runtime.Object, except ...string) {
	set := util.NewStringSet(except...)
	seed := rand.Int63()
	fuzzInternalObject(t, "", item, seed)
	version := testapi.Version()
	if !set.Has(version) {
		fuzzInternalObject(t, version, item, seed)
		roundTrip(t, testapi.Codec(), item)
	}
}

// For debugging problems
func TestSpecificKind(t *testing.T) {
	api.Scheme.Log(t)
	defer api.Scheme.Log(nil)

	kind := "PodList"
	item, err := api.Scheme.New("", kind)
	if err != nil {
		t.Errorf("Couldn't make a %v? %v", kind, err)
		return
	}
	roundTripSame(t, item)
}

func TestList(t *testing.T) {
	api.Scheme.Log(t)
	defer api.Scheme.Log(nil)

	kind := "List"
	item, err := api.Scheme.New("", kind)
	if err != nil {
		t.Errorf("Couldn't make a %v? %v", kind, err)
		return
	}
	roundTripSame(t, item)
}

var nonRoundTrippableTypes = util.NewStringSet("ThirdPartyResource")
var nonInternalRoundTrippableTypes = util.NewStringSet("List", "ListOptions", "PodExecOptions", "PodAttachOptions")
var nonRoundTrippableTypesByVersion = map[string][]string{}

func TestRoundTripTypes(t *testing.T) {
	// api.Scheme.Log(t)
	// defer api.Scheme.Log(nil)

	for kind := range api.Scheme.KnownTypes("") {
		if nonRoundTrippableTypes.Has(kind) {
			continue
		}
		// Try a few times, since runTest uses random values.
		for i := 0; i < *fuzzIters; i++ {
			item, err := api.Scheme.New("", kind)
			if err != nil {
				t.Fatalf("Couldn't make a %v? %v", kind, err)
			}
			if _, err := meta.TypeAccessor(item); err != nil {
				t.Fatalf("%q is not a TypeMeta and cannot be tested - add it to nonRoundTrippableTypes: %v", kind, err)
			}
			roundTripSame(t, item, nonRoundTrippableTypesByVersion[kind]...)
			if !nonInternalRoundTrippableTypes.Has(kind) {
				roundTrip(t, api.Codec, fuzzInternalObject(t, "", item, rand.Int63()))
			}
		}
	}
}

func TestEncode_Ptr(t *testing.T) {
	grace := int64(30)
	pod := &api.Pod{
		ObjectMeta: api.ObjectMeta{
			Labels: map[string]string{"name": "foo"},
		},
		Spec: api.PodSpec{
			RestartPolicy: api.RestartPolicyAlways,
			DNSPolicy:     api.DNSClusterFirst,

			TerminationGracePeriodSeconds: &grace,
		},
	}
	obj := runtime.Object(pod)
	data, err := latest.Codec.Encode(obj)
	obj2, err2 := latest.Codec.Decode(data)
	if err != nil || err2 != nil {
		t.Fatalf("Failure: '%v' '%v'", err, err2)
	}
	if _, ok := obj2.(*api.Pod); !ok {
		t.Fatalf("Got wrong type")
	}
	if !api.Semantic.DeepEqual(obj2, pod) {
		t.Errorf("Expected:\n %#v,\n Got:\n %#v", pod, obj2)
	}
}

func TestBadJSONRejection(t *testing.T) {
	badJSONMissingKind := []byte(`{ }`)
	if _, err := latest.Codec.Decode(badJSONMissingKind); err == nil {
		t.Errorf("Did not reject despite lack of kind field: %s", badJSONMissingKind)
	}
	badJSONUnknownType := []byte(`{"kind": "bar"}`)
	if _, err1 := latest.Codec.Decode(badJSONUnknownType); err1 == nil {
		t.Errorf("Did not reject despite use of unknown type: %s", badJSONUnknownType)
	}
	/*badJSONKindMismatch := []byte(`{"kind": "Pod"}`)
	if err2 := DecodeInto(badJSONKindMismatch, &Minion{}); err2 == nil {
		t.Errorf("Kind is set but doesn't match the object type: %s", badJSONKindMismatch)
	}*/
}

const benchmarkSeed = 100

func BenchmarkEncode(b *testing.B) {
	pod := api.Pod{}
	apiObjectFuzzer := apitesting.FuzzerFor(nil, "", rand.NewSource(benchmarkSeed))
	apiObjectFuzzer.Fuzz(&pod)
	for i := 0; i < b.N; i++ {
		latest.Codec.Encode(&pod)
	}
}

// BenchmarkEncodeJSON provides a baseline for regular JSON encode performance
func BenchmarkEncodeJSON(b *testing.B) {
	pod := api.Pod{}
	apiObjectFuzzer := apitesting.FuzzerFor(nil, "", rand.NewSource(benchmarkSeed))
	apiObjectFuzzer.Fuzz(&pod)
	for i := 0; i < b.N; i++ {
		json.Marshal(&pod)
	}
}

func BenchmarkDecode(b *testing.B) {
	pod := api.Pod{}
	apiObjectFuzzer := apitesting.FuzzerFor(nil, "", rand.NewSource(benchmarkSeed))
	apiObjectFuzzer.Fuzz(&pod)
	data, _ := latest.Codec.Encode(&pod)
	for i := 0; i < b.N; i++ {
		latest.Codec.Decode(data)
	}
}

func BenchmarkDecodeInto(b *testing.B) {
	pod := api.Pod{}
	apiObjectFuzzer := apitesting.FuzzerFor(nil, "", rand.NewSource(benchmarkSeed))
	apiObjectFuzzer.Fuzz(&pod)
	data, _ := latest.Codec.Encode(&pod)
	for i := 0; i < b.N; i++ {
		obj := api.Pod{}
		latest.Codec.DecodeInto(data, &obj)
	}
}

// BenchmarkDecodeJSON provides a baseline for regular JSON decode performance
func BenchmarkDecodeJSON(b *testing.B) {
	pod := api.Pod{}
	apiObjectFuzzer := apitesting.FuzzerFor(nil, "", rand.NewSource(benchmarkSeed))
	apiObjectFuzzer.Fuzz(&pod)
	data, _ := latest.Codec.Encode(&pod)
	for i := 0; i < b.N; i++ {
		obj := api.Pod{}
		json.Unmarshal(data, &obj)
	}
}
<|endoftext|>


<commit_before>package crank

import (
	"io"
	"log"
	"os"
	"strings"
	"syscall"
)

// TODO: The notifier can potentially have other notifications than "ready".
//       Eg: heartbeat

// Gets a channel on which to publish events.
//
// Returns a file on which the process is supposed to write data, which then
// translate into these events.
func startProcessNotifier(ready chan<- bool) (w *os.File, err error) {
	fds, err := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_STREAM, 0)
	if err != nil {
		return
	}
	r := os.NewFile(uintptr(fds[0]), "notify:r") // File name is arbitrary
	w = os.NewFile(uintptr(fds[1]), "notify:w")

	go runProcessNotifier(r, ready)

	return w, nil
}

func runProcessNotifier(r *os.File, ready chan<- bool) {
	// Read on pipe from child, and process commands
	defer r.Close()
	defer close(ready)

	var err error
	var command string
	var n int
	data := make([]byte, 4096)

	for {
		n, err = r.Read(data)
		if err == io.EOF {
			return
		}
		if err != nil {
			fail("Reading on pipe", err)
			return
		}

		command = strings.TrimSpace(string(data[:n]))

		switch command {
		case "READY=1":
			ready <- true
		default:
			log.Println("Unknown command received: ", command)
		}
	}
}
<commit_msg>Actually SOCK_DGRAM like I said we would...<commit_after>package crank

import (
	"io"
	"log"
	"os"
	"strings"
	"syscall"
)

// TODO: The notifier can potentially have other notifications than "ready".
//       Eg: heartbeat

// Gets a channel on which to publish events.
//
// Returns a file on which the process is supposed to write data, which then
// translate into these events.
func startProcessNotifier(ready chan<- bool) (w *os.File, err error) {
	fds, err := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_DGRAM, 0)
	if err != nil {
		return
	}
	r := os.NewFile(uintptr(fds[0]), "notify:r") // File name is arbitrary
	w = os.NewFile(uintptr(fds[1]), "notify:w")

	go runProcessNotifier(r, ready)

	return w, nil
}

func runProcessNotifier(r *os.File, ready chan<- bool) {
	// Read on pipe from child, and process commands
	defer r.Close()
	defer close(ready)

	var err error
	var command string
	var n int
	data := make([]byte, 4096)

	for {
		n, err = r.Read(data)
		if err == io.EOF {
			return
		}
		if err != nil {
			fail("Reading on notify socket", err)
			return
		}

		command = strings.TrimSpace(string(data[:n]))

		switch command {
		case "READY=1":
			ready <- true
		default:
			log.Println("Unknown command received: ", command)
		}
	}
}
<|endoftext|>


<commit_before>package finder

import (
	"bytes"
	"context"
	"fmt"
	"strings"
	"time"

	"github.com/lomik/graphite-clickhouse/helper/clickhouse"
)

const ReverseLevelOffset = 10000
const TreeLevelOffset = 20000
const ReverseTreeLevelOffset = 30000

const DefaultTreeDate = "1970-02-12"

type IndexFinder struct {
	url          string             // clickhouse dsn
	table        string             // graphite_tree table
	opts         clickhouse.Options // timeout, connectTimeout
	dailyEnabled bool
	body         []byte // clickhouse response body
	useReverse   bool
	useDaily     bool
}

func NewIndex(url string, table string, dailyEnabled bool, opts clickhouse.Options) Finder {
	return &IndexFinder{
		url:          url,
		table:        table,
		opts:         opts,
		dailyEnabled: dailyEnabled,
	}
}

func (idx *IndexFinder) where(query string, levelOffset int) *Where {
	level := strings.Count(query, ".") + 1

	w := NewWhere()

	w.Andf("Level = %d", level+levelOffset)

	if query == "*" {
		return w
	}

	// simple metric
	if !HasWildcard(query) {
		w.Andf("Path = %s OR Path = %s", Q(query), Q(query+"."))
		return w
	}

	// before any wildcard symbol
	simplePrefix := query[:strings.IndexAny(query, "[]{}*?")]

	if len(simplePrefix) > 0 {
		w.Andf("Path LIKE %s", Q(likeEscape(simplePrefix)+`%`))
	}

	// prefix search like "metric.name.xx*"
	if len(simplePrefix) == len(query)-1 && query[len(query)-1] == '*' {
		return w
	}

	// Q() replaces \ with \\, so using \. does not work here.
	// work around with [.]
	w.Andf("match(Path, %s)", Q(`^`+GlobToRegexp(query)+`[.]?$`))
	return w
}

func (idx *IndexFinder) Execute(ctx context.Context, query string, from int64, until int64) (err error) {
	p := strings.LastIndexByte(query, '.')

	if p < 0 || p >= len(query)-1 || HasWildcard(query[p+1:]) {
		idx.useReverse = false
	} else {
		idx.useReverse = true
	}

	if idx.dailyEnabled && from > 0 && until > 0 {
		idx.useDaily = true
	} else {
		idx.useDaily = false
	}

	var levelOffset int
	if idx.useDaily {
		if idx.useReverse {
			levelOffset = ReverseLevelOffset
		}
	} else {
		if idx.useReverse {
			levelOffset = ReverseTreeLevelOffset
		} else {
			levelOffset = TreeLevelOffset
		}
	}

	where := idx.where(query, levelOffset)

	if idx.useDaily {
		where.Andf(
			"Date >='%s' AND Date <= '%s'",
			time.Unix(from, 0).Format("2006-01-02"),
			time.Unix(until, 0).Format("2006-01-02"),
		)
	}

	idx.body, err = clickhouse.Query(
		ctx,
		idx.url,
		fmt.Sprintf("SELECT Path FROM %s WHERE %s GROUP BY Path", idx.table, where),
		idx.table,
		idx.opts,
	)

	return
}

func (idx *IndexFinder) Abs(v []byte) []byte {
	return v
}

func (idx *IndexFinder) makeList(onlySeries bool) [][]byte {
	if idx.body == nil {
		return [][]byte{}
	}

	rows := bytes.Split(idx.body, []byte{'\n'})

	skip := 0
	for i := 0; i < len(rows); i++ {
		if len(rows[i]) == 0 {
			skip++
			continue
		}
		if onlySeries && rows[i][len(rows[i])-1] == '.' {
			skip++
			continue
		}
		if skip > 0 {
			rows[i-skip] = rows[i]
		}
	}

	rows = rows[:len(rows)-skip]

	if idx.useReverse {
		for i := 0; i < len(rows); i++ {
			rows[i] = ReverseBytes(rows[i])
		}
	}

	return rows
}

func (idx *IndexFinder) List() [][]byte {
	return idx.makeList(false)
}

func (idx *IndexFinder) Series() [][]byte {
	return idx.makeList(true)
}
<commit_msg>missed reverse query<commit_after>package finder

import (
	"bytes"
	"context"
	"fmt"
	"strings"
	"time"

	"github.com/lomik/graphite-clickhouse/helper/clickhouse"
)

const ReverseLevelOffset = 10000
const TreeLevelOffset = 20000
const ReverseTreeLevelOffset = 30000

const DefaultTreeDate = "1970-02-12"

type IndexFinder struct {
	url          string             // clickhouse dsn
	table        string             // graphite_tree table
	opts         clickhouse.Options // timeout, connectTimeout
	dailyEnabled bool
	body         []byte // clickhouse response body
	useReverse   bool
	useDaily     bool
}

func NewIndex(url string, table string, dailyEnabled bool, opts clickhouse.Options) Finder {
	return &IndexFinder{
		url:          url,
		table:        table,
		opts:         opts,
		dailyEnabled: dailyEnabled,
	}
}

func (idx *IndexFinder) where(query string, levelOffset int) *Where {
	level := strings.Count(query, ".") + 1

	w := NewWhere()

	w.Andf("Level = %d", level+levelOffset)

	if query == "*" {
		return w
	}

	// simple metric
	if !HasWildcard(query) {
		w.Andf("Path = %s OR Path = %s", Q(query), Q(query+"."))
		return w
	}

	// before any wildcard symbol
	simplePrefix := query[:strings.IndexAny(query, "[]{}*?")]

	if len(simplePrefix) > 0 {
		w.Andf("Path LIKE %s", Q(likeEscape(simplePrefix)+`%`))
	}

	// prefix search like "metric.name.xx*"
	if len(simplePrefix) == len(query)-1 && query[len(query)-1] == '*' {
		return w
	}

	// Q() replaces \ with \\, so using \. does not work here.
	// work around with [.]
	w.Andf("match(Path, %s)", Q(`^`+GlobToRegexp(query)+`[.]?$`))
	return w
}

func (idx *IndexFinder) Execute(ctx context.Context, query string, from int64, until int64) (err error) {
	p := strings.LastIndexByte(query, '.')

	if p < 0 || p >= len(query)-1 || HasWildcard(query[p+1:]) {
		idx.useReverse = false
	} else {
		idx.useReverse = true
	}

	if idx.dailyEnabled && from > 0 && until > 0 {
		idx.useDaily = true
	} else {
		idx.useDaily = false
	}

	var levelOffset int
	if idx.useDaily {
		if idx.useReverse {
			levelOffset = ReverseLevelOffset
		}
	} else {
		if idx.useReverse {
			levelOffset = ReverseTreeLevelOffset
		} else {
			levelOffset = TreeLevelOffset
		}
	}

	if idx.useReverse {
		query = ReverseString(query)
	}

	where := idx.where(query, levelOffset)

	if idx.useDaily {
		where.Andf(
			"Date >='%s' AND Date <= '%s'",
			time.Unix(from, 0).Format("2006-01-02"),
			time.Unix(until, 0).Format("2006-01-02"),
		)
	}

	idx.body, err = clickhouse.Query(
		ctx,
		idx.url,
		fmt.Sprintf("SELECT Path FROM %s WHERE %s GROUP BY Path", idx.table, where),
		idx.table,
		idx.opts,
	)

	return
}

func (idx *IndexFinder) Abs(v []byte) []byte {
	return v
}

func (idx *IndexFinder) makeList(onlySeries bool) [][]byte {
	if idx.body == nil {
		return [][]byte{}
	}

	rows := bytes.Split(idx.body, []byte{'\n'})

	skip := 0
	for i := 0; i < len(rows); i++ {
		if len(rows[i]) == 0 {
			skip++
			continue
		}
		if onlySeries && rows[i][len(rows[i])-1] == '.' {
			skip++
			continue
		}
		if skip > 0 {
			rows[i-skip] = rows[i]
		}
	}

	rows = rows[:len(rows)-skip]

	if idx.useReverse {
		for i := 0; i < len(rows); i++ {
			rows[i] = ReverseBytes(rows[i])
		}
	}

	return rows
}

func (idx *IndexFinder) List() [][]byte {
	return idx.makeList(false)
}

func (idx *IndexFinder) Series() [][]byte {
	return idx.makeList(true)
}
<|endoftext|>


<commit_before>package dht

// get_peers and announce_peers.

import (
	"log"
	"time"

	"github.com/anacrolix/missinggo"
	"github.com/anacrolix/sync"
	"github.com/willf/bloom"

	"github.com/anacrolix/torrent/logonce"
)

// Maintains state for an ongoing Announce operation. An Announce is started
// by calling Server.Announce.
type Announce struct {
	mu    sync.Mutex
	Peers chan PeersValues
	// Inner chan is set to nil when on close.
	values              chan PeersValues
	stop                chan struct{}
	triedAddrs          *bloom.BloomFilter
	pending             int
	server              *Server
	infoHash            string
	numContacted        int
	announcePort        int
	announcePortImplied bool
}

// Returns the number of distinct remote addresses the announce has queried.
func (me *Announce) NumContacted() int {
	me.mu.Lock()
	defer me.mu.Unlock()
	return me.numContacted
}

// This is kind of the main thing you want to do with DHT. It traverses the
// graph toward nodes that store peers for the infohash, streaming them to the
// caller, and announcing the local node to each node if allowed and
// specified.
func (s *Server) Announce(infoHash string, port int, impliedPort bool) (*Announce, error) {
	s.mu.Lock()
	startAddrs := func() (ret []dHTAddr) {
		for _, n := range s.closestGoodNodes(160, infoHash) {
			ret = append(ret, n.addr)
		}
		return
	}()
	s.mu.Unlock()
	if len(startAddrs) == 0 {
		addrs, err := bootstrapAddrs(s.bootstrapNodes)
		if err != nil {
			return nil, err
		}
		for _, addr := range addrs {
			startAddrs = append(startAddrs, newDHTAddr(addr))
		}
	}
	disc := &Announce{
		Peers:               make(chan PeersValues, 100),
		stop:                make(chan struct{}),
		values:              make(chan PeersValues),
		triedAddrs:          bloom.NewWithEstimates(1000, 0.5),
		server:              s,
		infoHash:            infoHash,
		announcePort:        port,
		announcePortImplied: impliedPort,
	}
	// Function ferries from values to Values until discovery is halted.
	go func() {
		defer close(disc.Peers)
		for {
			select {
			case psv := <-disc.values:
				select {
				case disc.Peers <- psv:
				case <-disc.stop:
					return
				}
			case <-disc.stop:
				return
			}
		}
	}()
	for i, addr := range startAddrs {
		if i != 0 {
			time.Sleep(time.Millisecond)
		}
		disc.mu.Lock()
		disc.contact(addr)
		disc.mu.Unlock()
	}
	return disc, nil
}

func (me *Announce) gotNodeAddr(addr dHTAddr) {
	if missinggo.AddrPort(addr) == 0 {
		// Not a contactable address.
		return
	}
	if me.triedAddrs.Test([]byte(addr.String())) {
		return
	}
	if me.server.ipBlocked(addr.UDPAddr().IP) {
		return
	}
	me.server.mu.Lock()
	if me.server.badNodes.Test([]byte(addr.String())) {
		me.server.mu.Unlock()
		return
	}
	me.server.mu.Unlock()
	me.contact(addr)
}

func (me *Announce) contact(addr dHTAddr) {
	me.numContacted++
	me.triedAddrs.Add([]byte(addr.String()))
	if err := me.getPeers(addr); err != nil {
		log.Printf("error sending get_peers request to %s: %#v", addr, err)
		return
	}
	me.pending++
}

func (me *Announce) transactionClosed() {
	me.pending--
	if me.pending == 0 {
		me.close()
		return
	}
}

func (me *Announce) responseNode(node NodeInfo) {
	me.gotNodeAddr(node.Addr)
}

func (me *Announce) closingCh() chan struct{} {
	return me.stop
}

// Announce to a peer, if appropriate.
func (me *Announce) maybeAnnouncePeer(to dHTAddr, token, peerId string) {
	me.server.mu.Lock()
	defer me.server.mu.Unlock()
	if !me.server.config.NoSecurity {
		if len(peerId) != 20 {
			return
		}
		if !NodeIdSecure(peerId, to.IP()) {
			return
		}
	}
	err := me.server.announcePeer(to, me.infoHash, me.announcePort, token, me.announcePortImplied)
	me.server.mu.Unlock()
	if err != nil {
		logonce.Stderr.Printf("error announcing peer: %s", err)
	}
}

func (me *Announce) getPeers(addr dHTAddr) error {
	me.server.mu.Lock()
	defer me.server.mu.Unlock()
	t, err := me.server.getPeers(addr, me.infoHash)
	if err != nil {
		return err
	}
	t.SetResponseHandler(func(m Msg, ok bool) {
		// Register suggested nodes closer to the target info-hash.
		if m.R != nil {
			me.mu.Lock()
			for _, n := range m.R.Nodes {
				me.responseNode(n)
			}
			me.mu.Unlock()

			if vs := m.R.Values; len(vs) != 0 {
				nodeInfo := NodeInfo{
					Addr: t.remoteAddr,
				}
				copy(nodeInfo.ID[:], m.SenderID())
				select {
				case me.values <- PeersValues{
					Peers: func() (ret []Peer) {
						for _, cp := range vs {
							ret = append(ret, Peer(cp))
						}
						return
					}(),
					NodeInfo: nodeInfo,
				}:
				case <-me.stop:
				}
			}

			me.maybeAnnouncePeer(addr, m.R.Token, m.SenderID())
		}

		me.mu.Lock()
		me.transactionClosed()
		me.mu.Unlock()
	})
	return nil
}

// Corresponds to the "values" key in a get_peers KRPC response. A list of
// peers that a node has reported as being in the swarm for a queried info
// hash.
type PeersValues struct {
	Peers    []Peer // Peers given in get_peers response.
	NodeInfo        // The node that gave the response.
}

// Stop the announce.
func (me *Announce) Close() {
	me.mu.Lock()
	defer me.mu.Unlock()
	me.close()
}

func (ps *Announce) close() {
	select {
	case <-ps.stop:
	default:
		close(ps.stop)
	}
}
<commit_msg>Fix #47<commit_after>package dht

// get_peers and announce_peers.

import (
	"log"
	"time"

	"github.com/anacrolix/missinggo"
	"github.com/anacrolix/sync"
	"github.com/willf/bloom"

	"github.com/anacrolix/torrent/logonce"
)

// Maintains state for an ongoing Announce operation. An Announce is started
// by calling Server.Announce.
type Announce struct {
	mu    sync.Mutex
	Peers chan PeersValues
	// Inner chan is set to nil when on close.
	values              chan PeersValues
	stop                chan struct{}
	triedAddrs          *bloom.BloomFilter
	pending             int
	server              *Server
	infoHash            string
	numContacted        int
	announcePort        int
	announcePortImplied bool
}

// Returns the number of distinct remote addresses the announce has queried.
func (me *Announce) NumContacted() int {
	me.mu.Lock()
	defer me.mu.Unlock()
	return me.numContacted
}

// This is kind of the main thing you want to do with DHT. It traverses the
// graph toward nodes that store peers for the infohash, streaming them to the
// caller, and announcing the local node to each node if allowed and
// specified.
func (s *Server) Announce(infoHash string, port int, impliedPort bool) (*Announce, error) {
	s.mu.Lock()
	startAddrs := func() (ret []dHTAddr) {
		for _, n := range s.closestGoodNodes(160, infoHash) {
			ret = append(ret, n.addr)
		}
		return
	}()
	s.mu.Unlock()
	if len(startAddrs) == 0 {
		addrs, err := bootstrapAddrs(s.bootstrapNodes)
		if err != nil {
			return nil, err
		}
		for _, addr := range addrs {
			startAddrs = append(startAddrs, newDHTAddr(addr))
		}
	}
	disc := &Announce{
		Peers:               make(chan PeersValues, 100),
		stop:                make(chan struct{}),
		values:              make(chan PeersValues),
		triedAddrs:          bloom.NewWithEstimates(1000, 0.5),
		server:              s,
		infoHash:            infoHash,
		announcePort:        port,
		announcePortImplied: impliedPort,
	}
	// Function ferries from values to Values until discovery is halted.
	go func() {
		defer close(disc.Peers)
		for {
			select {
			case psv := <-disc.values:
				select {
				case disc.Peers <- psv:
				case <-disc.stop:
					return
				}
			case <-disc.stop:
				return
			}
		}
	}()
	for i, addr := range startAddrs {
		if i != 0 {
			time.Sleep(time.Millisecond)
		}
		disc.mu.Lock()
		disc.contact(addr)
		disc.mu.Unlock()
	}
	return disc, nil
}

func (me *Announce) gotNodeAddr(addr dHTAddr) {
	if missinggo.AddrPort(addr) == 0 {
		// Not a contactable address.
		return
	}
	if me.triedAddrs.Test([]byte(addr.String())) {
		return
	}
	if me.server.ipBlocked(addr.UDPAddr().IP) {
		return
	}
	me.server.mu.Lock()
	if me.server.badNodes.Test([]byte(addr.String())) {
		me.server.mu.Unlock()
		return
	}
	me.server.mu.Unlock()
	me.contact(addr)
}

func (me *Announce) contact(addr dHTAddr) {
	me.numContacted++
	me.triedAddrs.Add([]byte(addr.String()))
	if err := me.getPeers(addr); err != nil {
		log.Printf("error sending get_peers request to %s: %#v", addr, err)
		return
	}
	me.pending++
}

func (me *Announce) transactionClosed() {
	me.pending--
	if me.pending == 0 {
		me.close()
		return
	}
}

func (me *Announce) responseNode(node NodeInfo) {
	me.gotNodeAddr(node.Addr)
}

func (me *Announce) closingCh() chan struct{} {
	return me.stop
}

// Announce to a peer, if appropriate.
func (me *Announce) maybeAnnouncePeer(to dHTAddr, token, peerId string) {
	me.server.mu.Lock()
	defer me.server.mu.Unlock()
	if !me.server.config.NoSecurity {
		if len(peerId) != 20 {
			return
		}
		if !NodeIdSecure(peerId, to.IP()) {
			return
		}
	}
	err := me.server.announcePeer(to, me.infoHash, me.announcePort, token, me.announcePortImplied)
	if err != nil {
		logonce.Stderr.Printf("error announcing peer: %s", err)
	}
}

func (me *Announce) getPeers(addr dHTAddr) error {
	me.server.mu.Lock()
	defer me.server.mu.Unlock()
	t, err := me.server.getPeers(addr, me.infoHash)
	if err != nil {
		return err
	}
	t.SetResponseHandler(func(m Msg, ok bool) {
		// Register suggested nodes closer to the target info-hash.
		if m.R != nil {
			me.mu.Lock()
			for _, n := range m.R.Nodes {
				me.responseNode(n)
			}
			me.mu.Unlock()

			if vs := m.R.Values; len(vs) != 0 {
				nodeInfo := NodeInfo{
					Addr: t.remoteAddr,
				}
				copy(nodeInfo.ID[:], m.SenderID())
				select {
				case me.values <- PeersValues{
					Peers: func() (ret []Peer) {
						for _, cp := range vs {
							ret = append(ret, Peer(cp))
						}
						return
					}(),
					NodeInfo: nodeInfo,
				}:
				case <-me.stop:
				}
			}

			me.maybeAnnouncePeer(addr, m.R.Token, m.SenderID())
		}

		me.mu.Lock()
		me.transactionClosed()
		me.mu.Unlock()
	})
	return nil
}

// Corresponds to the "values" key in a get_peers KRPC response. A list of
// peers that a node has reported as being in the swarm for a queried info
// hash.
type PeersValues struct {
	Peers    []Peer // Peers given in get_peers response.
	NodeInfo        // The node that gave the response.
}

// Stop the announce.
func (me *Announce) Close() {
	me.mu.Lock()
	defer me.mu.Unlock()
	me.close()
}

func (ps *Announce) close() {
	select {
	case <-ps.stop:
	default:
		close(ps.stop)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"github.com/blasphemy/furry-robot/models"
	r "github.com/dancannon/gorethink"
	"github.com/spf13/cobra"
	"github.com/spf13/viper"
	"log"
	"time"
)

var NewUser *models.User
var session *r.Session

var AdminTool = &cobra.Command{
	Use:   "admintool",
	Short: "Admin tool",
	Run: func(cmd *cobra.Command, args []string) {
		log.Println("puush server admin tool")
	},
}

var AddUser = &cobra.Command{
	Use: "adduser",
	Run: func(cmd *cobra.Command, args []string) {
		log.Println("Adding user")
		uuid, err := GetNewApiKey()
		if err != nil {
			log.Fatal(err.Error())
		}
		NewUser.ApiKey = uuid
		NewUser.Epoch = time.Now()
		NewUser.LastActivity = time.Now()
		err = r.Db(viper.GetString("DBName")).Table(viper.GetString("UserTable")).Insert(NewUser).Exec(session)
		if err != nil {
			log.Fatal(err.Error())
		}
		log.Printf("User %s API KEY: %s", NewUser.Email, NewUser.ApiKey)
	},
}

func main() {
	ConfigInit()
	var err error
	session, err = r.Connect(r.ConnectOpts{
		Address: viper.GetString("RethinkDbConnectionString"),
	})
	if err != nil {
		log.Fatal(err.Error())
	}
	NewUser = &models.User{}
	AddUser.Flags().StringVarP(&NewUser.Email, "email", "e", "", "users email address")
	AddUser.Flags().BoolVarP(&NewUser.Active, "active", "a", true, "user is active")
	AdminTool.AddCommand(AddUser)
	AdminTool.Execute()
}

func ConfigInit() {
	viper.SetConfigName("puush")
	viper.AddConfigPath("../")
	viper.SetDefault("RethinkDbConnectionString", "127.0.0.1:28015")
	viper.SetDefault("DBName", "puush")
	viper.SetDefault("FileTable", "Files")
	viper.SetDefault("FilePieceTable", "FilePieces")
	viper.SetDefault("MetaTable", "Meta")
	viper.SetDefault("UserTable", "Users")
	viper.SetDefault("BaseUrl", "http://127.0.0.1:3000/")
	log.Println("Reading config")
	err := viper.ReadInConfig()
	if err != nil {
		log.Println("error reading config, using defaults")
		log.Println(err.Error())
	}
}

func GetNewApiKey() (string, error) {
	cur, err := r.UUID().Run(session)
	if err != nil {
		return "", err
	}
	var k interface{}
	err = cur.One(&k)
	if err != nil {
		return "", err
	}
	result, ok := k.(string)
	if !ok {
		return "", errors.New("Could not turn UUID into string")
	}
	return result, nil
}
<commit_msg>forgot to update config name<commit_after>package main

import (
	"errors"
	"github.com/blasphemy/furry-robot/models"
	r "github.com/dancannon/gorethink"
	"github.com/spf13/cobra"
	"github.com/spf13/viper"
	"log"
	"time"
)

var NewUser *models.User
var session *r.Session

var AdminTool = &cobra.Command{
	Use:   "admintool",
	Short: "Admin tool",
	Run: func(cmd *cobra.Command, args []string) {
		log.Println("puush server admin tool")
	},
}

var AddUser = &cobra.Command{
	Use: "adduser",
	Run: func(cmd *cobra.Command, args []string) {
		log.Println("Adding user")
		uuid, err := GetNewApiKey()
		if err != nil {
			log.Fatal(err.Error())
		}
		NewUser.ApiKey = uuid
		NewUser.Epoch = time.Now()
		NewUser.LastActivity = time.Now()
		err = r.Db(viper.GetString("DBName")).Table(viper.GetString("UserTable")).Insert(NewUser).Exec(session)
		if err != nil {
			log.Fatal(err.Error())
		}
		log.Printf("User %s API KEY: %s", NewUser.Email, NewUser.ApiKey)
	},
}

func main() {
	ConfigInit()
	var err error
	session, err = r.Connect(r.ConnectOpts{
		Address: viper.GetString("RethinkDbConnectionString"),
	})
	if err != nil {
		log.Fatal(err.Error())
	}
	NewUser = &models.User{}
	AddUser.Flags().StringVarP(&NewUser.Email, "email", "e", "", "users email address")
	AddUser.Flags().BoolVarP(&NewUser.Active, "active", "a", true, "user is active")
	AdminTool.AddCommand(AddUser)
	AdminTool.Execute()
}

func ConfigInit() {
	viper.SetConfigName("furryrobot")
	viper.AddConfigPath("../")
	viper.SetDefault("RethinkDbConnectionString", "127.0.0.1:28015")
	viper.SetDefault("DBName", "puush")
	viper.SetDefault("FileTable", "Files")
	viper.SetDefault("FilePieceTable", "FilePieces")
	viper.SetDefault("MetaTable", "Meta")
	viper.SetDefault("UserTable", "Users")
	viper.SetDefault("BaseUrl", "http://127.0.0.1:3000/")
	log.Println("Reading config")
	err := viper.ReadInConfig()
	if err != nil {
		log.Println("error reading config, using defaults")
		log.Println(err.Error())
	}
}

func GetNewApiKey() (string, error) {
	cur, err := r.UUID().Run(session)
	if err != nil {
		return "", err
	}
	var k interface{}
	err = cur.One(&k)
	if err != nil {
		return "", err
	}
	result, ok := k.(string)
	if !ok {
		return "", errors.New("Could not turn UUID into string")
	}
	return result, nil
}
<|endoftext|>


<commit_before>// Copyright (c) 2016 Pani Networks
// All Rights Reserved.
//
// 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.
//
// This file store default rules that should be applied by the agent
// when it doesn endpoint proisioning.
// TODO Eventually agent should just load this rules from provided location
// for now they just hardcoded in this file.

package agent

// Rule type in romana agent represents a firewall rule
// along with information about how this rule should be
// provisioned in firewall.
type Rule struct {
	// Text representation of the rule may contain
	// dynamic tokens (%s), this flag tells how to
	// expand such tokens.
	Format RuleFormat

	// Text representation of the rule.
	Body string

	// Specifies what position rule must occupy.
	// Provides a hint for firewall on how to
	// install this rule in relation to other rules.
	// e.g. top, bottom, after/before something.
	Position RulePosition

	// Specifies traffic direction the rule must be applied to.
	// Provides a hint for firewall on rule placement,
	// different firewall implementations might interpret it
	// differently.
	Direction RuleDirection
}

// RuleSet is a collection of agent rules.
type RuleSet []Rule

// RuleFormat indicates that Rule.Body contains a specific
// number of tokens that should be replaced with specific
// information.
type RuleFormat int

const (
	NoFormatNeeded RuleFormat = iota

	// There is one token in the rule which
	// must be replaced with a chain iptables
	// chain name.
	FormatChain

	// There are 3 tokens in the rule
	// first one must be replaced with iptables
	// chain name, second one must be replaced
	// with localhost ip address (e.g. 10.1.0.1)
	// and a last one with u32 mask that
	// matches romana tenant and segment.
	FormatChainHostU32TenantSegment
)

// RulePosition indicates that firewall implementation
// should render the rule at specific place of the ruleset
// e.g. in iptables chain.
type RulePosition int

const (
	// Firewall implementation uses default
	// position for the rule.
	DefaultPosition RulePosition = iota

	// Firewall implementation should put
	// this rule at the top of the chain/list.
	TopPosition

	// Firewall implementation should put
	// this rule at the bottom of the chain/list.
	BottomPosition
)

// RuleDirection indicates that rule should be applied to the traffic
// going in a specific direction.
type RuleDirection int

const (
	// List of rules matching traffic from endpoints to the host.
	EgressLocalDirection RuleDirection = iota

	// List of rules matching traffic from endpoints to the rest
	// of the world.
	EgressGlobalDirection

	// List of rules matching traffic from the host to the endpoints.
	IngressLocalDirection

	// List of rules matching traffic from the world to the endpoints.
	IngressGlobalDirection
)

// We support different firewall implementation backends (currently ShellxProvider and IPTsaveProvider).
// Different providers may use different strategies for placing and ordering rules. Furthermore, different
// orchestration systems (such as Kubernetes or OpenStack) have different requirements for the rules
// they need and for how rules are inserted.
// Therefore, we need to provide separate and specific rule specifications for each provider in the context
// of each orchestration environment. Below then, we have these specifications.

// KubeShellXRules is a set of rules to be applied for kubernetes with ShellexProvider firewall.
var KubeShellXRules = RuleSet{
	Rule{
		Format:    FormatChain,
		Body:      "%s -m comment --comment DefaultDrop -j DROP",
		Position:  DefaultPosition,
		Direction: EgressLocalDirection,
	},
	Rule{
		Format:    FormatChain,
		Body:      "%s -m state --state ESTABLISHED -j ACCEPT",
		Position:  DefaultPosition,
		Direction: EgressLocalDirection,
	},
	Rule{
		Format:    FormatChain,
		Body:      "%s -m comment --comment Outgoing -j RETURN",
		Position:  DefaultPosition,
		Direction: EgressGlobalDirection,
	},
	Rule{
		Format:    FormatChain,
		Body:      "%s -m state --state RELATED,ESTABLISHED -j ACCEPT",
		Position:  DefaultPosition,
		Direction: IngressGlobalDirection,
	},
}

// KubeSaveRestoreRules is a set of rules to be applied for kubernetes with IPTsaveProvider firewall.
var KubeSaveRestoreRules = RuleSet{
	Rule{
		Format:    FormatChain,
		Body:      "%s -m comment --comment DefaultDrop -j DROP",
		Position:  BottomPosition,
		Direction: EgressLocalDirection,
	},
	Rule{
		Format:    FormatChain,
		Body:      "%s -m state --state ESTABLISHED -j ACCEPT",
		Position:  TopPosition,
		Direction: EgressLocalDirection,
	},
	Rule{
		Format:    FormatChain,
		Body:      "%s -m comment --comment Outgoing -j RETURN",
		Position:  TopPosition,
		Direction: EgressGlobalDirection,
	},
	Rule{
		Format:    FormatChain,
		Body:      "%s -m state --state RELATED,ESTABLISHED -j ACCEPT",
		Position:  TopPosition,
		Direction: IngressGlobalDirection,
	},
}

// OpenStackShellRules is a set of rules to be applied for OpenStack with ShellexProvider firewall.
var OpenStackShellRules = RuleSet{
	Rule{
		Format:    FormatChain,
		Body:      "%s -m comment --comment DefaultDrop -j DROP",
		Position:  DefaultPosition,
		Direction: EgressLocalDirection,
	},
	Rule{
		Format:    FormatChain,
		Body:      "%s -m state --state ESTABLISHED -j ACCEPT",
		Position:  DefaultPosition,
		Direction: EgressLocalDirection,
	},
	Rule{
		Format:    FormatChain,
		Body:      "%s -m comment --comment Outgoing -j RETURN",
		Position:  DefaultPosition,
		Direction: EgressGlobalDirection,
	},
	Rule{
		Format:    FormatChainHostU32TenantSegment,
		Body:      "%s ! -s %s -m u32 --u32 %s -j ACCEPT",
		Position:  DefaultPosition,
		Direction: IngressGlobalDirection,
	},
	Rule{
		Format:    FormatChain,
		Body:      "%s -m state --state RELATED,ESTABLISHED -j ACCEPT",
		Position:  DefaultPosition,
		Direction: IngressGlobalDirection,
	},
}

// OpenStackSaveRestoreRules is a set of rules to be applied for OpenStack with IPTsaveProvider firewall.
var OpenStackSaveRestoreRules = RuleSet{
	Rule{
		Format:    FormatChain,
		Body:      "%s -m comment --comment DefaultDrop -j DROP",
		Position:  BottomPosition,
		Direction: EgressLocalDirection,
	},
	Rule{
		Format:    FormatChain,
		Body:      "%s -m state --state ESTABLISHED -j ACCEPT",
		Position:  TopPosition,
		Direction: EgressLocalDirection,
	},
	Rule{
		Format:    FormatChain,
		Body:      "%s -m comment --comment Outgoing -j RETURN",
		Position:  BottomPosition,
		Direction: EgressGlobalDirection,
	},
	Rule{
		Format:    FormatChainHostU32TenantSegment,
		Body:      "%s ! -s %s -m u32 --u32 %s -j ACCEPT",
		Position:  TopPosition,
		Direction: IngressGlobalDirection,
	},
	Rule{
		Format:    FormatChain,
		Body:      "%s -m state --state RELATED,ESTABLISHED -j ACCEPT",
		Position:  TopPosition,
		Direction: IngressGlobalDirection,
	},
}
<commit_msg>agent: remove rule sets, since they are not used anymore.<commit_after><|endoftext|>


<commit_before>package mcts

import (
	"context"
	"fmt"

	"github.com/nelhage/taktician/bitboard"
	"github.com/nelhage/taktician/tak"
)

type builder func(*MCTSConfig) Policy

var policyMap map[string]builder

func init() {
	policyMap = make(map[string]builder)
	policyMap[""] = buildUniform
	policyMap["uniform"] = buildUniform
}

func (mc *MonteCarloAI) buildPolicy() Policy {
	builder := policyMap[mc.cfg.Policy]
	if builder == nil {
		panic(fmt.Sprintf("no such policy: %s", mc.cfg.Policy))
	}
	return builder(&mc.cfg)
}

type UniformRandom struct {
	alloc *tak.Position
}

func buildUniform(cfg *MCTSConfig) Policy {
	return &UniformRandom{
		alloc: tak.Alloc(cfg.Size),
	}
}

func (u *UniformRandom) Select(ctx context.Context, m *MonteCarloAI, p *tak.Position) *tak.Position {
	moves := p.AllMoves(nil)
	var next *tak.Position
	for {
		r := m.r.Int31n(int32(len(moves)))
		m := moves[r]
		var e error
		if next, e = p.MovePreallocated(m, u.alloc); e == nil {
			break
		}
		moves[0], moves[r] = moves[r], moves[0]
		moves = moves[1:]
	}
	u.alloc = p
	return next
}

type PlaceWins struct {
	uniform UniformRandom
}

func findPlaceWins(mask uint64, empty uint64, gs []uint64, c *bitboard.Constants) uint64 {
	l := mask & c.L
	r := mask & c.R
	b := mask & c.B
	t := mask & c.T
	for _, g := range gs {
		if g&c.L != 0 {
			l |= g
		}
		if g&c.R != 0 {
			r |= g
		}
		if g&c.B != 0 {
			b |= g
		}
		if g&c.T != 0 {
			t |= g
		}
	}
	lf := bitboard.Grow(c, empty, l) | c.L&empty
	rf := bitboard.Grow(c, empty, r) | c.R&empty
	bf := bitboard.Grow(c, empty, b) | c.B&empty
	tf := bitboard.Grow(c, empty, t) | c.T&empty
	/*
		log.Printf("l =%64s", strconv.FormatUint(l, 2))
		log.Printf("lf=%64s", strconv.FormatUint(lf, 2))
		log.Printf("r =%64s", strconv.FormatUint(r, 2))
		log.Printf("rf=%64s", strconv.FormatUint(rf, 2))
		log.Printf("t =%64s", strconv.FormatUint(t, 2))
		log.Printf("tf=%64s", strconv.FormatUint(tf, 2))
		log.Printf("b =%64s", strconv.FormatUint(b, 2))
		log.Printf("bf=%64s", strconv.FormatUint(bf, 2))
	*/
	return (lf & rf) | (tf & bf)
}

func placeWinMove(c *bitboard.Constants, p *tak.Position) tak.Move {
	var myroad uint64
	var gs []uint64
	if p.ToMove() == tak.White {
		myroad = p.White &^ p.Standing
		gs = p.Analysis().WhiteGroups
	} else {
		myroad = p.Black &^ p.Standing
		gs = p.Analysis().BlackGroups
	}
	empty := c.Mask &^ (p.White | p.Black)
	mask := findPlaceWins(myroad, empty, gs, c)
	if mask != 0 {
		bit := mask ^ (mask & (mask - 1))
		x, y := bitboard.BitCoords(c, bit)
		return tak.Move{X: int8(x), Y: int8(y), Type: tak.PlaceFlat}
	}
	return tak.Move{}
}

func (pw *PlaceWins) Select(ctx context.Context, m *MonteCarloAI, p *tak.Position) *tak.Position {
	if move := placeWinMove(&m.c, p); move.Type != 0 {
		out, e := p.MovePreallocated(move, pw.uniform.alloc)
		if e != nil {
			panic("placeWinMove: bad move")
		}
		pw.uniform.alloc = p
		return out
	}
	return pw.uniform.Select(ctx, m, p)
}
<commit_msg>place_win policy<commit_after>package mcts

import (
	"context"
	"fmt"

	"github.com/nelhage/taktician/bitboard"
	"github.com/nelhage/taktician/tak"
)

type builder func(*MCTSConfig) Policy

var policyMap map[string]builder

func init() {
	policyMap = make(map[string]builder)
	policyMap[""] = buildUniform
	policyMap["uniform"] = buildUniform
	policyMap["place_win"] = buildPlaceWin
}

func (mc *MonteCarloAI) buildPolicy() Policy {
	builder := policyMap[mc.cfg.Policy]
	if builder == nil {
		panic(fmt.Sprintf("no such policy: %s", mc.cfg.Policy))
	}
	return builder(&mc.cfg)
}

type UniformRandom struct {
	alloc *tak.Position
}

func buildUniform(cfg *MCTSConfig) Policy {
	return &UniformRandom{
		alloc: tak.Alloc(cfg.Size),
	}
}

func buildPlaceWin(cfg *MCTSConfig) Policy {
	return &PlaceWins{
		UniformRandom{
			alloc: tak.Alloc(cfg.Size),
		}}
}

func (u *UniformRandom) Select(ctx context.Context, m *MonteCarloAI, p *tak.Position) *tak.Position {
	moves := p.AllMoves(nil)
	var next *tak.Position
	for {
		r := m.r.Int31n(int32(len(moves)))
		m := moves[r]
		var e error
		if next, e = p.MovePreallocated(m, u.alloc); e == nil {
			break
		}
		moves[0], moves[r] = moves[r], moves[0]
		moves = moves[1:]
	}
	u.alloc = p
	return next
}

type PlaceWins struct {
	uniform UniformRandom
}

func findPlaceWins(mask uint64, empty uint64, gs []uint64, c *bitboard.Constants) uint64 {
	l := mask & c.L
	r := mask & c.R
	b := mask & c.B
	t := mask & c.T
	for _, g := range gs {
		if g&c.L != 0 {
			l |= g
		}
		if g&c.R != 0 {
			r |= g
		}
		if g&c.B != 0 {
			b |= g
		}
		if g&c.T != 0 {
			t |= g
		}
	}
	lf := bitboard.Grow(c, empty, l) | c.L&empty
	rf := bitboard.Grow(c, empty, r) | c.R&empty
	bf := bitboard.Grow(c, empty, b) | c.B&empty
	tf := bitboard.Grow(c, empty, t) | c.T&empty
	/*
		log.Printf("l =%64s", strconv.FormatUint(l, 2))
		log.Printf("lf=%64s", strconv.FormatUint(lf, 2))
		log.Printf("r =%64s", strconv.FormatUint(r, 2))
		log.Printf("rf=%64s", strconv.FormatUint(rf, 2))
		log.Printf("t =%64s", strconv.FormatUint(t, 2))
		log.Printf("tf=%64s", strconv.FormatUint(tf, 2))
		log.Printf("b =%64s", strconv.FormatUint(b, 2))
		log.Printf("bf=%64s", strconv.FormatUint(bf, 2))
	*/
	return (lf & rf) | (tf & bf)
}

func placeWinMove(c *bitboard.Constants, p *tak.Position) tak.Move {
	var myroad uint64
	var gs []uint64
	if p.ToMove() == tak.White {
		myroad = p.White &^ p.Standing
		gs = p.Analysis().WhiteGroups
	} else {
		myroad = p.Black &^ p.Standing
		gs = p.Analysis().BlackGroups
	}
	empty := c.Mask &^ (p.White | p.Black)
	mask := findPlaceWins(myroad, empty, gs, c)
	if mask != 0 {
		bit := mask ^ (mask & (mask - 1))
		x, y := bitboard.BitCoords(c, bit)
		return tak.Move{X: int8(x), Y: int8(y), Type: tak.PlaceFlat}
	}
	return tak.Move{}
}

func (pw *PlaceWins) Select(ctx context.Context, m *MonteCarloAI, p *tak.Position) *tak.Position {
	if move := placeWinMove(&m.c, p); move.Type != 0 {
		out, e := p.MovePreallocated(move, pw.uniform.alloc)
		if e != nil {
			panic("placeWinMove: bad move")
		}
		pw.uniform.alloc = p
		return out
	}
	return pw.uniform.Select(ctx, m, p)
}
<|endoftext|>


<commit_before>package controller

import (
	"encoding/json"
	// "errors"
	"fmt"
	"path/filepath"
	"strings"
	// "time"

	"github.com/eaciit/colony-core/v0"
	"github.com/eaciit/colony-manager/helper"
	// "github.com/eaciit/dbox"
	_ "github.com/eaciit/dbox/dbc/jsons"
	// "github.com/eaciit/hdc/hdfs"
	"github.com/eaciit/knot/knot.v1"
	// "github.com/eaciit/live"
	// "github.com/eaciit/sshclient"
	// "github.com/eaciit/toolkit"
	// "golang.org/x/crypto/ssh"
)

var (
	leSourcePath = filepath.Join(EC_DATA_PATH, "langenvironment", "installer")
)

// const (
// 	// os+arsitektur os+bahasa
// 	SERVER_OS = ""
// 	ARCH_OS   = ""
// 	LANG      = ""
// )
const (
	SERVER_WIN   = "windows"
	SERVER_LINUX = "linux"
	SERVER_OSX   = "osx"

	LANG_GO    = "go"
	LANG_JAVA  = "java"
	LANG_SCALA = "scala"
)

type LangenvironmentController struct {
	App
}

func getArch(serverOS string, lang string, arch string) string {
	var result string
	if serverOS == SERVER_LINUX {
		if lang == LANG_GO {
			result = fmt.Sprintf("%s1.6.%s-%s.%s", LANG_GO, SERVER_LINUX, strings.TrimSpace(arch), "tar.gz")
		}
	} else if serverOS == SERVER_WIN {
		if lang == LANG_GO {
			result = fmt.Sprintf("%s1.6.%s-%s.%s", LANG_GO, SERVER_WIN, strings.TrimSpace(arch), "zip")
		}
	}

	return result
}

func CreateLangenvironmentController(l *knot.Server) *LangenvironmentController {
	var controller = new(LangenvironmentController)
	controller.Server = l
	return controller
}

func (l *LangenvironmentController) GetSampleDataForSetupLang() colonycore.LanguageEnvironmentPayload {
	// s := `[{ "ServerId": "vagrant-test1", "Lang": [ "go" ] }, { "ServerId": "vagrant-test2", "Lang": [ "go", "java" ] }]`
	s := `{ "ServerId": "test", "Lang": [ "go" ] }`

	r := colonycore.LanguageEnvironmentPayload{}
	err := json.Unmarshal([]byte(s), &r)
	if err != nil {
		fmt.Println(err)
	}

	return r
}

func (l *LangenvironmentController) Setup(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson
	payload := []*colonycore.LanguageEnvironmentPayload{}
	err := r.GetPayload(&payload)
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}

	for _, each := range payload {
		dataServers := new(colonycore.Server)
		err := colonycore.Get(dataServers, each.ServerId)
		if err != nil {
			return helper.CreateResult(false, nil, err.Error())
		}
		serverPathSeparator := CreateApplicationController(l.Server).GetServerPathSeparator(dataServers)

		sshSetting, sshClient, err := CreateServerController(l.Server).SSHConnect(dataServers)
		if err != nil {
			return helper.CreateResult(false, nil, err.Error())
		}
		defer sshClient.Close()

		var sourcePath string
		var destinationPath string
		var dataFile string
		var pathstring []string

		// destinationPath := strings.Join([]string{dataServers.DataPath, "langenvironment", "installer", "golang"}, serverPathSeparator)
		for _, eachDetail := range each.Lang {
			if dataServers.OS == SERVER_LINUX {
				cmdUnameM := fmt.Sprintf(`uname -m`)
				outArch, _ := sshSetting.GetOutputCommandSsh(cmdUnameM)

				if eachDetail == LANG_GO {
					pathstring = []string{dataServers.DataPath, "langenvironment", "installer", LANG_GO}

					dataFile = getArch(dataServers.OS, LANG_GO, outArch)
					sourcePath = filepath.Join(leSourcePath, LANG_GO, dataServers.OS, dataFile)
					destinationPath = strings.Join(append(pathstring, dataServers.OS), serverPathSeparator)
				}

				err = sshSetting.SshCopyByPath(sourcePath, destinationPath)
				if err != nil {
					return helper.CreateResult(false, nil, err.Error())
				}

				// "/home/vagrant/test/testextract"
				cmdExtractFile := fmt.Sprintf("sudo tar -xvf %s -C %s", strings.Join([]string{destinationPath, dataFile}, serverPathSeparator), "/usr/local")
				_, err := sshSetting.GetOutputCommandSsh(cmdExtractFile)
				if err != nil {
					return helper.CreateResult(false, nil, err.Error())
				}

				cmdChmodCli := fmt.Sprintf("sudo chmod -R 755 %s", "/usr/local/go")
				_, err = sshSetting.GetOutputCommandSsh(cmdChmodCli)
				if err != nil {
					return helper.CreateResult(false, nil, err.Error())
				}

				setEnvPath := func() error {
					cmd1 := `sed -i '/export GOPATH/d' ~/.bashrc`
					sshSetting.GetOutputCommandSsh(cmd1)

					cmd2 := "echo 'export GOPATH=/home/vagrant/goproject' >> ~/.bashrc"
					sshSetting.GetOutputCommandSsh(cmd2)

					return nil
				}

				//new folder src, bin, pkg
				cmdMkdirBin := fmt.Sprintf(`mkdir -p "%s"`, "goproject/bin")
				_, err = sshSetting.GetOutputCommandSsh(cmdMkdirBin)
				if err != nil {
					return helper.CreateResult(false, nil, err.Error())
				}

				cmdMkdirPkg := fmt.Sprintf(`mkdir -p "%s"`, "goproject/pkg")
				_, err = sshSetting.GetOutputCommandSsh(cmdMkdirPkg)
				if err != nil {
					return helper.CreateResult(false, nil, err.Error())
				}

				cmdMkdirSrc := fmt.Sprintf(`mkdir -p "%s"`, "goproject/src")
				_, err = sshSetting.GetOutputCommandSsh(cmdMkdirSrc)
				if err != nil {
					return helper.CreateResult(false, nil, err.Error())
				}

				if err := setEnvPath(); err != nil {
					return helper.CreateResult(false, nil, err.Error())
				}

				//testing run build golang
				cmdMkdirtest := fmt.Sprintf(`mkdir -p "%s"`, "goproject/src/test")
				_, err = sshSetting.GetOutputCommandSsh(cmdMkdirtest)
				if err != nil {
					return helper.CreateResult(false, nil, err.Error())
				}
				cmdTouch := "touch goproject/src/test/main.go"
				_, err = sshSetting.GetOutputCommandSsh(cmdTouch)
				if err != nil {
					return helper.CreateResult(false, nil, err.Error())
				}
				cmdEcho := `echo -e 'package main\nimport "fmt"\nfunc main(){fmt.Println("hello world")}' >> goproject/src/test/main.go`
				_, err = sshSetting.GetOutputCommandSsh(cmdEcho)
				if err != nil {
					return helper.CreateResult(false, nil, err.Error())
				}

				cmdRun := "go run goproject/src/test/main.go"
				_, err = sshSetting.GetOutputCommandSsh(cmdRun)
				if err != nil {
					return helper.CreateResult(false, nil, err.Error())
				}
				// fmt.Println(" :::: ", outRunTest)
			}
		}
	}

	return helper.CreateResult(true, payload, "")
}
<commit_msg>create function setupFromSH (config and set environment)<commit_after>package controller

import (
	// "archive/zip"
	"encoding/json"
	// "errors"
	"fmt"
	"path/filepath"
	"strings"
	// "time"

	"github.com/eaciit/colony-core/v0"
	"github.com/eaciit/colony-manager/helper"
	// "github.com/eaciit/dbox"
	_ "github.com/eaciit/dbox/dbc/jsons"
	// "github.com/eaciit/hdc/hdfs"
	"github.com/eaciit/knot/knot.v1"
	// "github.com/eaciit/live"
	// "github.com/eaciit/sshclient"
	// "github.com/eaciit/toolkit"
	// "golang.org/x/crypto/ssh"
)

var (
	leSourcePath = filepath.Join(EC_DATA_PATH, "langenvironment", "installer")
)

const (
	DESTINSTALL_PATH = "/usr/local/"
	SERVER_WIN       = "windows"
	SERVER_LINUX     = "linux"
	SERVER_OSX       = "osx"

	LANG_GO    = "go"
	LANG_JAVA  = "java"
	LANG_SCALA = "scala"

	INSTALLER_LINUX_GO = "go1.6.linux-x86_64.tar.gz"
)

type LangenvironmentController struct {
	App
}

func getArch(serverOS string, lang string, arch string) string {
	var result string
	if serverOS == SERVER_LINUX {
		if lang == LANG_GO {
			result = fmt.Sprintf("%s1.6.%s-%s.%s", LANG_GO, SERVER_LINUX, strings.TrimSpace(arch), "tar.gz")
		}
	} else if serverOS == SERVER_WIN {
		if lang == LANG_GO {
			result = fmt.Sprintf("%s1.6.%s-%s.%s", LANG_GO, SERVER_WIN, strings.TrimSpace(arch), "zip")
		}
	}

	return result
}

func CreateLangenvironmentController(l *knot.Server) *LangenvironmentController {
	var controller = new(LangenvironmentController)
	controller.Server = l
	return controller
}

func (l *LangenvironmentController) GetSampleDataForSetupLang() colonycore.LanguageEnvironmentPayload {
	// s := `[{ "ServerId": "vagrant-test1", "Lang": [ "go" ] }, { "ServerId": "vagrant-test2", "Lang": [ "go", "java" ] }]`
	s := `{ "ServerId": "test", "Lang": [ "go" ] }`

	r := colonycore.LanguageEnvironmentPayload{}
	err := json.Unmarshal([]byte(s), &r)
	if err != nil {
		fmt.Println(err)
	}

	return r
}

func (l *LangenvironmentController) Setup(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson
	payload := []*colonycore.LanguageEnvironmentPayload{}
	err := r.GetPayload(&payload)
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}

	for _, each := range payload {
		dataServers := new(colonycore.Server)
		err := colonycore.Get(dataServers, each.ServerId)
		if err != nil {
			return helper.CreateResult(false, nil, err.Error())
		}
		serverPathSeparator := CreateApplicationController(l.Server).GetServerPathSeparator(dataServers)

		sshSetting, sshClient, err := CreateServerController(l.Server).SSHConnect(dataServers)
		if err != nil {
			return helper.CreateResult(false, nil, err.Error())
		}
		defer sshClient.Close()

		var sourcePath string
		var destinationPath string
		var dataFile string
		var pathstring []string

		// destinationPath := strings.Join([]string{dataServers.DataPath, "langenvironment", "installer", "golang"}, serverPathSeparator)
		for _, eachDetail := range each.Lang {
			if dataServers.OS == SERVER_LINUX {
				cmdUnameM := fmt.Sprintf(`uname -m`)
				outArch, _ := sshSetting.GetOutputCommandSsh(cmdUnameM)

				if eachDetail == LANG_GO {
					pathstring = []string{dataServers.DataPath, "langenvironment", "installer", LANG_GO}

					dataFile = getArch(dataServers.OS, LANG_GO, outArch)
					sourcePath = filepath.Join(leSourcePath, LANG_GO, dataServers.OS, dataFile)
					destinationPath = strings.Join(append(pathstring, dataServers.OS), serverPathSeparator)
				}

				err = sshSetting.SshCopyByPath(sourcePath, destinationPath)
				if err != nil {
					return helper.CreateResult(false, nil, err.Error())
				}

				// "/home/vagrant/test/testextract"
				cmdExtractFile := fmt.Sprintf("sudo tar -xvf %s -C %s", strings.Join([]string{destinationPath, dataFile}, serverPathSeparator), "/usr/local")
				_, err := sshSetting.GetOutputCommandSsh(cmdExtractFile)
				if err != nil {
					return helper.CreateResult(false, nil, err.Error())
				}

				cmdChmodCli := fmt.Sprintf("sudo chmod -R 755 %s", "/usr/local/go")
				_, err = sshSetting.GetOutputCommandSsh(cmdChmodCli)
				if err != nil {
					return helper.CreateResult(false, nil, err.Error())
				}

				setEnvPath := func() error {
					cmd1 := `sed -i '/export GOPATH/d' ~/.bashrc`
					sshSetting.GetOutputCommandSsh(cmd1)

					cmd2 := "echo 'export GOPATH=/home/vagrant/goproject' >> ~/.bashrc"
					sshSetting.GetOutputCommandSsh(cmd2)

					return nil
				}

				//new folder src, bin, pkg
				cmdMkdirBin := fmt.Sprintf(`mkdir -p "%s"`, "goproject/bin")
				_, err = sshSetting.GetOutputCommandSsh(cmdMkdirBin)
				if err != nil {
					return helper.CreateResult(false, nil, err.Error())
				}

				cmdMkdirPkg := fmt.Sprintf(`mkdir -p "%s"`, "goproject/pkg")
				_, err = sshSetting.GetOutputCommandSsh(cmdMkdirPkg)
				if err != nil {
					return helper.CreateResult(false, nil, err.Error())
				}

				cmdMkdirSrc := fmt.Sprintf(`mkdir -p "%s"`, "goproject/src")
				_, err = sshSetting.GetOutputCommandSsh(cmdMkdirSrc)
				if err != nil {
					return helper.CreateResult(false, nil, err.Error())
				}

				if err := setEnvPath(); err != nil {
					return helper.CreateResult(false, nil, err.Error())
				}

				//testing run build golang
				cmdMkdirtest := fmt.Sprintf(`mkdir -p "%s"`, "goproject/src/test")
				_, err = sshSetting.GetOutputCommandSsh(cmdMkdirtest)
				if err != nil {
					return helper.CreateResult(false, nil, err.Error())
				}
				cmdTouch := "touch goproject/src/test/main.go"
				_, err = sshSetting.GetOutputCommandSsh(cmdTouch)
				if err != nil {
					return helper.CreateResult(false, nil, err.Error())
				}
				cmdEcho := `echo -e 'package main\nimport "fmt"\nfunc main(){fmt.Println("hello world")}' >> goproject/src/test/main.go`
				_, err = sshSetting.GetOutputCommandSsh(cmdEcho)
				if err != nil {
					return helper.CreateResult(false, nil, err.Error())
				}

				cmdRun := "go run goproject/src/test/main.go"
				_, err = sshSetting.GetOutputCommandSsh(cmdRun)
				if err != nil {
					return helper.CreateResult(false, nil, err.Error())
				}
				// fmt.Println(" :::: ", outRunTest)
			}
		}
	}

	return helper.CreateResult(true, payload, "")
}

func (l *LangenvironmentController) GetSampleFromSH() {
	s := `[{"LangName":"go", "commands":[{ "name": "build", "cmd": "go build" }, { "name": "run", "cmd": "go run" }], "installer":[{ "os": "linux", "InstallerFile": "/data-root/install.sh", "InstallerSource":"go1.6.installer.tar.gz" }, { "os": "windows", "InstallerFile": "installer.bat", "InstallerSource": "go1.6.installer.tar.gz" }]}]`
	fmt.Println(s)
}

func (l *LangenvironmentController) SetupFromSH(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson
	payload := l.GetSampleDataForSetupLang()

	fmt.Println("payload ServerId : ", payload.ServerId)

	dataServers := new(colonycore.Server)
	err := colonycore.Get(dataServers, payload.ServerId)
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}
	serverPathSeparator := CreateApplicationController(l.Server).GetServerPathSeparator(dataServers)

	sshSetting, sshClient, err := CreateServerController(l.Server).SSHConnect(dataServers)
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}
	defer sshClient.Close()

	var sourcePath string
	var destinationPath string
	var pathstring []string

	for _, vallang := range payload.Lang {
		if vallang == LANG_GO {
			pathstring = []string{dataServers.DataPath, "langenvironment", "installer", LANG_GO}

			sourcePath = filepath.Join(leSourcePath, LANG_GO, dataServers.OS, INSTALLER_LINUX_GO)
			destinationPath = strings.Join(append(pathstring, dataServers.OS), serverPathSeparator)
		}
		installShPath := filepath.Join(leSourcePath, LANG_GO, dataServers.OS, "install.sh")

		pathstring = append(pathstring, dataServers.OS)
		installShdestPath := strings.Join(append(pathstring, "install.sh"), serverPathSeparator)
		installFilePath := strings.Join(append(pathstring, INSTALLER_LINUX_GO), serverPathSeparator)

		fmt.Println(" :: ", sourcePath)
		fmt.Println(" :: ", destinationPath)
		fmt.Println(" :: ", INSTALLER_LINUX_GO)

		// compressPath := filepath.Join(leSourcePath)
		// err = toolkit.TarCompress(compressPath, filepath.Join(compressPath, fmt.Sprintf("%s.tar", dataServers.OS)))
		// if err != nil {
		// 	fmt.Println(err)
		// }

		err = sshSetting.SshCopyByPath(sourcePath, destinationPath)
		if err != nil {
			return helper.CreateResult(false, nil, err.Error())
		}

		err = sshSetting.SshCopyByPath(installShPath, destinationPath)
		if err != nil {
			return helper.CreateResult(false, nil, err.Error())
		}

		//sed -i 's/^M//' install.sh
		cmdSedInstall := fmt.Sprintf("sed -i 's/\r//g' %s", installShdestPath)
		_, err = sshSetting.GetOutputCommandSsh(cmdSedInstall)
		if err != nil {
			return helper.CreateResult(false, nil, err.Error())
		}

		fmt.Println(" installation sh dest :: ", installShdestPath)
		// // chmod +x install.sh
		cmdChmodCli := fmt.Sprintf("chmod -x %s", installShdestPath)
		_, err = sshSetting.GetOutputCommandSsh(cmdChmodCli)
		if err != nil {
			return helper.CreateResult(false, nil, err.Error())
		}

		// sh install.sh installFilePath DESTINSTALL_PATH projectpath
		cmdShCli := fmt.Sprintf("sh install.sh %s %s %s", installFilePath, DESTINSTALL_PATH, "goproject")
		fmt.Println("sh command :: ", cmdShCli)
		_, err = sshSetting.GetOutputCommandSsh(cmdShCli)
		if err != nil {
			return helper.CreateResult(false, nil, err.Error())
		}

	}

	return helper.CreateResult(true, payload, "")
}

func (l *LangenvironmentController) GetLanguage(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson

	dsLang, err := new(colonycore.LanguangeEnvironment).Get("")
	// dsLang := new(colonycore.LanguangeEnvironment)
	// err := colonycore.Get(dsLang, "halo")
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(dsLang)

	return helper.CreateResult(true, dsLang, "")
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"net"
	"os"
	"strconv"
	"strings"
	"syscall"

	"golang.org/x/net/ipv4"
)

func main() {
	prog := "mcast_listener"

	if len(os.Args) != 5 {
		fmt.Printf("usage:   %s interface protocol group     address:port\n", prog)
		fmt.Printf("example: %s eth2      udp      224.0.0.9 0.0.0.0:2000\n", prog)
		return
	}

	ifname := os.Args[1]
	proto := os.Args[2]
	group := os.Args[3]
	addrPort := os.Args[4]

	mcastRead(ifname, proto, group, addrPort)
}

func mcastRead(ifname, proto, group, addrPort string) {
	addr, port := splitHostPort(addrPort)
	p, err1 := strconv.Atoi(port)
	if err1 != nil {
		log.Fatal(err1)
	}

	a := net.ParseIP(addr)
	if a == nil {
		log.Fatal(fmt.Errorf("bad address: '%s'", addr))
	}

	g := net.ParseIP(group)
	if g == nil {
		log.Fatal(fmt.Errorf("bad group: '%s'", group))
	}

	ifi, err2 := net.InterfaceByName(ifname)
	if err2 != nil {
		log.Fatal(err2)
	}

	c, err3 := mcastOpen(a, p, ifname)
	if err3 != nil {
		log.Fatal(err3)
	}

	if err := c.JoinGroup(ifi, &net.UDPAddr{IP: g}); err != nil {
		log.Fatal(err)
	}

	if err := c.SetControlMessage(ipv4.FlagTTL|ipv4.FlagSrc|ipv4.FlagDst|ipv4.FlagInterface, true); err != nil {
		log.Fatal(err)
	}

	readLoop(c)

	c.Close()
}

func splitHostPort(hostPort string) (string, string) {
	s := strings.Split(hostPort, ":")
	host := s[0]
	if host == "" {
		host = "0.0.0.0"
	}
	if len(s) == 1 {
		return host, ""
	}
	return host, s[1]
}

func mcastOpen(bindAddr net.IP, port int, ifname string) (*ipv4.PacketConn, error) {
	s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP)
	if err != nil {
		log.Fatal(err)
	}
	if err := syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1); err != nil {
		log.Fatal(err)
	}
	//syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEPORT, 1)
	if err := syscall.SetsockoptString(s, syscall.SOL_SOCKET, syscall.SO_BINDTODEVICE, ifname); err != nil {
		log.Fatal(err)
	}

	lsa := syscall.SockaddrInet4{Port: port}
	copy(lsa.Addr[:], bindAddr.To4())

	if err := syscall.Bind(s, &lsa); err != nil {
		syscall.Close(s)
		log.Fatal(err)
	}
	f := os.NewFile(uintptr(s), "")
	c, err := net.FilePacketConn(f)
	f.Close()
	if err != nil {
		log.Fatal(err)
	}
	p := ipv4.NewPacketConn(c)

	return p, nil
}

func readLoop(c *ipv4.PacketConn) {

	log.Printf("readLoop: reading")

	buf := make([]byte, 10000)

	for {
		n, cm, _, err1 := c.ReadFrom(buf)
		if err1 != nil {
			log.Printf("readLoop: ReadFrom: error %v", err1)
			break
		}

		var name string

		ifi, err2 := net.InterfaceByIndex(cm.IfIndex)
		if err2 != nil {
			log.Printf("readLoop: unable to solve ifIndex=%d: error: %v", cm.IfIndex, err2)
		}

		if ifi == nil {
			name = "ifname?"
		} else {
			name = ifi.Name
		}

		log.Printf("readLoop: recv %d bytes from %s to %s on %s", n, cm.Src, cm.Dst, name)
	}

	log.Printf("readLoop: exiting")
}
<commit_msg>Recipe for sending unicast UDP with multicast socket.<commit_after>package main

import (
	"fmt"
	"log"
	"net"
	"os"
	"strconv"
	"strings"
	"syscall"

	"golang.org/x/net/ipv4"
)

func main() {
	prog := "mcast_listener"

	if len(os.Args) != 5 {
		fmt.Printf("usage:   %s interface group     laddress:lport raddress:rport\n", prog)
		fmt.Printf("example: %s eth2      224.0.0.9 0.0.0.0:2000   1.0.0.1:3000\n", prog)
		return
	}

	ifname := os.Args[1]
	group := os.Args[2]
	locAddrPort := os.Args[3]
	remAddrPort := os.Args[4]

	mcast(ifname, group, locAddrPort, remAddrPort)
}

func mcast(ifname, group, locAddrPort, remAddrPort string) {
	locAddr, locPort := splitHostPort(locAddrPort)
	p, err1 := strconv.Atoi(locPort)
	if err1 != nil {
		log.Fatal(err1)
	}

	remAddr, err2 := net.ResolveUDPAddr("udp", remAddrPort)
	if err2 != nil {
		log.Fatal(err2)
	}

	la := net.ParseIP(locAddr)
	if la == nil {
		log.Fatal(fmt.Errorf("bad address: '%s'", locAddr))
	}

	g := net.ParseIP(group)
	if g == nil {
		log.Fatal(fmt.Errorf("bad group: '%s'", group))
	}

	ifi, err3 := net.InterfaceByName(ifname)
	if err3 != nil {
		log.Fatal(err2)
	}

	c, u, err3 := mcastOpen(la, p, ifname)
	if err3 != nil {
		log.Fatal(err3)
	}

	if err := c.JoinGroup(ifi, &net.UDPAddr{IP: g}); err != nil {
		log.Fatal(err)
	}

	if err := c.SetControlMessage(ipv4.FlagTTL|ipv4.FlagSrc|ipv4.FlagDst|ipv4.FlagInterface, true); err != nil {
		log.Fatal(err)
	}

	log.Printf("writing one udp unicast packet to: %v", remAddr)

	n, err4 := u.WriteToUDP([]byte{0}, remAddr)
	if err4 != nil {
		log.Fatal(err4)
	}

	log.Printf("wrote one udp unicast packet (%d bytes) to %v", n, remAddr)

	readLoop(c)

	c.Close()
}

func splitHostPort(hostPort string) (string, string) {
	s := strings.Split(hostPort, ":")
	host := s[0]
	if host == "" {
		host = "0.0.0.0"
	}
	if len(s) == 1 {
		return host, ""
	}
	return host, s[1]
}

func mcastOpen(bindAddr net.IP, port int, ifname string) (*ipv4.PacketConn, *net.UDPConn, error) {
	s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP)
	if err != nil {
		log.Fatal(err)
	}
	if err := syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1); err != nil {
		log.Fatal(err)
	}
	//syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEPORT, 1)
	if err := syscall.SetsockoptString(s, syscall.SOL_SOCKET, syscall.SO_BINDTODEVICE, ifname); err != nil {
		log.Fatal(err)
	}

	lsa := syscall.SockaddrInet4{Port: port}
	copy(lsa.Addr[:], bindAddr.To4())

	if err := syscall.Bind(s, &lsa); err != nil {
		syscall.Close(s)
		log.Fatal(err)
	}
	f := os.NewFile(uintptr(s), "")
	c, err := net.FilePacketConn(f)
	f.Close()
	if err != nil {
		log.Fatal(err)
	}
	u := c.(*net.UDPConn)
	p := ipv4.NewPacketConn(c)

	return p, u, nil
}

func readLoop(c *ipv4.PacketConn) {

	log.Printf("readLoop: reading")

	buf := make([]byte, 10000)

	for {
		n, cm, _, err1 := c.ReadFrom(buf)
		if err1 != nil {
			log.Printf("readLoop: ReadFrom: error %v", err1)
			break
		}

		var name string

		ifi, err2 := net.InterfaceByIndex(cm.IfIndex)
		if err2 != nil {
			log.Printf("readLoop: unable to solve ifIndex=%d: error: %v", cm.IfIndex, err2)
		}

		if ifi == nil {
			name = "ifname?"
		} else {
			name = ifi.Name
		}

		log.Printf("readLoop: recv %d bytes from %s to %s on %s", n, cm.Src, cm.Dst, name)
	}

	log.Printf("readLoop: exiting")
}
<|endoftext|>