<commit_before>package gen4java

var t4java = `
{{define "enum"}}{{$Enum := title .Name}}
/*
 * {{title .Name}} generate by gs2java,don't modify it manually
 */
public enum {{title .Name}} {
    {{enumFields .}}
    private {{enumType .}} value;
    {{title .Name}}({{enumType .}} val){
        this.value = val;
    }
    @Override
    public String toString() {
        switch(this.value)
        {
        {{range .Constants}}
        case {{.Value}}:
            return "{{title .Name}}";
        {{end}}
        }
        return "{{title .Name}}#" + this.value;
    }
    public {{enumType .}} getValue() {
        return this.value;
    }
    public void marshal(Writer writer) throws Exception
    {
        {{if enumSize . | eq 4}} writer.writeUInt32(getValue()); {{else}} writer.writeByte(getValue()); {{end}}
    }
    public static {{title .Name}} unmarshal(Reader reader) throws Exception
    {
        {{enumType .}} code =  {{if enumSize . | eq 4}} reader.readUInt32(); {{else}} reader.readByte(); {{end}}
        switch(code)
        {
        {{range .Constants}}
        case {{.Value}}:
            return {{$Enum}}.{{title .Name}};
        {{end}}
        }
        throw new Exception("unknown enum constant :" + code);
    }
}
{{end}}

{{define "table"}}{{$Struct := tableName .}}
public class {{$Struct}} {{if isException .}}extends Exception{{end}}
{
{{range .Fields}}
    private  {{typeName .Type}} {{fieldName .Name}} = {{defaultVal .Type}};
{{end}}

{{if .Fields}}
    public {{$Struct}}(){

    }
{{end}}

    public {{$Struct}}{{constructor .Fields}} {
    {{range .Fields}}
        this.{{fieldName .Name}} = {{fieldName .Name}};
    {{end}}
    }

{{range .Fields}}
    public {{typeName .Type}} get{{title .Name}}()
    {
        return this.{{fieldName .Name}};
    }
    public void set{{title .Name}}({{typeName .Type}} arg)
    {
        this.{{fieldName .Name}} = arg;
    }
{{end}}

{{if isPOD . | not}}
    public void marshal(Writer writer)  throws Exception
    {
        writer.writeByte((byte){{len .Fields}});
{{range .Fields}}
        writer.writeByte((byte){{tagValue .Type}});
        {{marshalField .}}
{{end}}
    }
    public void unmarshal(Reader reader) throws Exception
    {
        byte __fields = reader.readByte();
{{range .Fields}}
        {
            byte tag = reader.readByte();

            if(tag != com.gsrpc.Tag.Skip.getValue()) {
                {{unmarshalField .}}
            }

            if(-- __fields == 0) {
                return;
            }
        }

{{end}}

        for(int i = 0; i < (int)__fields; i ++) {
            byte tag = reader.readByte();

            if (tag == com.gsrpc.Tag.Skip.getValue()) {
                continue;
            }

            reader.readSkip(tag);
        }
    }
{{else}}
    public void marshal(Writer writer)  throws Exception
    {
{{range .Fields}}
        {{marshalField .}}
{{end}}
    }

    public void unmarshal(Reader reader) throws Exception
    {
{{range .Fields}}
        {
            {{unmarshalField .}}
        }
{{end}}
    }

{{end}}
}
{{end}}

{{define "contract"}}{{$Contract := title .Name}}

public interface {{$Contract}} {
    String NAME = "{{.FullName}}";
{{range .Methods}}
    {{returnParam .Return}} {{methodName .Name}} {{params .Params}} throws Exception;
{{end}}
}

{{end}}

{{define "dispatcher"}}
{{$Contract := title .Name}}
/*
 * {{title .Name}} generate by gs2java,don't modify it manually
 */
public final class {{$Contract}}Dispatcher implements com.gsrpc.NamedDispatcher {

    private {{$Contract}} service;

    public {{$Contract}}Dispatcher({{$Contract}} service) {
        this.service = service;
    }

    public String name() {
        return "{{.FullName}}";
    }

    public com.gsrpc.Response dispatch(com.gsrpc.Request call) throws Exception
    {
        switch(call.getMethod()){
        {{range .Methods}}
        case {{.ID}}: {
{{range .Params}}{{unmarshalParam . "call" 4}}{{end}}
                {{if isAsync . | not}}
                {{if .Exceptions}}
                try{
                {{end}}
                    {{methodcall .}}

                    com.gsrpc.Response callReturn = new com.gsrpc.Response();
                    callReturn.setID(call.getID());
                    callReturn.setException((byte)-1);

                    {{if notVoid .Return}}
    {{marshalReturn .Return "ret" 4}}
                    callReturn.setContent(returnParam);
                    {{end}}

                    return callReturn;

                {{if .Exceptions}}}{{end}}{{range .Exceptions}} catch({{typeName .Type}} e) {

                    com.gsrpc.BufferWriter writer = new com.gsrpc.BufferWriter();

                    e.marshal(writer);

                    com.gsrpc.Response callReturn = new com.gsrpc.Response();
                    callReturn.setID(call.getID());
                    callReturn.setException((byte){{.ID}});
                    callReturn.setContent(writer.getContent());

                    return callReturn;
                }{{end}}
                {{else}}
                {{methodcall .}}
                {{end}}
            }
        {{end}}
        }
        return null;
    }
}
{{end}}

{{define "rpc"}}{{$Contract := title .Name}}
/*
 * {{title .Name}} generate by gs2java,don't modify it manually
 */
public final class {{$Contract}}RPC {

    /**
     * gsrpc net interface
     */
    private com.gsrpc.Channel net;

    /**
     * remote service id
     */
    private short serviceID;

    public {{$Contract}}RPC(com.gsrpc.Channel net, short serviceID){
        this.net = net;
        this.serviceID = serviceID;
    }

    {{range .Methods}}{{$Name := title .Name}}
    public {{methodRPC .}} throws Exception {

        com.gsrpc.Request request = new com.gsrpc.Request();

        request.setService(this.serviceID);

        request.setMethod((short){{.ID}});

        {{if .Params}}
        com.gsrpc.Param[] params = new com.gsrpc.Param[{{len .Params}}];
{{marshalParams .Params}}
        request.setParams(params);
        {{end}}

        {{if isAsync . | not}}
        com.gsrpc.Promise<{{objTypeName .Return}}> promise = new com.gsrpc.Promise<{{objTypeName .Return}}>(timeout){
            @Override
            public void Return(Exception e,com.gsrpc.Response callReturn){

                if (e != null) {
                    Notify(e,null);
                    return;
                }

                try{

                    if(callReturn.getException() != (byte)-1) {
                        switch(callReturn.getException()) {
                            {{range .Exceptions}}
                            case {{.ID}}:{
                            com.gsrpc.BufferReader reader = new com.gsrpc.BufferReader(callReturn.getContent());

                            {{typeName .Type}} exception = {{defaultVal .Type}};

                            {{readType "exception" .Type 4}}

                            Notify(exception,null);

                            return;
                        }
                        {{end}}
                        default:
                            Notify(new com.gsrpc.RemoteException(),null);
                            return;
                        }
                    }

                    {{if notVoid .Return}}
{{unmarshalReturn .Return "callReturn" 5}}
                    Notify(null,returnParam);
                    {{else}}
                    Notify(null,null);
                    {{end}}
                }catch(Exception e1) {
                    Notify(e1,null);
                }
            }
        };

        this.net.send(request,promise);

        return promise;
        {{else}}
        this.net.post(request);
        {{end}}
    }
    {{end}}
}
{{end}}
`
<commit_msg>update jvm generator<commit_after>package gen4java

var t4java = `
{{define "enum"}}{{$Enum := title .Name}}
/*
 * {{title .Name}} generate by gs2java,don't modify it manually
 */
public enum {{title .Name}} {
    {{enumFields .}}
    private {{enumType .}} value;
    {{title .Name}}({{enumType .}} val){
        this.value = val;
    }
    @Override
    public String toString() {
        switch(this.value)
        {
        {{range .Constants}}
        case {{.Value}}:
            return "{{title .Name}}";
        {{end}}
        }
        return "{{title .Name}}#" + this.value;
    }
    public {{enumType .}} getValue() {
        return this.value;
    }
    public void marshal(Writer writer) throws Exception
    {
        {{if enumSize . | eq 4}} writer.writeUInt32(getValue()); {{else}} writer.writeByte(getValue()); {{end}}
    }
    public static {{title .Name}} unmarshal(Reader reader) throws Exception
    {
        {{enumType .}} code =  {{if enumSize . | eq 4}} reader.readUInt32(); {{else}} reader.readByte(); {{end}}
        switch(code)
        {
        {{range .Constants}}
        case {{.Value}}:
            return {{$Enum}}.{{title .Name}};
        {{end}}
        }
        throw new Exception("unknown enum constant :" + code);
    }
}
{{end}}

{{define "table"}}{{$Struct := tableName .}}
public class {{$Struct}} {{if isException .}}extends Exception{{end}}
{
{{range .Fields}}
    private  {{typeName .Type}} {{fieldName .Name}} = {{defaultVal .Type}};
{{end}}

{{if .Fields}}
    public {{$Struct}}(){

    }
{{end}}

    public {{$Struct}}{{constructor .Fields}} {
    {{range .Fields}}
        this.{{fieldName .Name}} = {{fieldName .Name}};
    {{end}}
    }

{{range .Fields}}
    public {{typeName .Type}} get{{title .Name}}()
    {
        return this.{{fieldName .Name}};
    }
    public void set{{title .Name}}({{typeName .Type}} arg)
    {
        this.{{fieldName .Name}} = arg;
    }
{{end}}

{{if isPOD . | not}}
    public void marshal(Writer writer)  throws Exception
    {
        writer.writeByte((byte){{len .Fields}});
{{range .Fields}}
        writer.writeByte((byte){{tagValue .Type}});
        {{marshalField .}}
{{end}}
    }
    public void unmarshal(Reader reader) throws Exception
    {
        byte __fields = reader.readByte();
{{range .Fields}}
        {
            byte tag = reader.readByte();

            if(tag != com.gsrpc.Tag.Skip.getValue()) {
                {{unmarshalField .}}
            }

            if(-- __fields == 0) {
                return;
            }
        }

{{end}}

        for(int i = 0; i < (int)__fields; i ++) {
            byte tag = reader.readByte();

            if (tag == com.gsrpc.Tag.Skip.getValue()) {
                continue;
            }

            reader.readSkip(tag);
        }
    }
{{else}}
    public void marshal(Writer writer)  throws Exception
    {
{{range .Fields}}
        {{marshalField .}}
{{end}}
    }

    public void unmarshal(Reader reader) throws Exception
    {
{{range .Fields}}
        {
            {{unmarshalField .}}
        }
{{end}}
    }

{{end}}
}
{{end}}

{{define "contract"}}{{$Contract := title .Name}}

public interface {{$Contract}} {
    String NAME = "{{.FullName}}";
{{range .Methods}}
    {{returnParam .Return}} {{methodName .Name}} {{params .Params}} throws Exception;
{{end}}
}

{{end}}

{{define "dispatcher"}}
{{$Contract := title .Name}}
/*
 * {{title .Name}} generate by gs2java,don't modify it manually
 */
public final class {{$Contract}}Dispatcher implements com.gsrpc.NamedDispatcher {

    private {{$Contract}} service;

    public {{$Contract}}Dispatcher({{$Contract}} service) {
        this.service = service;
    }

    public String name() {
        return "{{.FullName}}";
    }

    public com.gsrpc.Response dispatch(com.gsrpc.Request call) throws Exception
    {
        switch(call.getMethod()){
        {{range .Methods}}
        case {{.ID}}: {
{{range .Params}}{{unmarshalParam . "call" 4}}{{end}}
                {{if isAsync . | not}}
                {{if .Exceptions}}
                try{
                {{end}}
                    {{methodcall .}}

                    com.gsrpc.Response callReturn = new com.gsrpc.Response();
                    callReturn.setID(call.getID());
                    callReturn.setException((byte)-1);

                    {{if notVoid .Return}}
    {{marshalReturn .Return "ret" 4}}
                    callReturn.setContent(returnParam);
                    {{end}}

                    return callReturn;

                {{if .Exceptions}}}{{end}}{{range .Exceptions}} catch({{typeName .Type}} e) {

                    com.gsrpc.BufferWriter writer = new com.gsrpc.BufferWriter();

                    e.marshal(writer);

                    com.gsrpc.Response callReturn = new com.gsrpc.Response();
                    callReturn.setID(call.getID());
                    callReturn.setException((byte){{.ID}});
                    callReturn.setContent(writer.getContent());

                    return callReturn;
                }{{end}}
                {{else}}
                {{methodcall .}}
                {{end}}
            }
        {{end}}
        }
        return null;
    }
}
{{end}}

{{define "rpc"}}{{$Contract := title .Name}}
/*
 * {{title .Name}} generate by gs2java,don't modify it manually
 */
public final class {{$Contract}}RPC {

    /**
     * gsrpc net interface
     */
    private com.gsrpc.Channel net;

    /**
     * remote service id
     */
    private short serviceID;

    public {{$Contract}}RPC(com.gsrpc.Channel net, short serviceID){
        this.net = net;
        this.serviceID = serviceID;
    }

    public {{$Contract}}RPC(com.gsrpc.Channel net) throws Exception {
        this.net = net;
        this.serviceID = com.gsrpc.Register.getInstance().getID({{$Contract}}.NAME);
    }

    {{range .Methods}}{{$Name := title .Name}}
    public {{methodRPC .}} throws Exception {

        com.gsrpc.Request request = new com.gsrpc.Request();

        request.setService(this.serviceID);

        request.setMethod((short){{.ID}});

        {{if .Params}}
        com.gsrpc.Param[] params = new com.gsrpc.Param[{{len .Params}}];
{{marshalParams .Params}}
        request.setParams(params);
        {{end}}

        {{if isAsync . | not}}
        com.gsrpc.Promise<{{objTypeName .Return}}> promise = new com.gsrpc.Promise<{{objTypeName .Return}}>(timeout){
            @Override
            public void Return(Exception e,com.gsrpc.Response callReturn){

                if (e != null) {
                    Notify(e,null);
                    return;
                }

                try{

                    if(callReturn.getException() != (byte)-1) {
                        switch(callReturn.getException()) {
                            {{range .Exceptions}}
                            case {{.ID}}:{
                            com.gsrpc.BufferReader reader = new com.gsrpc.BufferReader(callReturn.getContent());

                            {{typeName .Type}} exception = {{defaultVal .Type}};

                            {{readType "exception" .Type 4}}

                            Notify(exception,null);

                            return;
                        }
                        {{end}}
                        default:
                            Notify(new com.gsrpc.RemoteException(),null);
                            return;
                        }
                    }

                    {{if notVoid .Return}}
{{unmarshalReturn .Return "callReturn" 5}}
                    Notify(null,returnParam);
                    {{else}}
                    Notify(null,null);
                    {{end}}
                }catch(Exception e1) {
                    Notify(e1,null);
                }
            }
        };

        this.net.send(request,promise);

        return promise;
        {{else}}
        this.net.post(request);
        {{end}}
    }
    {{end}}
}
{{end}}
`
<|endoftext|>


<commit_before>package integration

import (
	"bufio"
	"html/template"
	"os"
	"os/exec"
	"path/filepath"
	"time"

	homedir "github.com/mitchellh/go-homedir"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

func leaveIt() bool {
	return os.Getenv("LEAVE_ARTIFACTS") != ""
}

func GetSSHKeyFile() (string, error) {
	dir, err := homedir.Dir()
	if err != nil {
		return "", err
	}
	return filepath.Join(dir, ".ssh", "kismatic-integration-testing.pem"), nil
}

type installOptions struct {
	allowPackageInstallation    bool
	disconnectedInstallation    bool
	autoConfigureDockerRegistry bool
	dockerRegistryIP            string
	dockerRegistryPort          int
	dockerRegistryCAPath        string
	modifyHostsFiles            bool
}

func installKismaticMini(node NodeDeets, sshKey string) error {
	sshUser := node.SSHUser
	plan := PlanAWS{
		Etcd:                     []NodeDeets{node},
		Master:                   []NodeDeets{node},
		Worker:                   []NodeDeets{node},
		Ingress:                  []NodeDeets{node},
		Storage:                  []NodeDeets{node},
		MasterNodeFQDN:           node.Hostname,
		MasterNodeShortName:      node.Hostname,
		SSHKeyFile:               sshKey,
		SSHUser:                  sshUser,
		AllowPackageInstallation: true,
	}
	return installKismaticWithPlan(plan, sshKey)
}

func installKismatic(nodes provisionedNodes, installOpts installOptions, sshKey string) error {
	sshUser := nodes.master[0].SSHUser
	masterDNS := nodes.master[0].Hostname
	if nodes.dnsRecord != nil && nodes.dnsRecord.Name != "" {
		masterDNS = nodes.dnsRecord.Name
	}
	plan := PlanAWS{
		AllowPackageInstallation: installOpts.allowPackageInstallation,
		DisconnectedInstallation: installOpts.disconnectedInstallation,
		Etcd:                nodes.etcd,
		Master:              nodes.master,
		Worker:              nodes.worker,
		Ingress:             nodes.ingress,
		Storage:             nodes.storage,
		MasterNodeFQDN:      masterDNS,
		MasterNodeShortName: masterDNS,
		SSHKeyFile:          sshKey,
		SSHUser:             sshUser,
		AutoConfiguredDockerRegistry: installOpts.autoConfigureDockerRegistry,
		DockerRegistryCAPath:         installOpts.dockerRegistryCAPath,
		DockerRegistryIP:             installOpts.dockerRegistryIP,
		DockerRegistryPort:           installOpts.dockerRegistryPort,
		ModifyHostsFiles:             installOpts.modifyHostsFiles,
	}
	return installKismaticWithPlan(plan, sshKey)
}

func installKismaticWithPlan(plan PlanAWS, sshKey string) error {
	By("Building a template")
	template, err := template.New("planAWSOverlay").Parse(planAWSOverlay)
	FailIfError(err, "Couldn't parse template")

	f, err := os.Create("kismatic-testing.yaml")
	FailIfError(err, "Error creating plan")
	defer f.Close()
	w := bufio.NewWriter(f)
	err = template.Execute(w, &plan)
	FailIfError(err, "Error filling in plan template")
	w.Flush()

	By("Punch it Chewie!")
	cmd := exec.Command("./kismatic", "install", "apply", "-f", f.Name())
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	return cmd.Run()
}

func installKismaticWithABadNode() {
	By("Building a template")
	template, err := template.New("planAWSOverlay").Parse(planAWSOverlay)
	FailIfError(err, "Couldn't parse template")

	By("Faking infrastructure")
	fakeNode := NodeDeets{
		id:       "FakeId",
		PublicIP: "10.0.0.0",
		Hostname: "FakeHostname",
	}

	By("Building a plan to set up an overlay network cluster on this hardware")
	sshKey, err := GetSSHKeyFile()
	FailIfError(err, "Error getting SSH Key file")
	plan := PlanAWS{
		Etcd:                []NodeDeets{fakeNode},
		Master:              []NodeDeets{fakeNode},
		Worker:              []NodeDeets{fakeNode},
		Ingress:             []NodeDeets{fakeNode},
		MasterNodeFQDN:      "yep.nope",
		MasterNodeShortName: "yep",
		SSHUser:             "Billy Rubin",
		SSHKeyFile:          sshKey,
	}
	By("Writing plan file out to disk")
	f, err := os.Create("kismatic-testing.yaml")
	FailIfError(err, "Error waiting for nodes")
	defer f.Close()
	w := bufio.NewWriter(f)
	err = template.Execute(w, &plan)
	FailIfError(err, "Error filling in plan template")
	w.Flush()
	f.Close()

	By("Validing our plan")
	cmd := exec.Command("./kismatic", "install", "validate", "-f", f.Name())
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	err = cmd.Run()
	if err == nil {
		Fail("Validation succeeeded even though it shouldn't have")
	}

	By("Well, try it anyway")
	cmd = exec.Command("./kismatic", "install", "apply", "-f", f.Name())
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	err = cmd.Run()
	if err == nil {
		Fail("Application succeeeded even though it shouldn't have")
	}
}

func completesInTime(dothis func(), howLong time.Duration) bool {
	c1 := make(chan string, 1)
	go func() {
		dothis()
		c1 <- "completed"
	}()

	select {
	case <-c1:
		return true
	case <-time.After(howLong):
		return false
	}
}

func canAccessDashboard() error {
	// Access the dashboard a few times to hit all replicas
	for i := 0; i < 3; i++ {
		cmd := exec.Command("./kismatic", "dashboard", "--url", "-f", "kismatic-testing.yaml")
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		if err := cmd.Run(); err != nil {
			return err
		}
	}

	return nil
}

func FailIfError(err error, message ...interface{}) {
	Expect(err).ToNot(HaveOccurred(), message...)
}

func FailIfSuccess(err error) {
	if err == nil {
		Fail("Expected failure")
	}
}

func FileExists(path string) bool {
	if _, err := os.Stat(path); os.IsNotExist(err) {
		return false
	}
	return true
}
<commit_msg>Use Pubilc IP for master FQDN during integration tests<commit_after>package integration

import (
	"bufio"
	"html/template"
	"os"
	"os/exec"
	"path/filepath"
	"time"

	homedir "github.com/mitchellh/go-homedir"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

func leaveIt() bool {
	return os.Getenv("LEAVE_ARTIFACTS") != ""
}

func GetSSHKeyFile() (string, error) {
	dir, err := homedir.Dir()
	if err != nil {
		return "", err
	}
	return filepath.Join(dir, ".ssh", "kismatic-integration-testing.pem"), nil
}

type installOptions struct {
	allowPackageInstallation    bool
	disconnectedInstallation    bool
	autoConfigureDockerRegistry bool
	dockerRegistryIP            string
	dockerRegistryPort          int
	dockerRegistryCAPath        string
	modifyHostsFiles            bool
}

func installKismaticMini(node NodeDeets, sshKey string) error {
	sshUser := node.SSHUser
	plan := PlanAWS{
		Etcd:                     []NodeDeets{node},
		Master:                   []NodeDeets{node},
		Worker:                   []NodeDeets{node},
		Ingress:                  []NodeDeets{node},
		Storage:                  []NodeDeets{node},
		MasterNodeFQDN:           node.PublicIP,
		MasterNodeShortName:      node.PublicIP,
		SSHKeyFile:               sshKey,
		SSHUser:                  sshUser,
		AllowPackageInstallation: true,
	}
	return installKismaticWithPlan(plan, sshKey)
}

func installKismatic(nodes provisionedNodes, installOpts installOptions, sshKey string) error {
	sshUser := nodes.master[0].SSHUser
	masterDNS := nodes.master[0].PublicIP
	if nodes.dnsRecord != nil && nodes.dnsRecord.Name != "" {
		masterDNS = nodes.dnsRecord.Name
	}
	plan := PlanAWS{
		AllowPackageInstallation: installOpts.allowPackageInstallation,
		DisconnectedInstallation: installOpts.disconnectedInstallation,
		Etcd:                nodes.etcd,
		Master:              nodes.master,
		Worker:              nodes.worker,
		Ingress:             nodes.ingress,
		Storage:             nodes.storage,
		MasterNodeFQDN:      masterDNS,
		MasterNodeShortName: masterDNS,
		SSHKeyFile:          sshKey,
		SSHUser:             sshUser,
		AutoConfiguredDockerRegistry: installOpts.autoConfigureDockerRegistry,
		DockerRegistryCAPath:         installOpts.dockerRegistryCAPath,
		DockerRegistryIP:             installOpts.dockerRegistryIP,
		DockerRegistryPort:           installOpts.dockerRegistryPort,
		ModifyHostsFiles:             installOpts.modifyHostsFiles,
	}
	return installKismaticWithPlan(plan, sshKey)
}

func installKismaticWithPlan(plan PlanAWS, sshKey string) error {
	By("Building a template")
	template, err := template.New("planAWSOverlay").Parse(planAWSOverlay)
	FailIfError(err, "Couldn't parse template")

	f, err := os.Create("kismatic-testing.yaml")
	FailIfError(err, "Error creating plan")
	defer f.Close()
	w := bufio.NewWriter(f)
	err = template.Execute(w, &plan)
	FailIfError(err, "Error filling in plan template")
	w.Flush()

	By("Punch it Chewie!")
	cmd := exec.Command("./kismatic", "install", "apply", "-f", f.Name())
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	return cmd.Run()
}

func installKismaticWithABadNode() {
	By("Building a template")
	template, err := template.New("planAWSOverlay").Parse(planAWSOverlay)
	FailIfError(err, "Couldn't parse template")

	By("Faking infrastructure")
	fakeNode := NodeDeets{
		id:       "FakeId",
		PublicIP: "10.0.0.0",
		Hostname: "FakeHostname",
	}

	By("Building a plan to set up an overlay network cluster on this hardware")
	sshKey, err := GetSSHKeyFile()
	FailIfError(err, "Error getting SSH Key file")
	plan := PlanAWS{
		Etcd:                []NodeDeets{fakeNode},
		Master:              []NodeDeets{fakeNode},
		Worker:              []NodeDeets{fakeNode},
		Ingress:             []NodeDeets{fakeNode},
		MasterNodeFQDN:      "yep.nope",
		MasterNodeShortName: "yep",
		SSHUser:             "Billy Rubin",
		SSHKeyFile:          sshKey,
	}
	By("Writing plan file out to disk")
	f, err := os.Create("kismatic-testing.yaml")
	FailIfError(err, "Error waiting for nodes")
	defer f.Close()
	w := bufio.NewWriter(f)
	err = template.Execute(w, &plan)
	FailIfError(err, "Error filling in plan template")
	w.Flush()
	f.Close()

	By("Validing our plan")
	cmd := exec.Command("./kismatic", "install", "validate", "-f", f.Name())
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	err = cmd.Run()
	if err == nil {
		Fail("Validation succeeeded even though it shouldn't have")
	}

	By("Well, try it anyway")
	cmd = exec.Command("./kismatic", "install", "apply", "-f", f.Name())
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	err = cmd.Run()
	if err == nil {
		Fail("Application succeeeded even though it shouldn't have")
	}
}

func completesInTime(dothis func(), howLong time.Duration) bool {
	c1 := make(chan string, 1)
	go func() {
		dothis()
		c1 <- "completed"
	}()

	select {
	case <-c1:
		return true
	case <-time.After(howLong):
		return false
	}
}

func canAccessDashboard() error {
	// Access the dashboard a few times to hit all replicas
	for i := 0; i < 3; i++ {
		cmd := exec.Command("./kismatic", "dashboard", "--url", "-f", "kismatic-testing.yaml")
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		if err := cmd.Run(); err != nil {
			return err
		}
	}

	return nil
}

func FailIfError(err error, message ...interface{}) {
	Expect(err).ToNot(HaveOccurred(), message...)
}

func FailIfSuccess(err error) {
	if err == nil {
		Fail("Expected failure")
	}
}

func FileExists(path string) bool {
	if _, err := os.Stat(path); os.IsNotExist(err) {
		return false
	}
	return true
}
<|endoftext|>


<commit_before>package dynect

import (
	"fmt"
	"log"
	"net/http"
	"strconv"
	"strings"
	"time"
)

// ConvenientClient A client with extra helper methods for common actions
type ConvenientClient struct {
	Client
}

// NewConvenientClient Creates a new ConvenientClient
func NewConvenientClient(customerName string) *ConvenientClient {
	return &ConvenientClient{
		Client{
			CustomerName: customerName,
			Transport:    &http.Transport{Proxy: http.ProxyFromEnvironment},
		}}
}

// CreateZone method to create a zone
func (c *ConvenientClient) CreateZone(zone, rname, serialStyle, ttl string) error {
	url := fmt.Sprintf("Zone/%s/", zone)
	data := &CreateZoneBlock{
		RName:       rname,
		SerialStyle: serialStyle,
		TTL:         ttl,
	}

	if err := c.Do("POST", url, data, nil); err != nil {
		return fmt.Errorf("Failed to create zone: %s", err)
	}

	return nil
}

// GetZone method to read a zone
func (c *ConvenientClient) GetZone(z *Zone) error {
	url := fmt.Sprintf("Zone/%s", z.Zone)
	data := &ZoneResponse{}

	if err := c.Do("GET", url, nil, data); err != nil {
		return fmt.Errorf("Failed to get zone: %s", err)
	}

	z.Serial = strconv.Itoa(data.Data.Serial)
	z.SerialStyle = data.Data.SerialStyle
	z.Zone = data.Data.Zone
	z.Type = data.Data.ZoneType

	return nil
}

// PublishZone Publish a specific zone and the changes for the current session
func (c *ConvenientClient) PublishZone(zone string) error {
	url := fmt.Sprintf("Zone/%s", zone)
	data := &PublishZoneBlock{
		Publish: true,
	}
	resp := &PublishZoneResponseBlock{}
	if err := c.Do("PUT", url, data, resp); err != nil {
		return fmt.Errorf("Failed to publish zone: %s", err)
	}
	url = fmt.Sprintf("Task/%s/", resp.Data.TaskID)
	respTask := &TaskStateResponse{}
	// Wait until the zone is published, but no more then 10s
	for i := 0; i < 100; i++ {
		if err := c.Do("GET", url, nil, respTask); err != nil {
			return fmt.Errorf("Failed to get task status: %s %s", resp.Data.TaskID, err)
		}
		log.Printf("Publishing zone %s. Status: %#+v : %#+v\n", zone, respTask.Data.Status, respTask)
		if respTask.Data.Status == "complete" {
			break
		}
		time.Sleep(100 * time.Millisecond)
	}

	return nil
}

// DeleteZoneNode method to delete everything in a zone
func (c *ConvenientClient) DeleteZoneNode(zone string) error {
	parentZone := strings.Join(strings.Split(zone, ".")[1:], ".")
	url := fmt.Sprintf("Node/%s/%s", parentZone, zone)

	if err := c.Do("DELETE", url, nil, nil); err != nil {
		return fmt.Errorf("Failed to delete zone node: %s", err)
	}

	return nil
}

// DeleteZone method to delete a zone
func (c *ConvenientClient) DeleteZone(zone string) error {
	url := fmt.Sprintf("Zone/%s/", zone)

	if err := c.Do("DELETE", url, nil, nil); err != nil {
		return fmt.Errorf("Failed to delete zone: %s", err)
	}

	return nil
}

// GetRecordID finds the dns record ID by fetching all records for a FQDN
func (c *ConvenientClient) GetRecordID(record *Record) error {
	finalID := ""
	url := fmt.Sprintf("AllRecord/%s/%s", record.Zone, record.FQDN)
	var records AllRecordsResponse
	err := c.Do("GET", url, nil, &records)
	if err != nil {
		return fmt.Errorf("Failed to find Dyn record id: %s", err)
	}
	for _, recordURL := range records.Data {
		id := strings.TrimPrefix(recordURL, fmt.Sprintf("/REST/%sRecord/%s/%s/", record.Type, record.Zone, record.FQDN))
		if !strings.Contains(id, "/") && id != "" {
			finalID = id
			log.Printf("[INFO] Found Dyn record ID: %s", id)
		}
	}
	if finalID == "" {
		return fmt.Errorf("Failed to find Dyn record id!")
	}

	record.ID = finalID
	return nil
}

// CreateRecord Method to create a DNS record
func (c *ConvenientClient) CreateRecord(record *Record) error {
	if record.FQDN == "" && record.Name == "" {
		record.FQDN = record.Zone
	} else if record.FQDN == "" {
		record.FQDN = fmt.Sprintf("%s.%s", record.Name, record.Zone)
	}
	rdata, err := buildRData(record)
	if err != nil {
		return fmt.Errorf("Failed to create Dyn RData: %s", err)
	}
	url := fmt.Sprintf("%sRecord/%s/%s", record.Type, record.Zone, record.FQDN)
	data := &RecordRequest{
		RData: rdata,
		TTL:   record.TTL,
	}
	return c.Do("POST", url, data, nil)
}

// UpdateRecord Method to update a DNS record
func (c *ConvenientClient) UpdateRecord(record *Record) error {
	if record.FQDN == "" {
		record.FQDN = fmt.Sprintf("%s.%s", record.Name, record.Zone)
	}
	rdata, err := buildRData(record)
	if err != nil {
		return fmt.Errorf("Failed to create Dyn RData: %s", err)
	}
	url := fmt.Sprintf("%sRecord/%s/%s/%s", record.Type, record.Zone, record.FQDN, record.ID)
	data := &RecordRequest{
		RData: rdata,
		TTL:   record.TTL,
	}
	return c.Do("PUT", url, data, nil)
}

// DeleteRecord Method to delete a DNS record
func (c *ConvenientClient) DeleteRecord(record *Record) error {
	if record.FQDN == "" {
		record.FQDN = fmt.Sprintf("%s.%s", record.Name, record.Zone)
	}
	// safety check that we have an ID, otherwise we could accidentally delete everything
	if record.ID == "" {
		return fmt.Errorf("No ID found! We can't continue!")
	}
	url := fmt.Sprintf("%sRecord/%s/%s/%s", record.Type, record.Zone, record.FQDN, record.ID)
	return c.Do("DELETE", url, nil, nil)
}

// GetRecord Method to get record details
func (c *ConvenientClient) GetRecord(record *Record) error {
	url := fmt.Sprintf("%sRecord/%s/%s/%s", record.Type, record.Zone, record.FQDN, record.ID)
	var rec RecordResponse
	err := c.Do("GET", url, nil, &rec)
	if err != nil {
		return err
	}

	record.Zone = rec.Data.Zone
	record.FQDN = rec.Data.FQDN
	record.Name = strings.TrimSuffix(rec.Data.FQDN, "."+rec.Data.Zone)
	record.Type = rec.Data.RecordType
	record.TTL = strconv.Itoa(rec.Data.TTL)

	switch rec.Data.RecordType {
	case "A", "AAAA":
		record.Value = rec.Data.RData.Address
	case "ALIAS":
		record.Value = rec.Data.RData.Alias
	case "CNAME":
		record.Value = rec.Data.RData.CName
	case "MX":
		record.Value = fmt.Sprintf("%d %s", rec.Data.RData.Preference, rec.Data.RData.Exchange)
	case "NS":
		record.Value = rec.Data.RData.NSDName
	case "SOA":
		record.Value = rec.Data.RData.RName
	case "TXT", "SPF":
		record.Value = rec.Data.RData.TxtData
	default:
		fmt.Println("unknown response", rec)
		return fmt.Errorf("Invalid Dyn record type: %s", rec.Data.RecordType)
	}

	return nil
}

func buildRData(r *Record) (DataBlock, error) {
	var rdata DataBlock

	switch r.Type {
	case "A", "AAAA":
		rdata = DataBlock{
			Address: r.Value,
		}
	case "ALIAS":
		rdata = DataBlock{
			Alias: r.Value,
		}
	case "CNAME":
		rdata = DataBlock{
			CName: r.Value,
		}
	case "MX":
		rdata = DataBlock{}
		fmt.Sscanf(r.Value, "%d %s", &rdata.Preference, &rdata.Exchange)
	case "NS":
		rdata = DataBlock{
			NSDName: r.Value,
		}
	case "SOA":
		rdata = DataBlock{
			RName: r.Value,
		}
	case "TXT", "SPF":
		rdata = DataBlock{
			TxtData: r.Value,
		}
	default:
		return rdata, fmt.Errorf("Invalid Dyn record type: %s", r.Type)
	}

	return rdata, nil
}
<commit_msg>better variables declaration<commit_after>package dynect

import (
	"fmt"
	"log"
	"net/http"
	"strconv"
	"strings"
	"time"
)

// ConvenientClient A client with extra helper methods for common actions
type ConvenientClient struct {
	Client
}

// NewConvenientClient Creates a new ConvenientClient
func NewConvenientClient(customerName string) *ConvenientClient {
	return &ConvenientClient{
		Client{
			CustomerName: customerName,
			Transport:    &http.Transport{Proxy: http.ProxyFromEnvironment},
		}}
}

// CreateZone method to create a zone
func (c *ConvenientClient) CreateZone(zone, rname, serialStyle, ttl string) error {
	url := fmt.Sprintf("Zone/%s/", zone)
	data := &CreateZoneBlock{
		RName:       rname,
		SerialStyle: serialStyle,
		TTL:         ttl,
	}

	if err := c.Do("POST", url, data, nil); err != nil {
		return fmt.Errorf("Failed to create zone: %s", err)
	}

	return nil
}

// GetZone method to read a zone
func (c *ConvenientClient) GetZone(z *Zone) error {
	url := fmt.Sprintf("Zone/%s", z.Zone)
	data := &ZoneResponse{}

	if err := c.Do("GET", url, nil, data); err != nil {
		return fmt.Errorf("Failed to get zone: %s", err)
	}

	z.Serial = strconv.Itoa(data.Data.Serial)
	z.SerialStyle = data.Data.SerialStyle
	z.Zone = data.Data.Zone
	z.Type = data.Data.ZoneType

	return nil
}

// PublishZone Publish a specific zone and the changes for the current session
func (c *ConvenientClient) PublishZone(zone string) error {
	url := fmt.Sprintf("Zone/%s", zone)
	data := &PublishZoneBlock{
		Publish: true,
	}
	var resp PublishZoneResponseBlock
	if err := c.Do("PUT", url, data, &resp); err != nil {
		return fmt.Errorf("Failed to publish zone: %s", err)
	}
	url = fmt.Sprintf("Task/%s/", resp.Data.TaskID)
	// Wait until the zone is published, but no more then 10s
	for i := 0; i < 100; i++ {
		var respTask TaskStateResponse
		if err := c.Do("GET", url, nil, &respTask); err != nil {
			return fmt.Errorf("Failed to get task status: %s %s", resp.Data.TaskID, err)
		}
		log.Printf("Publishing zone %s. Status: %#+v : %#+v\n", zone, respTask.Data.Status, respTask)
		if respTask.Data.Status == "complete" {
			break
		}
		time.Sleep(100 * time.Millisecond)
	}

	return nil
}

// DeleteZoneNode method to delete everything in a zone
func (c *ConvenientClient) DeleteZoneNode(zone string) error {
	parentZone := strings.Join(strings.Split(zone, ".")[1:], ".")
	url := fmt.Sprintf("Node/%s/%s", parentZone, zone)

	if err := c.Do("DELETE", url, nil, nil); err != nil {
		return fmt.Errorf("Failed to delete zone node: %s", err)
	}

	return nil
}

// DeleteZone method to delete a zone
func (c *ConvenientClient) DeleteZone(zone string) error {
	url := fmt.Sprintf("Zone/%s/", zone)

	if err := c.Do("DELETE", url, nil, nil); err != nil {
		return fmt.Errorf("Failed to delete zone: %s", err)
	}

	return nil
}

// GetRecordID finds the dns record ID by fetching all records for a FQDN
func (c *ConvenientClient) GetRecordID(record *Record) error {
	finalID := ""
	url := fmt.Sprintf("AllRecord/%s/%s", record.Zone, record.FQDN)
	var records AllRecordsResponse
	err := c.Do("GET", url, nil, &records)
	if err != nil {
		return fmt.Errorf("Failed to find Dyn record id: %s", err)
	}
	for _, recordURL := range records.Data {
		id := strings.TrimPrefix(recordURL, fmt.Sprintf("/REST/%sRecord/%s/%s/", record.Type, record.Zone, record.FQDN))
		if !strings.Contains(id, "/") && id != "" {
			finalID = id
			log.Printf("[INFO] Found Dyn record ID: %s", id)
		}
	}
	if finalID == "" {
		return fmt.Errorf("Failed to find Dyn record id!")
	}

	record.ID = finalID
	return nil
}

// CreateRecord Method to create a DNS record
func (c *ConvenientClient) CreateRecord(record *Record) error {
	if record.FQDN == "" && record.Name == "" {
		record.FQDN = record.Zone
	} else if record.FQDN == "" {
		record.FQDN = fmt.Sprintf("%s.%s", record.Name, record.Zone)
	}
	rdata, err := buildRData(record)
	if err != nil {
		return fmt.Errorf("Failed to create Dyn RData: %s", err)
	}
	url := fmt.Sprintf("%sRecord/%s/%s", record.Type, record.Zone, record.FQDN)
	data := &RecordRequest{
		RData: rdata,
		TTL:   record.TTL,
	}
	return c.Do("POST", url, data, nil)
}

// UpdateRecord Method to update a DNS record
func (c *ConvenientClient) UpdateRecord(record *Record) error {
	if record.FQDN == "" {
		record.FQDN = fmt.Sprintf("%s.%s", record.Name, record.Zone)
	}
	rdata, err := buildRData(record)
	if err != nil {
		return fmt.Errorf("Failed to create Dyn RData: %s", err)
	}
	url := fmt.Sprintf("%sRecord/%s/%s/%s", record.Type, record.Zone, record.FQDN, record.ID)
	data := &RecordRequest{
		RData: rdata,
		TTL:   record.TTL,
	}
	return c.Do("PUT", url, data, nil)
}

// DeleteRecord Method to delete a DNS record
func (c *ConvenientClient) DeleteRecord(record *Record) error {
	if record.FQDN == "" {
		record.FQDN = fmt.Sprintf("%s.%s", record.Name, record.Zone)
	}
	// safety check that we have an ID, otherwise we could accidentally delete everything
	if record.ID == "" {
		return fmt.Errorf("No ID found! We can't continue!")
	}
	url := fmt.Sprintf("%sRecord/%s/%s/%s", record.Type, record.Zone, record.FQDN, record.ID)
	return c.Do("DELETE", url, nil, nil)
}

// GetRecord Method to get record details
func (c *ConvenientClient) GetRecord(record *Record) error {
	url := fmt.Sprintf("%sRecord/%s/%s/%s", record.Type, record.Zone, record.FQDN, record.ID)
	var rec RecordResponse
	err := c.Do("GET", url, nil, &rec)
	if err != nil {
		return err
	}

	record.Zone = rec.Data.Zone
	record.FQDN = rec.Data.FQDN
	record.Name = strings.TrimSuffix(rec.Data.FQDN, "."+rec.Data.Zone)
	record.Type = rec.Data.RecordType
	record.TTL = strconv.Itoa(rec.Data.TTL)

	switch rec.Data.RecordType {
	case "A", "AAAA":
		record.Value = rec.Data.RData.Address
	case "ALIAS":
		record.Value = rec.Data.RData.Alias
	case "CNAME":
		record.Value = rec.Data.RData.CName
	case "MX":
		record.Value = fmt.Sprintf("%d %s", rec.Data.RData.Preference, rec.Data.RData.Exchange)
	case "NS":
		record.Value = rec.Data.RData.NSDName
	case "SOA":
		record.Value = rec.Data.RData.RName
	case "TXT", "SPF":
		record.Value = rec.Data.RData.TxtData
	default:
		fmt.Println("unknown response", rec)
		return fmt.Errorf("Invalid Dyn record type: %s", rec.Data.RecordType)
	}

	return nil
}

func buildRData(r *Record) (DataBlock, error) {
	var rdata DataBlock

	switch r.Type {
	case "A", "AAAA":
		rdata = DataBlock{
			Address: r.Value,
		}
	case "ALIAS":
		rdata = DataBlock{
			Alias: r.Value,
		}
	case "CNAME":
		rdata = DataBlock{
			CName: r.Value,
		}
	case "MX":
		rdata = DataBlock{}
		fmt.Sscanf(r.Value, "%d %s", &rdata.Preference, &rdata.Exchange)
	case "NS":
		rdata = DataBlock{
			NSDName: r.Value,
		}
	case "SOA":
		rdata = DataBlock{
			RName: r.Value,
		}
	case "TXT", "SPF":
		rdata = DataBlock{
			TxtData: r.Value,
		}
	default:
		return rdata, fmt.Errorf("Invalid Dyn record type: %s", r.Type)
	}

	return rdata, nil
}
<|endoftext|>


<commit_before>package genetics

import (
	"testing"
	"bytes"
	"github.com/yaricom/goNEAT/neat"
	"fmt"
	"strings"
	"bufio"
	"github.com/yaricom/goNEAT/neat/network"
	"reflect"
)

func TestPlainGenomeWriter_WriteTrait(t *testing.T) {
	params := []float64{
		0.40227575878298616, 0.0, 0.0, 0.0, 0.0, 0.3245553261200018, 0.0, 0.12248956525856575,
	}
	trait_id := 2
	trait := neat.NewTrait()
	trait.Id = trait_id
	trait.Params = params

	trait_str := fmt.Sprintf("%d %g %g %g %g %g %g %g %g",
		trait_id, params[0], params[1], params[2], params[3], params[4], params[5], params[6], params[7])

	out_buffer := bytes.NewBufferString("")
	wr := plainGenomeWriter{w:bufio.NewWriter(out_buffer)}
	err := wr.writeTrait(trait)
	if err != nil {
		t.Error(err)
		return
	}
	wr.w.Flush()

	out_str := strings.TrimSpace(out_buffer.String())
	if trait_str != out_str {
		t.Errorf("Wrong trait serialization\n[%s]\n[%s]", trait_str, out_str)
	}
}

// Tests NNode serialization
func TestPlainGenomeWriter_WriteNetworkNode(t *testing.T) {
	node_id, trait_id, ntype, neuron_type := 1, 10, network.SensorNode, network.InputNeuron
	node_str := fmt.Sprintf("%d %d %d %d SigmoidSteepenedActivation", node_id, trait_id, ntype, neuron_type)
	trait := neat.NewTrait()
	trait.Id = 10

	node := network.NewNNode(node_id, neuron_type)
	node.Trait = trait
	out_buffer := bytes.NewBufferString("")

	wr := plainGenomeWriter{w:bufio.NewWriter(out_buffer)}
	err := wr.writeNetworkNode(node)
	if err != nil {
		t.Error(err)
		return
	}
	wr.w.Flush()

	out_str := out_buffer.String()

	if out_str != node_str {
		t.Errorf("Node serialization failed. Expected: %s, but found %s", node_str, out_str)
	}
}

func TestPlainGenomeWriter_WriteConnectionGene(t *testing.T) {
	// gene  1 1 4 1.1983046913458986 0 1.0 1.1983046913458986 0
	traitId, inNodeId, outNodeId, innov_num := 1, 1, 4, int64(1)
	weight, mut_num := 1.1983046913458986, 1.1983046913458986
	recurrent, enabled := false, false
	gene_str := fmt.Sprintf("%d %d %d %g %t %d %g %t",
		traitId, inNodeId, outNodeId, weight, recurrent, innov_num, mut_num, enabled)

	trait := neat.NewTrait()
	trait.Id = traitId
	gene := NewGeneWithTrait(trait, weight, network.NewNNode(1, network.InputNeuron),
		network.NewNNode(4, network.HiddenNeuron), recurrent, innov_num, mut_num)
	gene.IsEnabled = enabled

	out_buf := bytes.NewBufferString("")

	wr := plainGenomeWriter{w:bufio.NewWriter(out_buf)}
	err := wr.writeConnectionGene(gene)
	if err != nil {
		t.Error(err)
		return
	}
	wr.w.Flush()

	out_str := out_buf.String()
	if gene_str != out_str {
		t.Errorf("Wrong Gene serialization\n[%s]\n[%s]", gene_str, out_str)
	}
}

func TestPlainGenomeWriter_WriteGenome(t *testing.T) {
	gnome := buildTestGenome(1)
	out_buf := bytes.NewBufferString("")
	wr, err := NewGenomeWriter(bufio.NewWriter(out_buf), PlainGenomeEncoding)
	if err == nil {
		err = wr.WriteGenome(gnome)
	}
	if err != nil {
		t.Error(err)
		return
	}

	g_scanner := bufio.NewScanner(strings.NewReader(gnome_str))
	g_scanner.Split(bufio.ScanLines)

	o_scanner := bufio.NewScanner(out_buf)
	o_scanner.Split(bufio.ScanLines)

	for g_scanner.Scan() {
		if !o_scanner.Scan() {
			t.Error("Unexpected end of genome data")
		}
		g_text := g_scanner.Text()
		o_text := o_scanner.Text()
		if g_text != o_text {
			t.Error(fmt.Sprintf("Lines mismatch [%s] != [%s]" , g_text, o_text))
		}
	}
}

func TestYamlGenomeWriter_WriteGenome(t *testing.T) {
	gnome := buildTestGenome(1)

	// append module with it's IO nodes
	io_nodes := []*network.NNode{
		{Id:5, NeuronType: network.HiddenNeuron, ActivationType: network.LinearActivation, Incoming:make([]*network.Link, 0), Outgoing:make([]*network.Link, 0)},
		{Id:6, NeuronType: network.HiddenNeuron, ActivationType: network.LinearActivation, Incoming:make([]*network.Link, 0), Outgoing:make([]*network.Link, 0)},
		{Id:7, NeuronType: network.HiddenNeuron, ActivationType: network.NullActivation, Incoming:make([]*network.Link, 0), Outgoing:make([]*network.Link, 0)},
	}
	gnome.Nodes = append(gnome.Nodes, io_nodes ...)

	// connect added nodes
	io_conn_genes := []*Gene{
		newGene(network.NewLinkWithTrait(gnome.Traits[0], 1.5, gnome.Nodes[0], gnome.Nodes[4], false), 4, 0, true),
		newGene(network.NewLinkWithTrait(gnome.Traits[2], 2.5, gnome.Nodes[1], gnome.Nodes[5], false), 5, 0, true),
		newGene(network.NewLinkWithTrait(gnome.Traits[1], 3.5, gnome.Nodes[6], gnome.Nodes[3], false), 6, 0, true),
	}
	gnome.Genes = append(gnome.Genes, io_conn_genes ...)

	// add control gene
	c_node := &network.NNode{
		Id:8, NeuronType: network.HiddenNeuron,
		ActivationType: network.MultiplyModuleActivation,
	}
	c_node.Incoming = []*network.Link{
		{Weight:1.0, InNode:io_nodes[0], OutNode:c_node},
		{Weight:1.0, InNode:io_nodes[1], OutNode:c_node},
	}
	c_node.Outgoing = []*network.Link{
		{Weight:1.0, InNode:c_node, OutNode:io_nodes[2]},
	}
	gnome.ControlGenes = []*MIMOControlGene{newMIMOGene(c_node, int64(7), 5.5, true)}

	// encode genome
	out_buf := bytes.NewBufferString("")
	wr, err := NewGenomeWriter(bufio.NewWriter(out_buf), YAMLGenomeEncoding)
	if err == nil {
		err = wr.WriteGenome(gnome)
	}
	if err != nil {
		t.Error(err)
		return
	}
	//t.Log(out_buf.String())

	// decode genome and compare
	enc := yamlGenomeReader{r:bufio.NewReader(bytes.NewBuffer(out_buf.Bytes()))}
	gnome_enc, err := enc.Read()
	if err != nil {
		t.Error(err)
		return
	}

	if gnome.Id != gnome_enc.Id {
		t.Error("gnome.Id != gnome_enc.Id", gnome.Id, gnome_enc.Id)
	}
	if len(gnome.Genes) != len(gnome_enc.Genes) {
		t.Error("len(gnome.Genes) != len(gnome_enc.Genes)", len(gnome.Genes), len(gnome_enc.Genes))
	}
	for i, g := range gnome.Genes {
		og := gnome_enc.Genes[i]
		if !g.Link.IsEqualGenetically(og.Link) {
			t.Error("!g.Link.IsEqualGenetically(og.Link) at:", i)
		}
		if g.IsEnabled != og.IsEnabled {
			t.Error("g.IsEnabled != og.IsEnabled at:", i)
		}
		if g.MutationNum != og.MutationNum {
			t.Error("g.MutationNum != og.MutationNum at:", i)
		}
		if g.InnovationNum != og.InnovationNum {
			t.Error("g.InnovationNum != og.InnovationNum at:", i)
		}
	}

	if len(gnome.Nodes) != len(gnome_enc.Nodes) {
		t.Error("len(gnome.Nodes) != len(gnome_enc.Nodes)", len(gnome.Nodes), len(gnome_enc.Nodes))
	}
	for i, n := range gnome.Nodes {
		nd := gnome_enc.Nodes[i]
		if n.Id != nd.Id {
			t.Error("n.Id != nd.Id at:", i)
		}
		if n.ActivationType != nd.ActivationType {
			t.Error("n.ActivationType != nd.ActivationType at:", i)
		}
		if n.NeuronType != nd.NeuronType {
			t.Error("n.NeuronType != nd.NeuronType at:", i)
		}
	}

	if len(gnome.Traits) != len(gnome_enc.Traits) {
		t.Error("len(gnome.Traits) != len(gnome_enc.Traits)", len(gnome.Traits), len(gnome_enc.Traits))
	}
	for i, tr := range gnome.Traits {
		etr := gnome_enc.Traits[i]
		if tr.Id != etr.Id {
			t.Error("tr.Id != etr.Id at:", i)
		}
		if !reflect.DeepEqual(tr.Params, etr.Params) {
			t.Error("!reflect.DeepEqual(tr.Params, etr.Params) at:", i)
		}
	}

	if len(gnome.ControlGenes) != len(gnome_enc.ControlGenes) {
		t.Error("len(gnome.ControlGenes) != len(gnome_enc.ControlGenes)",
			len(gnome.ControlGenes), len(gnome_enc.ControlGenes))
	}
	for i, cg := range gnome.ControlGenes {
		ocg := gnome_enc.ControlGenes[i]
		if cg.IsEnabled != ocg.IsEnabled {
			t.Error("cg.IsEnabled != ocg.IsEnabled at: ", i)
		}
		if cg.MutationNum != ocg.MutationNum {
			t.Error("cg.MutationNum != ocg.MutationNum at:", i)
		}
		if cg.InnovationNum != ocg.InnovationNum {
			t.Error("cg.InnovationNum != ocg.InnovationNum at:", i)
		}
		if cg.ControlNode.Id != ocg.ControlNode.Id {
			t.Error("cg.ControlNode.Id != ocg.ControlNode.Id at:", i, cg.ControlNode.Id, ocg.ControlNode.Id)
		}
		checkLinks(cg.ControlNode.Incoming, ocg.ControlNode.Incoming, t)
		checkLinks(cg.ControlNode.Outgoing, ocg.ControlNode.Outgoing, t)
	}
}

func checkLinks(left, right []*network.Link, t *testing.T) {
	if len(left) != len(right) {
		t.Error("Links size mismatch", len(left), len(right))
	}
	for i, l := range left {
		r := right[i]
		if l.InNode.Id != r.InNode.Id {
			t.Error("l.InNode.Id != r.InNode.Id", l.InNode.Id, r.InNode.Id)
		}
		if l.OutNode.Id != r.OutNode.Id {
			t.Error("l.OutNode.Id != r.OutNode.Id", l.OutNode.Id, r.OutNode.Id )
		}
		if l.Weight != r.Weight {
			t.Error("l.Weight != r.Weight", l.Weight, r.Weight)
		}
	}
}<commit_msg>Modular genome build routine extracted into separate function<commit_after>package genetics

import (
	"testing"
	"bytes"
	"github.com/yaricom/goNEAT/neat"
	"fmt"
	"strings"
	"bufio"
	"github.com/yaricom/goNEAT/neat/network"
	"reflect"
)

func TestPlainGenomeWriter_WriteTrait(t *testing.T) {
	params := []float64{
		0.40227575878298616, 0.0, 0.0, 0.0, 0.0, 0.3245553261200018, 0.0, 0.12248956525856575,
	}
	trait_id := 2
	trait := neat.NewTrait()
	trait.Id = trait_id
	trait.Params = params

	trait_str := fmt.Sprintf("%d %g %g %g %g %g %g %g %g",
		trait_id, params[0], params[1], params[2], params[3], params[4], params[5], params[6], params[7])

	out_buffer := bytes.NewBufferString("")
	wr := plainGenomeWriter{w:bufio.NewWriter(out_buffer)}
	err := wr.writeTrait(trait)
	if err != nil {
		t.Error(err)
		return
	}
	wr.w.Flush()

	out_str := strings.TrimSpace(out_buffer.String())
	if trait_str != out_str {
		t.Errorf("Wrong trait serialization\n[%s]\n[%s]", trait_str, out_str)
	}
}

// Tests NNode serialization
func TestPlainGenomeWriter_WriteNetworkNode(t *testing.T) {
	node_id, trait_id, ntype, neuron_type := 1, 10, network.SensorNode, network.InputNeuron
	node_str := fmt.Sprintf("%d %d %d %d SigmoidSteepenedActivation", node_id, trait_id, ntype, neuron_type)
	trait := neat.NewTrait()
	trait.Id = 10

	node := network.NewNNode(node_id, neuron_type)
	node.Trait = trait
	out_buffer := bytes.NewBufferString("")

	wr := plainGenomeWriter{w:bufio.NewWriter(out_buffer)}
	err := wr.writeNetworkNode(node)
	if err != nil {
		t.Error(err)
		return
	}
	wr.w.Flush()

	out_str := out_buffer.String()

	if out_str != node_str {
		t.Errorf("Node serialization failed. Expected: %s, but found %s", node_str, out_str)
	}
}

func TestPlainGenomeWriter_WriteConnectionGene(t *testing.T) {
	// gene  1 1 4 1.1983046913458986 0 1.0 1.1983046913458986 0
	traitId, inNodeId, outNodeId, innov_num := 1, 1, 4, int64(1)
	weight, mut_num := 1.1983046913458986, 1.1983046913458986
	recurrent, enabled := false, false
	gene_str := fmt.Sprintf("%d %d %d %g %t %d %g %t",
		traitId, inNodeId, outNodeId, weight, recurrent, innov_num, mut_num, enabled)

	trait := neat.NewTrait()
	trait.Id = traitId
	gene := NewGeneWithTrait(trait, weight, network.NewNNode(1, network.InputNeuron),
		network.NewNNode(4, network.HiddenNeuron), recurrent, innov_num, mut_num)
	gene.IsEnabled = enabled

	out_buf := bytes.NewBufferString("")

	wr := plainGenomeWriter{w:bufio.NewWriter(out_buf)}
	err := wr.writeConnectionGene(gene)
	if err != nil {
		t.Error(err)
		return
	}
	wr.w.Flush()

	out_str := out_buf.String()
	if gene_str != out_str {
		t.Errorf("Wrong Gene serialization\n[%s]\n[%s]", gene_str, out_str)
	}
}

func TestPlainGenomeWriter_WriteGenome(t *testing.T) {
	gnome := buildTestGenome(1)
	out_buf := bytes.NewBufferString("")
	wr, err := NewGenomeWriter(bufio.NewWriter(out_buf), PlainGenomeEncoding)
	if err == nil {
		err = wr.WriteGenome(gnome)
	}
	if err != nil {
		t.Error(err)
		return
	}

	g_scanner := bufio.NewScanner(strings.NewReader(gnome_str))
	g_scanner.Split(bufio.ScanLines)

	o_scanner := bufio.NewScanner(out_buf)
	o_scanner.Split(bufio.ScanLines)

	for g_scanner.Scan() {
		if !o_scanner.Scan() {
			t.Error("Unexpected end of genome data")
		}
		g_text := g_scanner.Text()
		o_text := o_scanner.Text()
		if g_text != o_text {
			t.Error(fmt.Sprintf("Lines mismatch [%s] != [%s]" , g_text, o_text))
		}
	}
}

func TestYamlGenomeWriter_WriteGenome(t *testing.T) {
	gnome := buildTestModularGenome(1)

	// encode genome
	out_buf := bytes.NewBufferString("")
	wr, err := NewGenomeWriter(bufio.NewWriter(out_buf), YAMLGenomeEncoding)
	if err == nil {
		err = wr.WriteGenome(gnome)
	}
	if err != nil {
		t.Error(err)
		return
	}
	//t.Log(out_buf.String())

	// decode genome and compare
	enc := yamlGenomeReader{r:bufio.NewReader(bytes.NewBuffer(out_buf.Bytes()))}
	gnome_enc, err := enc.Read()
	if err != nil {
		t.Error(err)
		return
	}

	if gnome.Id != gnome_enc.Id {
		t.Error("gnome.Id != gnome_enc.Id", gnome.Id, gnome_enc.Id)
	}
	if len(gnome.Genes) != len(gnome_enc.Genes) {
		t.Error("len(gnome.Genes) != len(gnome_enc.Genes)", len(gnome.Genes), len(gnome_enc.Genes))
	}
	for i, g := range gnome.Genes {
		og := gnome_enc.Genes[i]
		if !g.Link.IsEqualGenetically(og.Link) {
			t.Error("!g.Link.IsEqualGenetically(og.Link) at:", i)
		}
		if g.IsEnabled != og.IsEnabled {
			t.Error("g.IsEnabled != og.IsEnabled at:", i)
		}
		if g.MutationNum != og.MutationNum {
			t.Error("g.MutationNum != og.MutationNum at:", i)
		}
		if g.InnovationNum != og.InnovationNum {
			t.Error("g.InnovationNum != og.InnovationNum at:", i)
		}
	}

	if len(gnome.Nodes) != len(gnome_enc.Nodes) {
		t.Error("len(gnome.Nodes) != len(gnome_enc.Nodes)", len(gnome.Nodes), len(gnome_enc.Nodes))
	}
	for i, n := range gnome.Nodes {
		nd := gnome_enc.Nodes[i]
		if n.Id != nd.Id {
			t.Error("n.Id != nd.Id at:", i)
		}
		if n.ActivationType != nd.ActivationType {
			t.Error("n.ActivationType != nd.ActivationType at:", i)
		}
		if n.NeuronType != nd.NeuronType {
			t.Error("n.NeuronType != nd.NeuronType at:", i)
		}
	}

	if len(gnome.Traits) != len(gnome_enc.Traits) {
		t.Error("len(gnome.Traits) != len(gnome_enc.Traits)", len(gnome.Traits), len(gnome_enc.Traits))
	}
	for i, tr := range gnome.Traits {
		etr := gnome_enc.Traits[i]
		if tr.Id != etr.Id {
			t.Error("tr.Id != etr.Id at:", i)
		}
		if !reflect.DeepEqual(tr.Params, etr.Params) {
			t.Error("!reflect.DeepEqual(tr.Params, etr.Params) at:", i)
		}
	}

	if len(gnome.ControlGenes) != len(gnome_enc.ControlGenes) {
		t.Error("len(gnome.ControlGenes) != len(gnome_enc.ControlGenes)",
			len(gnome.ControlGenes), len(gnome_enc.ControlGenes))
	}
	for i, cg := range gnome.ControlGenes {
		ocg := gnome_enc.ControlGenes[i]
		if cg.IsEnabled != ocg.IsEnabled {
			t.Error("cg.IsEnabled != ocg.IsEnabled at: ", i)
		}
		if cg.MutationNum != ocg.MutationNum {
			t.Error("cg.MutationNum != ocg.MutationNum at:", i)
		}
		if cg.InnovationNum != ocg.InnovationNum {
			t.Error("cg.InnovationNum != ocg.InnovationNum at:", i)
		}
		if cg.ControlNode.Id != ocg.ControlNode.Id {
			t.Error("cg.ControlNode.Id != ocg.ControlNode.Id at:", i, cg.ControlNode.Id, ocg.ControlNode.Id)
		}
		checkLinks(cg.ControlNode.Incoming, ocg.ControlNode.Incoming, t)
		checkLinks(cg.ControlNode.Outgoing, ocg.ControlNode.Outgoing, t)
	}
}

func checkLinks(left, right []*network.Link, t *testing.T) {
	if len(left) != len(right) {
		t.Error("Links size mismatch", len(left), len(right))
	}
	for i, l := range left {
		r := right[i]
		if l.InNode.Id != r.InNode.Id {
			t.Error("l.InNode.Id != r.InNode.Id", l.InNode.Id, r.InNode.Id)
		}
		if l.OutNode.Id != r.OutNode.Id {
			t.Error("l.OutNode.Id != r.OutNode.Id", l.OutNode.Id, r.OutNode.Id )
		}
		if l.Weight != r.Weight {
			t.Error("l.Weight != r.Weight", l.Weight, r.Weight)
		}
	}
}<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"strings"

	"github.com/sirupsen/logrus"
	"k8s.io/client-go/rest"
)

func main() {
	initLogrus()

	kubeClient, err := createKubeClient()
	if err != nil {
		panic(err)
	}

	webhook := newWebhook(kubeClient)

	tlsConfig := &tlsConfig{
		crtPath: env("TLS_CRT"),
		keyPath: env("TLS_KEY"),
	}

	if err = webhook.start(443, tlsConfig, nil); err != nil {
		panic(err)
	}
}

var logLevels = map[string]logrus.Level{
	"panic": logrus.PanicLevel,
	"fatal": logrus.FatalLevel,
	"error": logrus.ErrorLevel,
	"warn":  logrus.WarnLevel,
	"info":  logrus.InfoLevel,
	"debug": logrus.DebugLevel,
	"trace": logrus.TraceLevel,
}

func initLogrus() {
	logrus.SetOutput(os.Stdout)

	logLevel := logrus.DebugLevel
	invalid := false

	rawLogLevel, present := os.LookupEnv("LOG_LEVEL")
	if present {
		if level, valid := logLevels[strings.ToLower(rawLogLevel)]; valid {
			logLevel = level
		} else {
			invalid = true
		}
	}

	logrus.SetLevel(logLevel)

	if invalid {
		keys := make([]string, len(logLevels))
		i := 0
		for key := range logLevels {
			keys[i] = key
			i++
		}
		logrus.Warningf("Unknown log level %s, valid log levels are: %v", rawLogLevel, strings.Join(keys, ", "))
	}
}

func createKubeClient() (*kubeClient, error) {
	config, err := rest.InClusterConfig()
	if err != nil {
		return nil, err
	}

	return newKubeClient(config)
}

func env(key string) string {
	if value, found := os.LookupEnv(key); found {
		return value
	}
	panic(fmt.Errorf("%s env var not found", key))
}
<commit_msg>Adding the ability to configure the webhook port.<commit_after>package main

import (
	"fmt"
	"os"
	"strconv"
	"strings"

	"github.com/sirupsen/logrus"
	"k8s.io/client-go/rest"
)

func main() {
	initLogrus()

	kubeClient, err := createKubeClient()
	if err != nil {
		panic(err)
	}

	webhook := newWebhook(kubeClient)

	tlsConfig := &tlsConfig{
		crtPath: env("TLS_CRT"),
		keyPath: env("TLS_KEY"),
	}

	port, err := port("HTTPS_PORT")
	if err != nil {
		panic(err)
	}

	if err = webhook.start(port, tlsConfig, nil); err != nil {
		panic(err)
	}
}

var logLevels = map[string]logrus.Level{
	"panic": logrus.PanicLevel,
	"fatal": logrus.FatalLevel,
	"error": logrus.ErrorLevel,
	"warn":  logrus.WarnLevel,
	"info":  logrus.InfoLevel,
	"debug": logrus.DebugLevel,
	"trace": logrus.TraceLevel,
}

func initLogrus() {
	logrus.SetOutput(os.Stdout)

	logLevel := logrus.DebugLevel
	invalid := false

	rawLogLevel, present := os.LookupEnv("LOG_LEVEL")
	if present {
		if level, valid := logLevels[strings.ToLower(rawLogLevel)]; valid {
			logLevel = level
		} else {
			invalid = true
		}
	}

	logrus.SetLevel(logLevel)

	if invalid {
		keys := make([]string, len(logLevels))
		i := 0
		for key := range logLevels {
			keys[i] = key
			i++
		}
		logrus.Warningf("Unknown log level %s, valid log levels are: %v", rawLogLevel, strings.Join(keys, ", "))
	}
}

func createKubeClient() (*kubeClient, error) {
	config, err := rest.InClusterConfig()
	if err != nil {
		return nil, err
	}

	return newKubeClient(config)
}

func env(key string) string {
	if value, found := os.LookupEnv(key); found {
		return value
	}
	panic(fmt.Errorf("%s env var not found", key))
}

func port(key string) (int, error) {
	if port, found := os.LookupEnv(key); found {
		return strconv.Atoi(port)
	}
	return 443, nil
}
<|endoftext|>


<commit_before>// Copyright 2015 Hajime Hoshi
//
// 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.

// +build darwin freebsd linux windows
// +build !js
// +build !android
// +build !ios

package ui

import (
	"errors"
	"runtime"
	"sync"
	"time"

	"github.com/go-gl/glfw/v3.2/glfw"
	"github.com/hajimehoshi/ebiten/internal/opengl"
)

type userInterface struct {
	window      *glfw.Window
	width       int
	height      int
	scale       float64
	deviceScale float64
	funcs       chan func()
	running     bool
	sizeChanged bool
	m           sync.Mutex
}

var currentUI *userInterface

func init() {
	if err := initialize(); err != nil {
		panic(err)
	}
}

func initialize() error {
	runtime.LockOSThread()

	if err := glfw.Init(); err != nil {
		return err
	}
	glfw.WindowHint(glfw.Visible, glfw.False)
	glfw.WindowHint(glfw.Resizable, glfw.False)
	glfw.WindowHint(glfw.ContextVersionMajor, 2)
	glfw.WindowHint(glfw.ContextVersionMinor, 1)

	// As start, create an window with temporary size to create OpenGL context thread.
	window, err := glfw.CreateWindow(16, 16, "", nil, nil)
	if err != nil {
		return err
	}
	hideConsoleWindowOnWindows()
	u := &userInterface{
		window:      window,
		funcs:       make(chan func()),
		sizeChanged: true,
	}
	u.window.MakeContextCurrent()
	glfw.SwapInterval(1)
	currentUI = u
	return nil
}

func RunMainThreadLoop(ch <-chan error) error {
	// TODO: Check this is done on the main thread.
	currentUI.setRunning(true)
	defer func() {
		currentUI.setRunning(false)
	}()
	for {
		select {
		case f := <-currentUI.funcs:
			f()
		case err := <-ch:
			// ch returns a value not only when an error occur but also it is closed.
			return err
		}
	}
}

func (u *userInterface) isRunning() bool {
	u.m.Lock()
	defer u.m.Unlock()
	return u.running
}

func (u *userInterface) setRunning(running bool) {
	u.m.Lock()
	defer u.m.Unlock()
	u.running = running
}

func (u *userInterface) runOnMainThread(f func() error) error {
	if u.funcs == nil {
		// already closed
		return nil
	}
	ch := make(chan struct{})
	var err error
	u.funcs <- func() {
		err = f()
		close(ch)
	}
	<-ch
	return err
}

func SetScreenSize(width, height int) bool {
	u := currentUI
	if !u.isRunning() {
		panic("ui: Run is not called yet")
	}
	r := false
	_ = u.runOnMainThread(func() error {
		u.setScreenSize(width, height, u.scale)
		return nil
	})
	return r
}

func SetScreenScale(scale float64) bool {
	u := currentUI
	if !u.isRunning() {
		panic("ui: Run is not called yet")
	}
	r := false
	_ = u.runOnMainThread(func() error {
		u.setScreenSize(u.width, u.height, scale)
		return nil
	})
	return r
}

func ScreenScale() float64 {
	u := currentUI
	if !u.isRunning() {
		return 0
	}
	s := 0.0
	_ = u.runOnMainThread(func() error {
		s = u.scale
		return nil
	})
	return s
}

func SetCursorVisibility(visible bool) {
	// This can be called before Run: change the state asyncly.
	go func() {
		_ = currentUI.runOnMainThread(func() error {
			c := glfw.CursorNormal
			if !visible {
				c = glfw.CursorHidden
			}
			currentUI.window.SetInputMode(glfw.CursorMode, c)
			return nil
		})
	}()
}

func Run(width, height int, scale float64, title string, g GraphicsContext) error {
	u := currentUI
	// GLContext must be created before setting the screen size, which requires
	// swapping buffers.
	opengl.Init(currentUI.runOnMainThread)
	if err := u.runOnMainThread(func() error {
		m := glfw.GetPrimaryMonitor()
		v := m.GetVideoMode()
		if !u.setScreenSize(width, height, scale) {
			return errors.New("ui: Fail to set the screen size")
		}
		u.window.SetTitle(title)
		u.window.Show()

		w, h := u.glfwSize()
		x := (v.Width - w) / 2
		y := (v.Height - h) / 3
		x, y = adjustWindowPosition(x, y)
		u.window.SetPos(x, y)
		return nil
	}); err != nil {
		return err
	}
	return u.loop(g)
}

func (u *userInterface) glfwSize() (int, int) {
	return int(float64(u.width) * u.scale * glfwScale()), int(float64(u.height) * u.scale * glfwScale())
}

func (u *userInterface) actualScreenScale() float64 {
	if u.deviceScale == 0 {
		u.deviceScale = deviceScale()
	}
	return u.scale * u.deviceScale
}

func (u *userInterface) pollEvents() {
	glfw.PollEvents()
	currentInput.update(u.window, u.scale*glfwScale())
}

func (u *userInterface) update(g GraphicsContext) error {
	shouldClose := false
	_ = u.runOnMainThread(func() error {
		shouldClose = u.window.ShouldClose()
		return nil
	})
	if shouldClose {
		return &RegularTermination{}
	}

	actualScale := 0.0
	_ = u.runOnMainThread(func() error {
		if !u.sizeChanged {
			return nil
		}
		u.sizeChanged = false
		actualScale = u.actualScreenScale()
		return nil
	})
	if 0 < actualScale {
		g.SetSize(u.width, u.height, actualScale)
	}

	_ = u.runOnMainThread(func() error {
		u.pollEvents()
		for u.window.GetAttrib(glfw.Focused) == 0 {
			// Wait for an arbitrary period to avoid busy loop.
			time.Sleep(time.Second / 60)
			u.pollEvents()
			if u.window.ShouldClose() {
				return nil
			}
		}
		return nil
	})
	if err := g.Update(); err != nil {
		return err
	}
	return nil
}

func (u *userInterface) loop(g GraphicsContext) error {
	defer func() {
		_ = u.runOnMainThread(func() error {
			glfw.Terminate()
			return nil
		})
	}()
	for {
		if err := u.update(g); err != nil {
			return err
		}
		// The bound framebuffer must be the default one (0) before swapping buffers.
		if err := opengl.GetContext().BindScreenFramebuffer(); err != nil {
			return err
		}
		_ = u.runOnMainThread(func() error {
			u.swapBuffers()
			return nil
		})
	}
}

func (u *userInterface) swapBuffers() {
	u.window.SwapBuffers()
}

func (u *userInterface) setScreenSize(width, height int, scale float64) bool {
	if u.width == width && u.height == height && u.scale == scale {
		return false
	}

	origScale := u.scale
	u.scale = scale

	// On Windows, giving a too small width doesn't call a callback (#165).
	// To prevent hanging up, return asap if the width is too small.
	// 252 is an arbitrary number and I guess this is small enough.
	// TODO: The same check should be in ui_js.go
	const minWindowWidth = 252
	if int(float64(width)*u.actualScreenScale()) < minWindowWidth {
		u.scale = origScale
		return false
	}
	u.width = width
	u.height = height

	// To make sure the current existing framebuffers are rendered,
	// swap buffers here before SetSize is called.
	u.swapBuffers()

	ch := make(chan struct{})
	window := u.window
	window.SetFramebufferSizeCallback(func(_ *glfw.Window, width, height int) {
		window.SetFramebufferSizeCallback(nil)
		close(ch)
	})
	w, h := u.glfwSize()
	window.SetSize(w, h)

event:
	for {
		glfw.PollEvents()
		select {
		case <-ch:
			break event
		default:
		}
	}
	u.sizeChanged = true
	return true
}
<commit_msg>ui: Avoid recalc the scale factor<commit_after>// Copyright 2015 Hajime Hoshi
//
// 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.

// +build darwin freebsd linux windows
// +build !js
// +build !android
// +build !ios

package ui

import (
	"errors"
	"runtime"
	"sync"
	"time"

	"github.com/go-gl/glfw/v3.2/glfw"
	"github.com/hajimehoshi/ebiten/internal/opengl"
)

type userInterface struct {
	window      *glfw.Window
	width       int
	height      int
	scale       float64
	deviceScale float64
	glfwScale   float64
	funcs       chan func()
	running     bool
	sizeChanged bool
	m           sync.Mutex
}

var currentUI *userInterface

func init() {
	if err := initialize(); err != nil {
		panic(err)
	}
}

func initialize() error {
	runtime.LockOSThread()

	if err := glfw.Init(); err != nil {
		return err
	}
	glfw.WindowHint(glfw.Visible, glfw.False)
	glfw.WindowHint(glfw.Resizable, glfw.False)
	glfw.WindowHint(glfw.ContextVersionMajor, 2)
	glfw.WindowHint(glfw.ContextVersionMinor, 1)

	// As start, create an window with temporary size to create OpenGL context thread.
	window, err := glfw.CreateWindow(16, 16, "", nil, nil)
	if err != nil {
		return err
	}
	hideConsoleWindowOnWindows()
	u := &userInterface{
		window:      window,
		funcs:       make(chan func()),
		sizeChanged: true,
	}
	u.window.MakeContextCurrent()
	glfw.SwapInterval(1)
	currentUI = u
	return nil
}

func RunMainThreadLoop(ch <-chan error) error {
	// TODO: Check this is done on the main thread.
	currentUI.setRunning(true)
	defer func() {
		currentUI.setRunning(false)
	}()
	for {
		select {
		case f := <-currentUI.funcs:
			f()
		case err := <-ch:
			// ch returns a value not only when an error occur but also it is closed.
			return err
		}
	}
}

func (u *userInterface) isRunning() bool {
	u.m.Lock()
	defer u.m.Unlock()
	return u.running
}

func (u *userInterface) setRunning(running bool) {
	u.m.Lock()
	defer u.m.Unlock()
	u.running = running
}

func (u *userInterface) runOnMainThread(f func() error) error {
	if u.funcs == nil {
		// already closed
		return nil
	}
	ch := make(chan struct{})
	var err error
	u.funcs <- func() {
		err = f()
		close(ch)
	}
	<-ch
	return err
}

func SetScreenSize(width, height int) bool {
	u := currentUI
	if !u.isRunning() {
		panic("ui: Run is not called yet")
	}
	r := false
	_ = u.runOnMainThread(func() error {
		u.setScreenSize(width, height, u.scale)
		return nil
	})
	return r
}

func SetScreenScale(scale float64) bool {
	u := currentUI
	if !u.isRunning() {
		panic("ui: Run is not called yet")
	}
	r := false
	_ = u.runOnMainThread(func() error {
		u.setScreenSize(u.width, u.height, scale)
		return nil
	})
	return r
}

func ScreenScale() float64 {
	u := currentUI
	if !u.isRunning() {
		return 0
	}
	s := 0.0
	_ = u.runOnMainThread(func() error {
		s = u.scale
		return nil
	})
	return s
}

func SetCursorVisibility(visible bool) {
	// This can be called before Run: change the state asyncly.
	go func() {
		_ = currentUI.runOnMainThread(func() error {
			c := glfw.CursorNormal
			if !visible {
				c = glfw.CursorHidden
			}
			currentUI.window.SetInputMode(glfw.CursorMode, c)
			return nil
		})
	}()
}

func Run(width, height int, scale float64, title string, g GraphicsContext) error {
	u := currentUI
	// GLContext must be created before setting the screen size, which requires
	// swapping buffers.
	opengl.Init(currentUI.runOnMainThread)
	if err := u.runOnMainThread(func() error {
		m := glfw.GetPrimaryMonitor()
		v := m.GetVideoMode()
		if !u.setScreenSize(width, height, scale) {
			return errors.New("ui: Fail to set the screen size")
		}
		u.window.SetTitle(title)
		u.window.Show()

		w, h := u.glfwSize()
		x := (v.Width - w) / 2
		y := (v.Height - h) / 3
		x, y = adjustWindowPosition(x, y)
		u.window.SetPos(x, y)
		return nil
	}); err != nil {
		return err
	}
	return u.loop(g)
}

func (u *userInterface) glfwSize() (int, int) {
	if u.glfwScale == 0 {
		u.glfwScale = glfwScale()
	}
	return int(float64(u.width) * u.scale * u.glfwScale), int(float64(u.height) * u.scale * u.glfwScale)
}

func (u *userInterface) actualScreenScale() float64 {
	if u.deviceScale == 0 {
		u.deviceScale = deviceScale()
	}
	return u.scale * u.deviceScale
}

func (u *userInterface) pollEvents() {
	glfw.PollEvents()
	if u.glfwScale == 0 {
		u.glfwScale = glfwScale()
	}
	currentInput.update(u.window, u.scale*u.glfwScale)
}

func (u *userInterface) update(g GraphicsContext) error {
	shouldClose := false
	_ = u.runOnMainThread(func() error {
		shouldClose = u.window.ShouldClose()
		return nil
	})
	if shouldClose {
		return &RegularTermination{}
	}

	actualScale := 0.0
	_ = u.runOnMainThread(func() error {
		if !u.sizeChanged {
			return nil
		}
		u.sizeChanged = false
		actualScale = u.actualScreenScale()
		return nil
	})
	if 0 < actualScale {
		g.SetSize(u.width, u.height, actualScale)
	}

	_ = u.runOnMainThread(func() error {
		u.pollEvents()
		for u.window.GetAttrib(glfw.Focused) == 0 {
			// Wait for an arbitrary period to avoid busy loop.
			time.Sleep(time.Second / 60)
			u.pollEvents()
			if u.window.ShouldClose() {
				return nil
			}
		}
		return nil
	})
	if err := g.Update(); err != nil {
		return err
	}
	return nil
}

func (u *userInterface) loop(g GraphicsContext) error {
	defer func() {
		_ = u.runOnMainThread(func() error {
			glfw.Terminate()
			return nil
		})
	}()
	for {
		if err := u.update(g); err != nil {
			return err
		}
		// The bound framebuffer must be the default one (0) before swapping buffers.
		if err := opengl.GetContext().BindScreenFramebuffer(); err != nil {
			return err
		}
		_ = u.runOnMainThread(func() error {
			u.swapBuffers()
			return nil
		})
	}
}

func (u *userInterface) swapBuffers() {
	u.window.SwapBuffers()
}

func (u *userInterface) setScreenSize(width, height int, scale float64) bool {
	if u.width == width && u.height == height && u.scale == scale {
		return false
	}

	origScale := u.scale
	u.scale = scale

	// On Windows, giving a too small width doesn't call a callback (#165).
	// To prevent hanging up, return asap if the width is too small.
	// 252 is an arbitrary number and I guess this is small enough.
	// TODO: The same check should be in ui_js.go
	const minWindowWidth = 252
	if int(float64(width)*u.actualScreenScale()) < minWindowWidth {
		u.scale = origScale
		return false
	}
	u.width = width
	u.height = height

	// To make sure the current existing framebuffers are rendered,
	// swap buffers here before SetSize is called.
	u.swapBuffers()

	ch := make(chan struct{})
	window := u.window
	window.SetFramebufferSizeCallback(func(_ *glfw.Window, width, height int) {
		window.SetFramebufferSizeCallback(nil)
		close(ch)
	})
	w, h := u.glfwSize()
	window.SetSize(w, h)

event:
	for {
		glfw.PollEvents()
		select {
		case <-ch:
			break event
		default:
		}
	}
	u.sizeChanged = true
	return true
}
<|endoftext|>


<commit_before>package gettext

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
)

const (
	DEFAULT_LANGUAGE = "en"
)

type Collection struct {
	catalogs        map[string]*Catalog
	defaultLanguage string
}

func NewCollection() *Collection {
	return &Collection{
		catalogs:        map[string]*Catalog{},
		defaultLanguage: "en",
	}
}

func (c *Collection) LoadDirectory(path string) error {
	directoryPath := fmt.Sprintf("%s%s*.mo", path, string(os.PathSeparator))
	files, err := filepath.Glob(directoryPath)
	if err != nil {
		return err
	}

	c.catalogs = make(map[string]*Catalog, 0)

	for _, fileName := range files {
		language := strings.ToLower(fmt.Sprintf(strings.TrimSuffix(fileName, filepath.Ext(fileName))))

		filePath := fmt.Sprintf("%s%s%s", path, string(os.PathSeparator), fileName)
		fileBytes, err := ioutil.ReadFile(filePath)
		if err != nil {
			return err
		}

		catalog := NewCatalog()
		if err := catalog.ReadMo(bytes.NewReader(fileBytes)); err != nil {
			return err
		}

		c.catalogs[language] = catalog
	}

	return nil
}

func (c *Collection) SetDefaultLanguage(langCode string) {
	c.defaultLanguage = langCode
}

func (c *Collection) Get(langCode string) *Catalog {
	langCode = strings.ToLower(langCode)
	catalog, ok := c.catalogs[langCode]
	if ok {
		return catalog
	}

	catalog, ok = c.catalogs[strings.Split(langCode, "-")[0]]
	if ok {
		return catalog
	}

	catalog, ok = c.catalogs[c.defaultLanguage]
	if ok {
		return catalog
	}

	return NewCatalog()
}
<commit_msg>Fix file retrieve from directories<commit_after>package gettext

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
)

const (
	DEFAULT_LANGUAGE = "en"
)

type Collection struct {
	catalogs        map[string]*Catalog
	defaultLanguage string
}

func NewCollection() *Collection {
	return &Collection{
		catalogs:        map[string]*Catalog{},
		defaultLanguage: "en",
	}
}

func (c *Collection) LoadDirectory(path string) error {
	directoryPath := fmt.Sprintf("%s%s*.mo", path, string(os.PathSeparator))
	files, err := filepath.Glob(directoryPath)
	if err != nil {
		return err
	}

	c.catalogs = make(map[string]*Catalog, 0)

	for _, fileName := range files {
		language := strings.ToLower(fmt.Sprintf(strings.TrimSuffix(filepath.Base(fileName), filepath.Ext(fileName))))

		filePath := fmt.Sprintf("%s", fileName)
		fmt.Println(language, "->", filePath)
		fileBytes, err := ioutil.ReadFile(filePath)
		if err != nil {
			return err
		}

		catalog := NewCatalog()
		if err := catalog.ReadMo(bytes.NewReader(fileBytes)); err != nil {
			return err
		}

		c.catalogs[language] = catalog
	}

	return nil
}

func (c *Collection) SetDefaultLanguage(langCode string) {
	c.defaultLanguage = langCode
}

func (c *Collection) Get(langCode string) *Catalog {
	langCode = strings.ToLower(langCode)
	catalog, ok := c.catalogs[langCode]
	if ok {
		return catalog
	}

	catalog, ok = c.catalogs[strings.Split(langCode, "-")[0]]
	if ok {
		return catalog
	}

	catalog, ok = c.catalogs[c.defaultLanguage]
	if ok {
		return catalog
	}

	return NewCatalog()
}
<|endoftext|>


<commit_before>package imagectl

import (
	"errors"
	"io/ioutil"
	"os"
	"strings"
	"github.com/coreos/go-systemd/unit"
	systemd "github.com/coreos/go-systemd/dbus"
)

func setupMount(sd *systemd.Conn, what, where, fstype, options string) error {
	// mount -t $type -o$options $what $where

	sdname := unit.UnitNamePathEscape(where)
	sdfile := "[Mount]\nWhat=" + what + "\nWhere=" + where + "\nType=" + fstype + "\nOptions=" + options + "\n"
	sdauto := "[Automount]\nWhere=" + where + "\n\n[Install]\nWantedBy=local-fs.target\n"

	if err := ioutil.WriteFile("/etc/systemd/system/" + sdname + ".mount", []byte(sdfile), 0644); err != nil {
		return err
	}
	if err := ioutil.WriteFile("/etc/systemd/system/" + sdname + ".automount", []byte(sdauto), 0644); err != nil {
		return err
	}

	if err := sd.Reload(); err != nil {
		return err
	}

	possible, _, err := sd.EnableUnitFiles([]string{sdname + ".automount"}, false, false)
	if !possible {
		return errors.New("Internal error: Auto-generated " + sdname + ".automount does not have an [Install] section.")
	}
	if err != nil {
		return err
	}

	_, err = sd.StartUnit(sdname + ".automount", "replace", nil)
	if err != nil {
		return err
	}

	return nil
}

func destroyMount(sd *systemd.Conn, where string) error {
	sdname := unit.UnitNamePathEscape(where)

	_, err := sd.StopUnit(sdname + ".automount", "replace", nil)
	if err != nil {
		return err
	}

	_, err = sd.DisableUnitFiles([]string{sdname + ".automount"}, false)
	if err != nil {
		return err
	}

	if err := os.Remove("/etc/systemd/system/" + sdname + ".mount"); err != nil {
		return err
	}
	if err := os.Remove("/etc/systemd/system/" + sdname + ".automount"); err != nil {
		return err
	}

	if err := sd.Reload(); err != nil {
		return err
	}

	return nil
}

func setupMountOverlay(sd *systemd.Conn, whatRo []string, whatRW, where string) error {
	if err := os.MkdirAll("/var/lib/image-layers/.work", 0700); err != nil {
		return err
	}

	if whatRW == "" {
		switch len(whatRo) {
			case 0:
				return setupMount(sd, "tmpfs", where, "tmpfs", "ro")
			case 1:
				return setupMount(sd, whatRo[0], where, "none", "bind,ro") // Note: ro probably doesn't work
			default:
				return setupMount(sd, "overlay", where, "overlay", "lowerdir=" + strings.Join(whatRo, ":"))
		}
	} else {
		switch len(whatRo) {
			case 0:
				return setupMount(sd, whatRW, where, "none", "bind")
			default:
				return setupMount(sd, "overlay", where, "overlay", "lowerdir=" + strings.Join(whatRo, ":") + ",upperdir=" + whatRW + ",workdir=/var/lib/image-layers/.work")
		}
	}
}

func doUnitOperation(op func(name, mode string, ch chan<- string) (int, error), name, mode string) error {
	done := make(chan string)
	_, err := op(name, mode, done)
	if err != nil {
		return err
	}
	result := <-done
	if result != "done" {
		return errors.New(result)
	}

	return nil
}

func mount(sd *systemd.Conn, where string) error {
	sdname := unit.UnitNamePathEscape(where)
	return doUnitOperation(sd.StartUnit, sdname + ".mount", "replace")
}

func remount(sd *systemd.Conn, where string) error {
	sdname := unit.UnitNamePathEscape(where)
	return doUnitOperation(sd.RestartUnit, sdname + ".mount", "replace")
}

func umount(sd *systemd.Conn, where string) error {
	sdname := unit.UnitNamePathEscape(where)
	return doUnitOperation(sd.StopUnit, sdname + ".mount", "replace")
}
<commit_msg>imagectl: Fix the order of lower dirs.<commit_after>package imagectl

import (
	"errors"
	"io/ioutil"
	"os"
	"strings"
	"github.com/coreos/go-systemd/unit"
	systemd "github.com/coreos/go-systemd/dbus"
)

func setupMount(sd *systemd.Conn, what, where, fstype, options string) error {
	// mount -t $type -o$options $what $where

	sdname := unit.UnitNamePathEscape(where)
	sdfile := "[Mount]\nWhat=" + what + "\nWhere=" + where + "\nType=" + fstype + "\nOptions=" + options + "\n"
	sdauto := "[Automount]\nWhere=" + where + "\n\n[Install]\nWantedBy=local-fs.target\n"

	if err := ioutil.WriteFile("/etc/systemd/system/" + sdname + ".mount", []byte(sdfile), 0644); err != nil {
		return err
	}
	if err := ioutil.WriteFile("/etc/systemd/system/" + sdname + ".automount", []byte(sdauto), 0644); err != nil {
		return err
	}

	if err := sd.Reload(); err != nil {
		return err
	}

	possible, _, err := sd.EnableUnitFiles([]string{sdname + ".automount"}, false, false)
	if !possible {
		return errors.New("Internal error: Auto-generated " + sdname + ".automount does not have an [Install] section.")
	}
	if err != nil {
		return err
	}

	_, err = sd.StartUnit(sdname + ".automount", "replace", nil)
	if err != nil {
		return err
	}

	return nil
}

func destroyMount(sd *systemd.Conn, where string) error {
	sdname := unit.UnitNamePathEscape(where)

	_, err := sd.StopUnit(sdname + ".automount", "replace", nil)
	if err != nil {
		return err
	}

	_, err = sd.DisableUnitFiles([]string{sdname + ".automount"}, false)
	if err != nil {
		return err
	}

	if err := os.Remove("/etc/systemd/system/" + sdname + ".mount"); err != nil {
		return err
	}
	if err := os.Remove("/etc/systemd/system/" + sdname + ".automount"); err != nil {
		return err
	}

	if err := sd.Reload(); err != nil {
		return err
	}

	return nil
}

func setupMountOverlay(sd *systemd.Conn, whatRo []string, whatRW, where string) error {
	if err := os.MkdirAll("/var/lib/image-layers/.work", 0700); err != nil {
		return err
	}

	// I guess overlayfs was designed in Australia.
	whatRoReversed := make([]string, 0, len(whatRo))
	for i := len(whatRo)-1; i >= 0; i-- {
		whatRoReversed = append(whatRoReversed, whatRo[i])
	}
	whatRo = whatRoReversed

	if whatRW == "" {
		switch len(whatRo) {
			case 0:
				return setupMount(sd, "tmpfs", where, "tmpfs", "ro")
			case 1:
				return setupMount(sd, whatRo[0], where, "none", "bind,ro") // Note: ro probably doesn't work
			default:
				return setupMount(sd, "overlay", where, "overlay", "lowerdir=" + strings.Join(whatRo, ":"))
		}
	} else {
		switch len(whatRo) {
			case 0:
				return setupMount(sd, whatRW, where, "none", "bind")
			default:
				return setupMount(sd, "overlay", where, "overlay", "lowerdir=" + strings.Join(whatRo, ":") + ",upperdir=" + whatRW + ",workdir=/var/lib/image-layers/.work")
		}
	}
}

func doUnitOperation(op func(name, mode string, ch chan<- string) (int, error), name, mode string) error {
	done := make(chan string)
	_, err := op(name, mode, done)
	if err != nil {
		return err
	}
	result := <-done
	if result != "done" {
		return errors.New(result)
	}

	return nil
}

func mount(sd *systemd.Conn, where string) error {
	sdname := unit.UnitNamePathEscape(where)
	return doUnitOperation(sd.StartUnit, sdname + ".mount", "replace")
}

func remount(sd *systemd.Conn, where string) error {
	sdname := unit.UnitNamePathEscape(where)
	return doUnitOperation(sd.RestartUnit, sdname + ".mount", "replace")
}

func umount(sd *systemd.Conn, where string) error {
	sdname := unit.UnitNamePathEscape(where)
	return doUnitOperation(sd.StopUnit, sdname + ".mount", "replace")
}
<|endoftext|>