<commit_before>// Copyright 2015 Afshin Darian. All rights reserved.
// Use of this source code is governed by The MIT License
// that can be found in the LICENSE file.

/*
Package wares_test contains tests and examples for package wares. The goal is
100% code coverage.
*/
package wares_test

import (
	"bytes"
	"encoding/json"
	"fmt"
	"github.com/ursiform/forest"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"testing"
)

const (
	sessionID     = "SOME-SESSION-ID"
	sessionUserID = "SOME-USER-ID"
)

type requested struct {
	body   []byte
	method string
	path   string
}

type wanted struct {
	code    int
	success bool
	data    interface{}
}

func makeRequest(t *testing.T, app *forest.App, params *requested, want *wanted) *http.Response {
	var request *http.Request
	method := params.method
	path := params.path
	body := params.body
	if body != nil {
		request, _ = http.NewRequest(method, path, bytes.NewBuffer(body))
	} else {
		request, _ = http.NewRequest(method, path, nil)
	}
	response := httptest.NewRecorder()
	app.Router.ServeHTTP(response, request)
	responseData := new(forest.Response)
	responseBody, err := ioutil.ReadAll(response.Body)
	if err != nil {
		t.Error(err)
		return nil
	}
	if err := json.Unmarshal(responseBody, responseData); err != nil {
		t.Errorf("unmarshal error: %v when attempting to read: %s", err, string(responseBody))
		return nil
	}
	if response.Code != want.code {
		t.Errorf("%s %s want: %d (%s) got: %d %s, body: %s", method, path,
			want.code, http.StatusText(want.code), response.Code, http.StatusText(response.Code), string(responseBody))
		return nil
	}
	if responseData.Success != want.success {
		t.Errorf("%s %s should return success: %t", method, path, want.success)
		return nil
	}
	return &http.Response{Header: response.Header()}
}

func TestAuthenticateFailure(t *testing.T) {
	debug := false
	method := "GET"
	root := "/foo"
	path := "/foo/authenticate/failure"
	app := forest.New(debug)
	app.RegisterRoute(root, newRouter(app))
	params := &requested{method: method, path: path}
	want := &wanted{code: http.StatusUnauthorized, success: false}
	makeRequest(t, app, params, want)
}

func TestAuthenticateSuccess(t *testing.T) {
	debug := false
	method := "GET"
	root := "/foo"
	path := "/foo/authenticate/success"
	app := forest.New(debug)
	app.RegisterRoute(root, newRouter(app))
	params := &requested{method: method, path: path}
	want := &wanted{code: http.StatusOK, success: true}
	makeRequest(t, app, params, want)
}

func TestBadRequest(t *testing.T) {
	debug := false
	method := "GET"
	root := "/foo"
	path := "/foo/bad-request"
	app := forest.New(debug)
	app.RegisterRoute(root, newRouter(app))
	params := &requested{method: method, path: path}
	want := &wanted{code: http.StatusBadRequest, success: false}
	makeRequest(t, app, params, want)
}

func TestBodyParserFailureNoInit(t *testing.T) {
	debug := false
	method := "POST"
	root := "/foo"
	path := "/foo/body-parser/failure/no-init"
	body := []byte("{\"foo\": \"bar\"}")
	app := forest.New(debug)
	app.RegisterRoute(root, newRouter(app))
	params := &requested{body: body, method: method, path: path}
	want := &wanted{code: http.StatusInternalServerError, success: false}
	makeRequest(t, app, params, want)
}

func TestBodyParserSuccess(t *testing.T) {
	debug := false
	method := "POST"
	root := "/foo"
	path := "/foo/body-parser/success"
	body := []byte("{\"foo\": \"bar\"}")
	app := forest.New(debug)
	app.RegisterRoute(root, newRouter(app))
	params := &requested{body: body, method: method, path: path}
	want := &wanted{code: http.StatusOK, success: true}
	makeRequest(t, app, params, want)
}

func TestConflict(t *testing.T) {
	debug := false
	method := "GET"
	root := "/foo"
	path := "/foo/conflict"
	app := forest.New(debug)
	app.RegisterRoute(root, newRouter(app))
	params := &requested{method: method, path: path}
	want := &wanted{code: http.StatusConflict, success: false}
	makeRequest(t, app, params, want)
}

func TestCSRFFailureBodyNil(t *testing.T) {
	debug := false
	method := "GET"
	root := "/foo"
	path := "/foo/csrf"
	app := forest.New(debug)
	app.RegisterRoute(root, newRouter(app))
	params := &requested{method: method, path: path}
	want := &wanted{code: http.StatusBadRequest, success: false}
	makeRequest(t, app, params, want)
}

func TestCSRFFailureBodyParse(t *testing.T) {
	debug := false
	method := "GET"
	root := "/foo"
	path := "/foo/csrf"
	body := []byte("{BAD JSON}")
	app := forest.New(debug)
	app.RegisterRoute(root, newRouter(app))
	params := &requested{body: body, method: method, path: path}
	want := &wanted{code: http.StatusBadRequest, success: false}
	makeRequest(t, app, params, want)
}

func TestCSRFFailureBodyTooShort(t *testing.T) {
	debug := false
	method := "GET"
	root := "/foo"
	path := "/foo/csrf"
	body := []byte("{")
	app := forest.New(debug)
	app.RegisterRoute(root, newRouter(app))
	params := &requested{body: body, method: method, path: path}
	want := &wanted{code: http.StatusBadRequest, success: false}
	makeRequest(t, app, params, want)
}

func TestCSRFFailureWrongSessionID(t *testing.T) {
	debug := false
	method := "GET"
	root := "/foo"
	path := "/foo/csrf"
	body := []byte(fmt.Sprintf("{\"sessionid\": \"WRONG-SESSION-ID\"}"))
	app := forest.New(debug)
	app.RegisterRoute(root, newRouter(app))
	params := &requested{body: body, method: method, path: path}
	want := &wanted{code: http.StatusBadRequest, success: false}
	makeRequest(t, app, params, want)
}

func TestCSRFSuccess(t *testing.T) {
	debug := false
	method := "GET"
	root := "/foo"
	path := "/foo/csrf"
	body := []byte(fmt.Sprintf("{\"sessionid\": \"%s\"}", sessionID))
	app := forest.New(debug)
	app.RegisterRoute(root, newRouter(app))
	params := &requested{body: body, method: method, path: path}
	want := &wanted{code: http.StatusOK, success: true}
	makeRequest(t, app, params, want)
}

func TestMethodNotAllowed(t *testing.T) {
	debug := false
	method := "OPTIONS"
	root := "/foo"
	path := "/foo"
	app := forest.New(debug)
	app.RegisterRoute(root, newRouter(app))
	params := &requested{method: method, path: path}
	want := &wanted{code: http.StatusMethodNotAllowed, success: false}
	makeRequest(t, app, params, want)
}

func TestNotFound(t *testing.T) {
	debug := false
	method := "GET"
	root := "/foo"
	path := "/foo/not-found"
	app := forest.New(debug)
	app.RegisterRoute(root, newRouter(app))
	params := &requested{method: method, path: path}
	want := &wanted{code: http.StatusNotFound, success: false}
	makeRequest(t, app, params, want)
}

func TestServerError(t *testing.T) {
	debug := false
	method := "GET"
	root := "/foo"
	path := "/foo/server-error"
	app := forest.New(debug)
	app.RegisterRoute(root, newRouter(app))
	params := &requested{method: method, path: path}
	want := &wanted{code: http.StatusInternalServerError, success: false}
	makeRequest(t, app, params, want)
}

func TestUnauthorized(t *testing.T) {
	debug := false
	method := "GET"
	root := "/foo"
	path := "/foo/unauthorized"
	app := forest.New(debug)
	app.RegisterRoute(root, newRouter(app))
	params := &requested{method: method, path: path}
	want := &wanted{code: http.StatusUnauthorized, success: false}
	makeRequest(t, app, params, want)
}
<commit_msg>moving Populater to forest-wares, uninitialized BodyParser should be 500 error, adding some BodyParser tests<commit_after>// Copyright 2015 Afshin Darian. All rights reserved.
// Use of this source code is governed by The MIT License
// that can be found in the LICENSE file.

/*
Package wares_test contains tests and examples for package wares. The goal is
100% code coverage.
*/
package wares_test

import (
	"bytes"
	"encoding/json"
	"fmt"
	"github.com/ursiform/forest"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"testing"
)

const (
	sessionID     = "SOME-SESSION-ID"
	sessionUserID = "SOME-USER-ID"
)

type requested struct {
	body   []byte
	method string
	path   string
}

type wanted struct {
	code    int
	success bool
	data    interface{}
}

func makeRequest(t *testing.T, app *forest.App, params *requested, want *wanted) *http.Response {
	var request *http.Request
	method := params.method
	path := params.path
	body := params.body
	if body != nil {
		request, _ = http.NewRequest(method, path, bytes.NewBuffer(body))
	} else {
		request, _ = http.NewRequest(method, path, nil)
	}
	response := httptest.NewRecorder()
	app.Router.ServeHTTP(response, request)
	responseData := new(forest.Response)
	responseBody, err := ioutil.ReadAll(response.Body)
	if err != nil {
		t.Error(err)
		return nil
	}
	if err := json.Unmarshal(responseBody, responseData); err != nil {
		t.Errorf("unmarshal error: %v when attempting to read: %s", err, string(responseBody))
		return nil
	}
	if response.Code != want.code {
		t.Errorf("%s %s want: %d (%s) got: %d %s, body: %s", method, path,
			want.code, http.StatusText(want.code), response.Code, http.StatusText(response.Code), string(responseBody))
		return nil
	}
	if responseData.Success != want.success {
		t.Errorf("%s %s should return success: %t", method, path, want.success)
		return nil
	}
	return &http.Response{Header: response.Header()}
}

func TestAuthenticateFailure(t *testing.T) {
	debug := false
	method := "GET"
	root := "/foo"
	path := "/foo/authenticate/failure"
	app := forest.New(debug)
	app.RegisterRoute(root, newRouter(app))
	params := &requested{method: method, path: path}
	want := &wanted{code: http.StatusUnauthorized, success: false}
	makeRequest(t, app, params, want)
}

func TestAuthenticateSuccess(t *testing.T) {
	debug := false
	method := "GET"
	root := "/foo"
	path := "/foo/authenticate/success"
	app := forest.New(debug)
	app.RegisterRoute(root, newRouter(app))
	params := &requested{method: method, path: path}
	want := &wanted{code: http.StatusOK, success: true}
	makeRequest(t, app, params, want)
}

func TestBadRequest(t *testing.T) {
	debug := false
	method := "GET"
	root := "/foo"
	path := "/foo/bad-request"
	app := forest.New(debug)
	app.RegisterRoute(root, newRouter(app))
	params := &requested{method: method, path: path}
	want := &wanted{code: http.StatusBadRequest, success: false}
	makeRequest(t, app, params, want)
}

func TestBodyParserFailureBodyNil(t *testing.T) {
	debug := false
	method := "POST"
	root := "/foo"
	path := "/foo/body-parser/success"
	app := forest.New(debug)
	app.RegisterRoute(root, newRouter(app))
	params := &requested{method: method, path: path}
	want := &wanted{code: http.StatusBadRequest, success: false}
	makeRequest(t, app, params, want)
}

func TestBodyParserFailureNoInit(t *testing.T) {
	debug := false
	method := "POST"
	root := "/foo"
	path := "/foo/body-parser/failure/no-init"
	body := []byte("{\"foo\": \"bar\"}")
	app := forest.New(debug)
	app.RegisterRoute(root, newRouter(app))
	params := &requested{body: body, method: method, path: path}
	want := &wanted{code: http.StatusInternalServerError, success: false}
	makeRequest(t, app, params, want)
}

func TestBodyParserSuccess(t *testing.T) {
	debug := false
	method := "POST"
	root := "/foo"
	path := "/foo/body-parser/success"
	body := []byte("{\"foo\": \"bar\"}")
	app := forest.New(debug)
	app.RegisterRoute(root, newRouter(app))
	params := &requested{body: body, method: method, path: path}
	want := &wanted{code: http.StatusOK, success: true}
	makeRequest(t, app, params, want)
}

func TestConflict(t *testing.T) {
	debug := false
	method := "GET"
	root := "/foo"
	path := "/foo/conflict"
	app := forest.New(debug)
	app.RegisterRoute(root, newRouter(app))
	params := &requested{method: method, path: path}
	want := &wanted{code: http.StatusConflict, success: false}
	makeRequest(t, app, params, want)
}

func TestCSRFFailureBodyNil(t *testing.T) {
	debug := false
	method := "GET"
	root := "/foo"
	path := "/foo/csrf"
	app := forest.New(debug)
	app.RegisterRoute(root, newRouter(app))
	params := &requested{method: method, path: path}
	want := &wanted{code: http.StatusBadRequest, success: false}
	makeRequest(t, app, params, want)
}

func TestCSRFFailureBodyParse(t *testing.T) {
	debug := false
	method := "GET"
	root := "/foo"
	path := "/foo/csrf"
	body := []byte("{BAD JSON}")
	app := forest.New(debug)
	app.RegisterRoute(root, newRouter(app))
	params := &requested{body: body, method: method, path: path}
	want := &wanted{code: http.StatusBadRequest, success: false}
	makeRequest(t, app, params, want)
}

func TestCSRFFailureBodyTooShort(t *testing.T) {
	debug := false
	method := "GET"
	root := "/foo"
	path := "/foo/csrf"
	body := []byte("{")
	app := forest.New(debug)
	app.RegisterRoute(root, newRouter(app))
	params := &requested{body: body, method: method, path: path}
	want := &wanted{code: http.StatusBadRequest, success: false}
	makeRequest(t, app, params, want)
}

func TestCSRFFailureWrongSessionID(t *testing.T) {
	debug := false
	method := "GET"
	root := "/foo"
	path := "/foo/csrf"
	body := []byte(fmt.Sprintf("{\"sessionid\": \"WRONG-SESSION-ID\"}"))
	app := forest.New(debug)
	app.RegisterRoute(root, newRouter(app))
	params := &requested{body: body, method: method, path: path}
	want := &wanted{code: http.StatusBadRequest, success: false}
	makeRequest(t, app, params, want)
}

func TestCSRFSuccess(t *testing.T) {
	debug := false
	method := "GET"
	root := "/foo"
	path := "/foo/csrf"
	body := []byte(fmt.Sprintf("{\"sessionid\": \"%s\"}", sessionID))
	app := forest.New(debug)
	app.RegisterRoute(root, newRouter(app))
	params := &requested{body: body, method: method, path: path}
	want := &wanted{code: http.StatusOK, success: true}
	makeRequest(t, app, params, want)
}

func TestMethodNotAllowed(t *testing.T) {
	debug := false
	method := "OPTIONS"
	root := "/foo"
	path := "/foo"
	app := forest.New(debug)
	app.RegisterRoute(root, newRouter(app))
	params := &requested{method: method, path: path}
	want := &wanted{code: http.StatusMethodNotAllowed, success: false}
	makeRequest(t, app, params, want)
}

func TestNotFound(t *testing.T) {
	debug := false
	method := "GET"
	root := "/foo"
	path := "/foo/not-found"
	app := forest.New(debug)
	app.RegisterRoute(root, newRouter(app))
	params := &requested{method: method, path: path}
	want := &wanted{code: http.StatusNotFound, success: false}
	makeRequest(t, app, params, want)
}

func TestServerError(t *testing.T) {
	debug := false
	method := "GET"
	root := "/foo"
	path := "/foo/server-error"
	app := forest.New(debug)
	app.RegisterRoute(root, newRouter(app))
	params := &requested{method: method, path: path}
	want := &wanted{code: http.StatusInternalServerError, success: false}
	makeRequest(t, app, params, want)
}

func TestUnauthorized(t *testing.T) {
	debug := false
	method := "GET"
	root := "/foo"
	path := "/foo/unauthorized"
	app := forest.New(debug)
	app.RegisterRoute(root, newRouter(app))
	params := &requested{method: method, path: path}
	want := &wanted{code: http.StatusUnauthorized, success: false}
	makeRequest(t, app, params, want)
}
<|endoftext|>


<commit_before>/*
Copyright 2018 The Kubernetes Authors.

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 spyglass

import (
	"bytes"
	"context"
	"fmt"
	"testing"

	"k8s.io/test-infra/prow/kube"
)

// Tests getting handles to objects associated with the current Prow job
func TestFetchArtifacts_Prow(t *testing.T) {
	goodFetcher := NewPodLogArtifactFetcher(&fakePodLogJAgent{})
	maxSize := int64(500e6)
	testCases := []struct {
		name         string
		key          string
		artifact     string
		expectedPath string
		expectedLink string
		expected     []byte
		expectErr    bool
	}{
		{
			name:         "Fetch build-log.txt from valid src",
			key:          "BFG/435",
			artifact:     singleLogName,
			expectedLink: fmt.Sprintf("/log?container=%s&id=435&job=BFG", kube.TestContainerName),
			expected:     []byte("frobscottle"),
		},
		{
			name:      "Fetch log from empty src",
			key:       "",
			artifact:  singleLogName,
			expectErr: true,
		},
		{
			name:      "Fetch log from incomplete src",
			key:       "BFG",
			artifact:  singleLogName,
			expectErr: true,
		},
		{
			name:      "Fetch log with no artifact name",
			key:       "BFG/435",
			artifact:  "",
			expectErr: true,
		},
		{
			name:         "Fetch log with custom artifact name",
			key:          "BFG/435",
			artifact:     fmt.Sprintf("%s-%s", customContainerName, singleLogName),
			expectedLink: fmt.Sprintf("/log?container=%s&id=435&job=BFG", customContainerName),
			expected:     []byte("snozzcumber"),
		},
	}

	for _, tc := range testCases {
		artifact, err := goodFetcher.Artifact(context.Background(), tc.key, tc.artifact, maxSize)
		if err != nil && !tc.expectErr {
			t.Errorf("%s: failed unexpectedly for artifact %s, err: %v", tc.name, artifact.JobPath(), err)
			continue
		}
		if err == nil && tc.expectErr {
			t.Errorf("%s: expected error, got no error", tc.name)
			continue
		}

		if artifact != nil {
			if artifact.JobPath() != tc.artifact {
				t.Errorf("Unexpected job path, expected %s, got %q", artifact.JobPath(), tc.artifact)
			}
			link := artifact.CanonicalLink()
			if link != tc.expectedLink {
				t.Errorf("Unexpected link, expected %s, got %q", tc.expectedLink, link)
			}
			res, err := artifact.ReadAll()
			if err != nil {
				t.Fatalf("%s failed reading bytes of log. got err: %v", tc.name, err)
				continue
			}
			if !bytes.Equal(tc.expected, res) {
				t.Errorf("Unexpected result of reading pod logs, expected %q, got %q", tc.expected, res)
			}
		}

	}
}
<commit_msg>delete minor unreachable code caused by t.Fatalf<commit_after>/*
Copyright 2018 The Kubernetes Authors.

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 spyglass

import (
	"bytes"
	"context"
	"fmt"
	"testing"

	"k8s.io/test-infra/prow/kube"
)

// Tests getting handles to objects associated with the current Prow job
func TestFetchArtifacts_Prow(t *testing.T) {
	goodFetcher := NewPodLogArtifactFetcher(&fakePodLogJAgent{})
	maxSize := int64(500e6)
	testCases := []struct {
		name         string
		key          string
		artifact     string
		expectedPath string
		expectedLink string
		expected     []byte
		expectErr    bool
	}{
		{
			name:         "Fetch build-log.txt from valid src",
			key:          "BFG/435",
			artifact:     singleLogName,
			expectedLink: fmt.Sprintf("/log?container=%s&id=435&job=BFG", kube.TestContainerName),
			expected:     []byte("frobscottle"),
		},
		{
			name:      "Fetch log from empty src",
			key:       "",
			artifact:  singleLogName,
			expectErr: true,
		},
		{
			name:      "Fetch log from incomplete src",
			key:       "BFG",
			artifact:  singleLogName,
			expectErr: true,
		},
		{
			name:      "Fetch log with no artifact name",
			key:       "BFG/435",
			artifact:  "",
			expectErr: true,
		},
		{
			name:         "Fetch log with custom artifact name",
			key:          "BFG/435",
			artifact:     fmt.Sprintf("%s-%s", customContainerName, singleLogName),
			expectedLink: fmt.Sprintf("/log?container=%s&id=435&job=BFG", customContainerName),
			expected:     []byte("snozzcumber"),
		},
	}

	for _, tc := range testCases {
		artifact, err := goodFetcher.Artifact(context.Background(), tc.key, tc.artifact, maxSize)
		if err != nil && !tc.expectErr {
			t.Errorf("%s: failed unexpectedly for artifact %s, err: %v", tc.name, artifact.JobPath(), err)
			continue
		}
		if err == nil && tc.expectErr {
			t.Errorf("%s: expected error, got no error", tc.name)
			continue
		}

		if artifact != nil {
			if artifact.JobPath() != tc.artifact {
				t.Errorf("Unexpected job path, expected %s, got %q", artifact.JobPath(), tc.artifact)
			}
			link := artifact.CanonicalLink()
			if link != tc.expectedLink {
				t.Errorf("Unexpected link, expected %s, got %q", tc.expectedLink, link)
			}
			res, err := artifact.ReadAll()
			if err != nil {
				t.Fatalf("%s failed reading bytes of log. got err: %v", tc.name, err)
			}
			if !bytes.Equal(tc.expected, res) {
				t.Errorf("Unexpected result of reading pod logs, expected %q, got %q", tc.expected, res)
			}
		}

	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/HewlettPackard/oneview-golang/ov"
	// "github.com/HewlettPackard/oneview-golang/utils"
	"os"
)

func main() {
	var (
		clientOV    *ov.OVClient
		// eg_name     = "DemoEnclosureGroup"
		// new_eg_name = "RenamedEnclosureGroup"
		// script      = "#TEST COMMAND"
	)
	ovc := clientOV.NewOVClient(
		os.Getenv("ONEVIEW_OV_USER"),
		os.Getenv("ONEVIEW_OV_PASSWORD"),
		os.Getenv("ONEVIEW_OV_DOMAIN"),
		os.Getenv("ONEVIEW_OV_ENDPOINT"),
		false,
		800)

	interconnect_list, err := ovc.GetInterconnects("", "", "", "")
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println("#----------------Interconnect List---------------#")

		for i := 0; i < len(interconnect_list.Members); i++ {
			fmt.Println(interconnect_list.Members[i].Name)
		}
	}

	interconnect, err := ovc.GetInterconnectByName(interconnect_list.Members[0].Name)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println("#-------------Interconnect by name----------------#")
	fmt.Println(interconnect.Name)

	uri := interconnect.URI
	interconnect, err = ovc.GetInterconnectByUri(uri)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println("#----------------Interconnect by URI--------------#")
	fmt.Println(interconnect.Name)
}
<commit_msg>Interconnect edits.<commit_after>package main

import (
	"fmt"
	"github.com/HewlettPackard/oneview-golang/ov"
	"os"
)

func main() {
	var (
		clientOV    *ov.OVClient
	)
	ovc := clientOV.NewOVClient(
		os.Getenv("ONEVIEW_OV_USER"),
		os.Getenv("ONEVIEW_OV_PASSWORD"),
		os.Getenv("ONEVIEW_OV_DOMAIN"),
		os.Getenv("ONEVIEW_OV_ENDPOINT"),
		false,
		600)

	interconnect_list, err := ovc.GetInterconnects("", "", "", "")
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println("#----------------Interconnect List---------------#")

		for i := 0; i < len(interconnect_list.Members); i++ {
			fmt.Println(interconnect_list.Members[i].Name)
		}
	}

	interconnect, err := ovc.GetInterconnectByName(interconnect_list.Members[0].Name)
	if err != nil {
		fmt.Println(err)
	}
	} else {
		fmt.Println("#-------------Interconnect by Name----------------#")
		fmt.Println(interconnect.Name)

		uri := interconnect.URI
		interconnect, err = ovc.GetInterconnectByUri(uri)
		if err != nil {
			fmt.Println(err)
		} else {
			fmt.Println("#----------------Interconnect by URI--------------#")
			fmt.Println(interconnect.Name)
		}
	}
}
<|endoftext|>


<commit_before>/*************************************************************************
> File Name: server_test.go
> Author: Yang Zhiqin
> Mail:zhiqin.yang.f@gmail.com
> Created Time: Thu 31 Oct 2013 02:05:12 AM EDT
> Unit test for server
************************************************************************/

package db

import (
	"fmt"
	"testing"
)

func TestInsert(t *testing.T) {
	ser := &Server{"backend", "192.168.1.117", 3306, "admin", "admin", nil}
	db, _ := ser.GetDB()
	template := &SimpleDbTemplate{db}
	insert_sql := "insert into user(name, age, level) values(?,?,?)"
	id ,_:= template.Insert(insert_sql, "zhan san", 20, 100)
	fmt.Println(id)
}

func TestUpdate(t *testing.T) {
	ser := &Server{"backend", "192.168.1.117", 3306, "admin", "admin", nil}
	db, _ := ser.GetDB()
	template := &SimpleDbTemplate{db}
	update_sql := "update user set name = ? where id = ?"

	num,_ := template.Excute(update_sql, "wang wu", 1)

	if 1 != num {
		t.Error("fail")
	}

}

func TestTransaction(t *testing.T) {

	ser := &Server{"backend", "192.168.1.117", 3306, "admin", "admin", nil}
	db, _ := ser.GetDB()
	template := &SimpleDbTemplate{db}
	tx ,_:= template.Begin()
	insert_sql := "insert into user(name, age, level) values(?,?,?)"

	id ,_:= tx.Insert(insert_sql, "zhan sani xxxx", 20, 100)
	fmt.Println(id)
	id,_ = tx.Insert(insert_sql, "zhan sani xxxr3x", 20, 100)

	fmt.Println(id)
	id ,_= tx.Insert(insert_sql, "zhan sani xxx 5x", 20, 100)

	fmt.Println(id)
	tx.Commit()
}
<commit_msg>recommit<commit_after>/*************************************************************************
> File Name: server_test.go
> Author: Yang Zhiqin
> Mail:zhiqin.yang.f@gmail.com
> Created Time: Thu 31 Oct 2013 02:05:12 AM EDT
> Unit test for server
************************************************************************/

package db

import (
	"fmt"
    "testing"
    "database/sql"
)

func TestInsert(t *testing.T) {
	ser := &Server{"backend", "192.168.1.117", 3306, "admin", "admin", nil}
	db, _ := ser.GetDB()
	template := &SimpleDbTemplate{db}
	insert_sql := "insert into user(name, age, level) values(?,?,?)"
	id ,_:= template.Insert(insert_sql, "zhan san", 20, 100)
	fmt.Println(id)
}

func TestUpdate(t *testing.T) {
	ser := &Server{"backend", "192.168.1.117", 3306, "admin", "admin", nil}
	db, _ := ser.GetDB()
	template := &SimpleDbTemplate{db}
	update_sql := "update user set name = ? where id = ?"

	num,_ := template.Excute(update_sql, "wang wu", 1)

	if 1 != num {
		t.Error("fail")
	}

}

func TestTransaction(t *testing.T) {

	ser := &Server{"backend", "192.168.1.117", 3306, "admin", "admin", nil}
	db, _ := ser.GetDB()
	template := &SimpleDbTemplate{db}
	tx ,_:= template.Begin()
	insert_sql := "insert into user(name, age, level) values(?,?,?)"

	id ,_:= tx.Insert(insert_sql, "zhan sani xxxx", 20, 100)
	fmt.Println(id)
	id,_ = tx.Insert(insert_sql, "zhan sani xxxr3x", 20, 100)

	fmt.Println(id)

    id ,_= tx.Insert(insert_sql, "zhan sani xxx 5x", 20, 100)

	fmt.Println(id)
	tx.Commit()
}

func TestQuery(t *testing.T) {

	ser := &Server{"backend", "192.168.1.117", 3306, "admin", "admin", nil}
	db, _ := ser.GetDB()
	template := &SimpleDbTemplate{db}
	//tx ,_:= template.Begin()

    query_sql := "select name, age , level from user ";

    list ,err:= template.QueryForList(query_sql,rowMapper)

    if(nil != err ) {
        t.Error(err.Error())
    }

    for e := list.Front(); e != nil; e = e.Next() {
        fmt.Println(e.Value);

    }
}

type User struct {

    Name string
    Level int
    Age int
}

func  rowMapper( row * sql.Rows ) interface{} {

    var name string
    var level int
    var age int
    row.Scan(&name, &age, &level)

    return User{name, level, age}

}
<|endoftext|>


<commit_before>// +build testtools

package main

import (
	"bufio"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"strconv"
	"strings"
	"time"

	"github.com/github/git-lfs/api"
	"github.com/github/git-lfs/httputil"
	"github.com/github/git-lfs/progress"
	"github.com/github/git-lfs/tools"
)

// This test custom adapter just acts as a bridge for uploads/downloads
// in order to demonstrate & test the custom transfer adapter protocols
// All we actually do is relay the requests back to the normal storage URLs
// of our test server for simplicity, but this proves the principle
func main() {

	scanner := bufio.NewScanner(os.Stdin)
	writer := bufio.NewWriter(os.Stdout)
	errWriter := bufio.NewWriter(os.Stderr)

	for scanner.Scan() {
		line := scanner.Text()
		var req request
		if err := json.Unmarshal([]byte(line), &req); err != nil {
			writeToStderr(fmt.Sprintf("Unable to parse request: %v\n", line), errWriter)
			continue
		}

		switch req.Id {
		case "init":
			writeToStderr(fmt.Sprintf("Initialised test custom adapter for %s\n", req.Operation), errWriter)
			resp := &initResponse{}
			sendResponse(resp, writer, errWriter)
		case "download":
			writeToStderr(fmt.Sprintf("Received download request for %s\n", req.Oid), errWriter)
			performDownload(req.Oid, req.Size, req.Action, writer, errWriter)
		case "upload":
			writeToStderr(fmt.Sprintf("Received upload request for %s\n", req.Oid), errWriter)
			performUpload(req.Oid, req.Size, req.Action, req.Path, writer, errWriter)
		case "terminate":
			writeToStderr("Terminating test custom adapter gracefully.\n", errWriter)
			break
		}
	}

}

func writeToStderr(msg string, errWriter *bufio.Writer) {
	if !strings.HasSuffix(msg, "\n") {
		msg = msg + "\n"
	}
	errWriter.WriteString(msg)
	errWriter.Flush()
}

func sendResponse(r interface{}, writer, errWriter *bufio.Writer) error {
	b, err := json.Marshal(r)
	if err != nil {
		return err
	}
	// Line oriented JSON
	b = append(b, '\n')
	_, err = writer.Write(b)
	if err != nil {
		return err
	}
	writer.Flush()
	writeToStderr(fmt.Sprintf("Sent message %v", string(b)), errWriter)
	return nil
}

func sendTransferError(oid string, code int, message string, writer, errWriter *bufio.Writer) {
	resp := &transferResponse{"complete", oid, "", &transferError{code, message}}
	err := sendResponse(resp, writer, errWriter)
	if err != nil {
		writeToStderr(fmt.Sprintf("Unable to send transfer error: %v\n", err), errWriter)
	}
}

func sendProgress(oid string, bytesSoFar int64, bytesSinceLast int, writer, errWriter *bufio.Writer) {
	resp := &progressResponse{"progress", oid, bytesSoFar, bytesSinceLast}
	err := sendResponse(resp, writer, errWriter)
	if err != nil {
		writeToStderr(fmt.Sprintf("Unable to send progress update: %v\n", err), errWriter)
	}
}

func performDownload(oid string, size int64, a *action, writer, errWriter *bufio.Writer) {
	// We just use the URLs we're given, so we're just a proxy for the direct method
	// but this is enough to test intermediate custom adapters
	req, err := httputil.NewHttpRequest("GET", a.Href, a.Header)
	if err != nil {
		sendTransferError(oid, 2, err.Error(), writer, errWriter)
		return
	}
	res, err := httputil.DoHttpRequest(req, true)
	if err != nil {
		sendTransferError(oid, res.StatusCode, err.Error(), writer, errWriter)
		return
	}
	defer res.Body.Close()

	dlFile, err := ioutil.TempFile("", "lfscustomdl")
	if err != nil {
		sendTransferError(oid, 3, err.Error(), writer, errWriter)
		return
	}
	defer dlFile.Close()
	dlfilename := dlFile.Name()
	// Wrap callback to give name context
	cb := func(totalSize int64, readSoFar int64, readSinceLast int) error {
		sendProgress(oid, readSoFar, readSinceLast, writer, errWriter)
		return nil
	}
	_, err = tools.CopyWithCallback(dlFile, res.Body, res.ContentLength, cb)
	if err != nil {
		sendTransferError(oid, 4, fmt.Sprintf("cannot write data to tempfile %q: %v", dlfilename, err), writer, errWriter)
		os.Remove(dlfilename)
		return
	}
	if err := dlFile.Close(); err != nil {
		sendTransferError(oid, 5, fmt.Sprintf("can't close tempfile %q: %v", dlfilename, err), writer, errWriter)
		os.Remove(dlfilename)
		return
	}

	// completed
	complete := &transferResponse{"complete", oid, dlfilename, nil}
	err = sendResponse(complete, writer, errWriter)
	if err != nil {
		writeToStderr(fmt.Sprintf("Unable to send completion message: %v\n", err), errWriter)
	}
}

func performUpload(oid string, size int64, a *action, fromPath string, writer, errWriter *bufio.Writer) {
	// We just use the URLs we're given, so we're just a proxy for the direct method
	// but this is enough to test intermediate custom adapters
	req, err := httputil.NewHttpRequest("PUT", a.Href, a.Header)
	if err != nil {
		sendTransferError(oid, 2, err.Error(), writer, errWriter)
		return
	}

	if len(req.Header.Get("Content-Type")) == 0 {
		req.Header.Set("Content-Type", "application/octet-stream")
	}

	if req.Header.Get("Transfer-Encoding") == "chunked" {
		req.TransferEncoding = []string{"chunked"}
	} else {
		req.Header.Set("Content-Length", strconv.FormatInt(size, 10))
	}

	req.ContentLength = size

	f, err := os.OpenFile(fromPath, os.O_RDONLY, 0644)
	if err != nil {
		sendTransferError(oid, 3, fmt.Sprintf("Cannot read data from %q: %v", fromPath, err), writer, errWriter)
		return
	}
	defer f.Close()

	// Ensure progress callbacks made while uploading
	// Wrap callback to give name context
	cb := func(totalSize int64, readSoFar int64, readSinceLast int) error {
		sendProgress(oid, readSoFar, readSinceLast, writer, errWriter)
		return nil
	}
	var reader io.Reader
	reader = &progress.CallbackReader{
		C:         cb,
		TotalSize: size,
		Reader:    f,
	}

	req.Body = ioutil.NopCloser(reader)

	res, err := httputil.DoHttpRequest(req, true)
	if err != nil {
		sendTransferError(oid, res.StatusCode, fmt.Sprintf("Error uploading data for %s: %v", oid, err), writer, errWriter)
		return
	}

	if res.StatusCode > 299 {
		sendTransferError(oid, res.StatusCode, fmt.Sprintf("Invalid status for %s: %d", httputil.TraceHttpReq(req), res.StatusCode), writer, errWriter)
		return
	}

	io.Copy(ioutil.Discard, res.Body)
	res.Body.Close()

	// completed
	complete := &transferResponse{"complete", oid, "", nil}
	err = sendResponse(complete, writer, errWriter)
	if err != nil {
		writeToStderr(fmt.Sprintf("Unable to send completion message: %v\n", err), errWriter)
	}

}

// Structs reimplemented so closer to a real external implementation
type header struct {
	Key   string `json:"key"`
	Value string `json:"value"`
}
type action struct {
	Href      string            `json:"href"`
	Header    map[string]string `json:"header,omitempty"`
	ExpiresAt time.Time         `json:"expires_at,omitempty"`
}
type transferError struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
}

// Combined request struct which can accept anything
type request struct {
	Id                  string  `json:"id"`
	Operation           string  `json:"operation"`
	Concurrent          bool    `json:"concurrent"`
	ConcurrentTransfers int     `json:"concurrenttransfers"`
	Oid                 string  `json:"oid"`
	Size                int64   `json:"size"`
	Path                string  `json:"path"`
	Action              *action `json:"action"`
}

type initResponse struct {
	Error *api.ObjectError `json:"error,omitempty"`
}
type transferResponse struct {
	Id    string         `json:"id"`
	Oid   string         `json:"oid"`
	Path  string         `json:"path,omitempty"` // always blank for upload
	Error *transferError `json:"error,omitempty"`
}
type progressResponse struct {
	Id             string `json:"id"`
	Oid            string `json:"oid"`
	BytesSoFar     int64  `json:"bytesSoFar"`
	BytesSinceLast int    `json:"bytesSinceLast"`
}
<commit_msg>Remove unnecessary dependency on api package<commit_after>// +build testtools

package main

import (
	"bufio"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"strconv"
	"strings"
	"time"

	"github.com/github/git-lfs/httputil"
	"github.com/github/git-lfs/progress"
	"github.com/github/git-lfs/tools"
)

// This test custom adapter just acts as a bridge for uploads/downloads
// in order to demonstrate & test the custom transfer adapter protocols
// All we actually do is relay the requests back to the normal storage URLs
// of our test server for simplicity, but this proves the principle
func main() {

	scanner := bufio.NewScanner(os.Stdin)
	writer := bufio.NewWriter(os.Stdout)
	errWriter := bufio.NewWriter(os.Stderr)

	for scanner.Scan() {
		line := scanner.Text()
		var req request
		if err := json.Unmarshal([]byte(line), &req); err != nil {
			writeToStderr(fmt.Sprintf("Unable to parse request: %v\n", line), errWriter)
			continue
		}

		switch req.Id {
		case "init":
			writeToStderr(fmt.Sprintf("Initialised test custom adapter for %s\n", req.Operation), errWriter)
			resp := &initResponse{}
			sendResponse(resp, writer, errWriter)
		case "download":
			writeToStderr(fmt.Sprintf("Received download request for %s\n", req.Oid), errWriter)
			performDownload(req.Oid, req.Size, req.Action, writer, errWriter)
		case "upload":
			writeToStderr(fmt.Sprintf("Received upload request for %s\n", req.Oid), errWriter)
			performUpload(req.Oid, req.Size, req.Action, req.Path, writer, errWriter)
		case "terminate":
			writeToStderr("Terminating test custom adapter gracefully.\n", errWriter)
			break
		}
	}

}

func writeToStderr(msg string, errWriter *bufio.Writer) {
	if !strings.HasSuffix(msg, "\n") {
		msg = msg + "\n"
	}
	errWriter.WriteString(msg)
	errWriter.Flush()
}

func sendResponse(r interface{}, writer, errWriter *bufio.Writer) error {
	b, err := json.Marshal(r)
	if err != nil {
		return err
	}
	// Line oriented JSON
	b = append(b, '\n')
	_, err = writer.Write(b)
	if err != nil {
		return err
	}
	writer.Flush()
	writeToStderr(fmt.Sprintf("Sent message %v", string(b)), errWriter)
	return nil
}

func sendTransferError(oid string, code int, message string, writer, errWriter *bufio.Writer) {
	resp := &transferResponse{"complete", oid, "", &transferError{code, message}}
	err := sendResponse(resp, writer, errWriter)
	if err != nil {
		writeToStderr(fmt.Sprintf("Unable to send transfer error: %v\n", err), errWriter)
	}
}

func sendProgress(oid string, bytesSoFar int64, bytesSinceLast int, writer, errWriter *bufio.Writer) {
	resp := &progressResponse{"progress", oid, bytesSoFar, bytesSinceLast}
	err := sendResponse(resp, writer, errWriter)
	if err != nil {
		writeToStderr(fmt.Sprintf("Unable to send progress update: %v\n", err), errWriter)
	}
}

func performDownload(oid string, size int64, a *action, writer, errWriter *bufio.Writer) {
	// We just use the URLs we're given, so we're just a proxy for the direct method
	// but this is enough to test intermediate custom adapters
	req, err := httputil.NewHttpRequest("GET", a.Href, a.Header)
	if err != nil {
		sendTransferError(oid, 2, err.Error(), writer, errWriter)
		return
	}
	res, err := httputil.DoHttpRequest(req, true)
	if err != nil {
		sendTransferError(oid, res.StatusCode, err.Error(), writer, errWriter)
		return
	}
	defer res.Body.Close()

	dlFile, err := ioutil.TempFile("", "lfscustomdl")
	if err != nil {
		sendTransferError(oid, 3, err.Error(), writer, errWriter)
		return
	}
	defer dlFile.Close()
	dlfilename := dlFile.Name()
	// Wrap callback to give name context
	cb := func(totalSize int64, readSoFar int64, readSinceLast int) error {
		sendProgress(oid, readSoFar, readSinceLast, writer, errWriter)
		return nil
	}
	_, err = tools.CopyWithCallback(dlFile, res.Body, res.ContentLength, cb)
	if err != nil {
		sendTransferError(oid, 4, fmt.Sprintf("cannot write data to tempfile %q: %v", dlfilename, err), writer, errWriter)
		os.Remove(dlfilename)
		return
	}
	if err := dlFile.Close(); err != nil {
		sendTransferError(oid, 5, fmt.Sprintf("can't close tempfile %q: %v", dlfilename, err), writer, errWriter)
		os.Remove(dlfilename)
		return
	}

	// completed
	complete := &transferResponse{"complete", oid, dlfilename, nil}
	err = sendResponse(complete, writer, errWriter)
	if err != nil {
		writeToStderr(fmt.Sprintf("Unable to send completion message: %v\n", err), errWriter)
	}
}

func performUpload(oid string, size int64, a *action, fromPath string, writer, errWriter *bufio.Writer) {
	// We just use the URLs we're given, so we're just a proxy for the direct method
	// but this is enough to test intermediate custom adapters
	req, err := httputil.NewHttpRequest("PUT", a.Href, a.Header)
	if err != nil {
		sendTransferError(oid, 2, err.Error(), writer, errWriter)
		return
	}

	if len(req.Header.Get("Content-Type")) == 0 {
		req.Header.Set("Content-Type", "application/octet-stream")
	}

	if req.Header.Get("Transfer-Encoding") == "chunked" {
		req.TransferEncoding = []string{"chunked"}
	} else {
		req.Header.Set("Content-Length", strconv.FormatInt(size, 10))
	}

	req.ContentLength = size

	f, err := os.OpenFile(fromPath, os.O_RDONLY, 0644)
	if err != nil {
		sendTransferError(oid, 3, fmt.Sprintf("Cannot read data from %q: %v", fromPath, err), writer, errWriter)
		return
	}
	defer f.Close()

	// Ensure progress callbacks made while uploading
	// Wrap callback to give name context
	cb := func(totalSize int64, readSoFar int64, readSinceLast int) error {
		sendProgress(oid, readSoFar, readSinceLast, writer, errWriter)
		return nil
	}
	var reader io.Reader
	reader = &progress.CallbackReader{
		C:         cb,
		TotalSize: size,
		Reader:    f,
	}

	req.Body = ioutil.NopCloser(reader)

	res, err := httputil.DoHttpRequest(req, true)
	if err != nil {
		sendTransferError(oid, res.StatusCode, fmt.Sprintf("Error uploading data for %s: %v", oid, err), writer, errWriter)
		return
	}

	if res.StatusCode > 299 {
		sendTransferError(oid, res.StatusCode, fmt.Sprintf("Invalid status for %s: %d", httputil.TraceHttpReq(req), res.StatusCode), writer, errWriter)
		return
	}

	io.Copy(ioutil.Discard, res.Body)
	res.Body.Close()

	// completed
	complete := &transferResponse{"complete", oid, "", nil}
	err = sendResponse(complete, writer, errWriter)
	if err != nil {
		writeToStderr(fmt.Sprintf("Unable to send completion message: %v\n", err), errWriter)
	}

}

// Structs reimplemented so closer to a real external implementation
type header struct {
	Key   string `json:"key"`
	Value string `json:"value"`
}
type action struct {
	Href      string            `json:"href"`
	Header    map[string]string `json:"header,omitempty"`
	ExpiresAt time.Time         `json:"expires_at,omitempty"`
}
type transferError struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
}

// Combined request struct which can accept anything
type request struct {
	Id                  string  `json:"id"`
	Operation           string  `json:"operation"`
	Concurrent          bool    `json:"concurrent"`
	ConcurrentTransfers int     `json:"concurrenttransfers"`
	Oid                 string  `json:"oid"`
	Size                int64   `json:"size"`
	Path                string  `json:"path"`
	Action              *action `json:"action"`
}

type initResponse struct {
	Error *transferError `json:"error,omitempty"`
}
type transferResponse struct {
	Id    string         `json:"id"`
	Oid   string         `json:"oid"`
	Path  string         `json:"path,omitempty"` // always blank for upload
	Error *transferError `json:"error,omitempty"`
}
type progressResponse struct {
	Id             string `json:"id"`
	Oid            string `json:"oid"`
	BytesSoFar     int64  `json:"bytesSoFar"`
	BytesSinceLast int    `json:"bytesSinceLast"`
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"github.com/kortschak/BioGo/align/pals"
	"github.com/kortschak/BioGo/align/pals/filter"
	"github.com/kortschak/BioGo/morass"
	"github.com/kortschak/BioGo/seq"
	"io"
	"log"
	"os"
	"path/filepath"
	"runtime"
	"runtime/pprof"
	"strconv"
	"strings"
	"time"
)

const (
	timeFormat = "20060102150405-Mon"
)

var (
	pid           = os.Getpid()
	mem           *uintptr
	profile       *os.File
	queryName     string
	targetName    string
	selfCompare   bool
	sameStrand    bool
	outFile       string
	maxK          int
	minHitLen     int
	minId         float64
	dpMinHitLen   int
	dpMinId       float64
	tubeOffset    int
	tmpDir        string
	tmpChunk      int
	tmpConcurrent bool
	threads       int
	maxMem        uint64
	logToFile     bool
	debug         bool
	verbose       bool
	cpuprofile    string
	logger        *log.Logger
)

func init() {
	flag.StringVar(&queryName, "query", "", "Filename for query sequence.")
	flag.StringVar(&targetName, "target", "", "Filename for target sequence.")
	flag.BoolVar(&selfCompare, "self", false, "Is this a self comparison?")
	flag.BoolVar(&sameStrand, "same", false, "Only compare same strand")

	flag.StringVar(&outFile, "out", "", "File to send output to.")

	flag.IntVar(&maxK, "k", -1, "Maximum kmer length (negative indicates automatic detection based on architecture).")
	flag.IntVar(&minHitLen, "filtlen", 400, "Minimum hit length for filter.")
	flag.Float64Var(&minId, "filtid", 0.94, "Minimum hit identity for filter.")
	flag.IntVar(&dpMinHitLen, "dplen", 0, "Minimum hit length for aligner.")
	flag.Float64Var(&dpMinId, "dpid", 0, "Minimum hit identity for aligner.")
	flag.IntVar(&tubeOffset, "tubeoffset", 0, "Tube offset - 0 indicate autotune.")

	flag.StringVar(&tmpDir, "tmp", "", "Path for temporary files.")
	flag.IntVar(&tmpChunk, "chunk", 1<<20, "Chunk size for morass.")
	flag.BoolVar(&tmpConcurrent, "tmpcon", false, "Process morass concurrently.")

	flag.IntVar(&threads, "threads", 1, "Number of threads to use for alignment.")
	flag.Uint64Var(&maxMem, "mem", 0, "Maximum nominal memory - 0 indicates unlimited.")

	flag.BoolVar(&logToFile, "log", false, "Log to file.")
	flag.BoolVar(&debug, "debug", false, "Include file names/lines in log.")
	flag.BoolVar(&verbose, "v", false, "Log additional information.")

	flag.StringVar(&cpuprofile, "cpuprofile", "", "write cpu profile to this file.")

	help := flag.Bool("help", false, "Print this help message.")

	flag.Parse()

	if *help {
		flag.Usage()
		os.Exit(1)
	}

	if maxMem == 0 {
		mem = nil
	} else {
		*mem = uintptr(maxMem)
	}

	runtime.GOMAXPROCS(threads)
}

func initLog(fileName string) {
	var w io.Writer = os.Stderr
	if fileName != "" {
		if file, err := os.Create(fileName); err == nil {
			fmt.Fprintln(file, strings.Join(os.Args, " "))
			w = io.MultiWriter(os.Stderr, file)
		} else {
			fmt.Printf("Error: Could not open log file: %v", err)
			os.Exit(1)
		}
	}

	logger = log.New(w, fmt.Sprintf("%s:", filepath.Base(os.Args[0])), log.Flags())
	if debug {
		logger.SetFlags(log.Flags() | log.Lshortfile)
	}
}

func main() {
	if cpuprofile != "" {
		profile, err := os.Create(cpuprofile)
		if err != nil {
			fmt.Fprintf(os.Stderr, "Error: %v.", err)
			os.Exit(0)
		}
		fmt.Fprintf(os.Stderr, "Writing CPU profile data to %s\n", cpuprofile)
		pprof.StartCPUProfile(profile)
		defer pprof.StopCPUProfile()
	}

	if logToFile {
		initLog("krishna-" + time.Now().Format(timeFormat) + "-" + strconv.Itoa(pid) + ".log")
	} else {
		initLog("")
	}

	logger.Println(os.Args)
	var target, query *seq.Seq
	if targetName != "" {
		target = packSequence(targetName)
	} else {
		logger.Fatalln("No target provided.")
	}

	var writer *pals.Writer
	if outFile == "" {
		writer = pals.NewWriter(os.Stdout, 2, 60, false)
	} else {
		var err error
		writer, err = pals.NewWriterName(outFile, 2, 60, false)
		if err != nil {
			log.Fatalf("Could not open output file: %v", err)
		}
	}
	defer writer.Close()

	if !selfCompare {
		if queryName != "" {
			query = packSequence(queryName)
		} else {
			logger.Fatalln("No query provided in non-self comparison.")
		}
	} else {
		query = target
	}

	if maxK > 0 {
		pals.MaxKmerLen = maxK
	}

	m, err := morass.New(filter.FilterHit{}, "krishna_"+strconv.Itoa(pid), tmpDir, tmpChunk, tmpConcurrent)
	if err != nil {
		logger.Fatalf("Error: %v", err)
	}
	pa := pals.New(target, query, selfCompare, m, threads, tubeOffset, mem, logger)

	if err = pa.Optimise(minHitLen, minId); err != nil {
		logger.Fatalf("Error: %v", err)
	}
	if dpMinHitLen != 0 && dpMinId != 0 {
		pa.DPParams.MinHitLength = minHitLen
		pa.DPParams.MinId = minId
	}
	logger.Printf("Using filter parameters:")
	logger.Printf("\tWordSize = %d", pa.FilterParams.WordSize)
	logger.Printf("\tMinMatch = %d", pa.FilterParams.MinMatch)
	logger.Printf("\tMaxError = %d", pa.FilterParams.MaxError)
	logger.Printf("\tTubeOffset = %d", pa.FilterParams.TubeOffset)
	logger.Printf("\tAvg List Length = %.3f", pa.AvgIndexListLength(pa.FilterParams))
	logger.Printf("Using dynamic programming parameters:")
	logger.Printf("\tMinLen = %d", pa.DPParams.MinHitLength)
	logger.Printf("\tMinID = %.1f%%", pa.DPParams.MinId*100)
	logger.Printf("Estimated minimum memory required = %dMiB", pa.MemRequired(pa.FilterParams)/(1<<20))
	logger.Printf("Building index for %s", target.ID)

	if err = pa.BuildIndex(); err != nil {
		logger.Fatalf("Error: %v", err)
	}

	both := !sameStrand
	for _, comp := range [...]bool{false, true} {
		if comp {
			logger.Println("Working on complementary strands")
		} else {
			logger.Println("Working on self strand")
		}
		if both || !comp {
			hits, err := pa.Align(comp)
			if err != nil {
				logger.Fatalf("Error: %v", err)
			}

			logger.Println("Writing results")
			n, err := WriteDPHits(writer, target, query, hits, comp)
			if err != nil {
				logger.Fatalf("Error: %v.", err)
			}
			logger.Printf("Wrote hits (%v bytes)", n)
		}
	}
}
<commit_msg>Clean up properly and mark tmp more meaningfully<commit_after>package main

import (
	"flag"
	"fmt"
	"github.com/kortschak/BioGo/align/pals"
	"github.com/kortschak/BioGo/align/pals/filter"
	"github.com/kortschak/BioGo/morass"
	"github.com/kortschak/BioGo/seq"
	"io"
	"log"
	"os"
	"path/filepath"
	"runtime"
	"runtime/pprof"
	"strconv"
	"strings"
	"time"
)

const (
	timeFormat = "20060102150405-Mon"
)

var (
	pid           = os.Getpid()
	mem           *uintptr
	profile       *os.File
	queryName     string
	targetName    string
	selfCompare   bool
	sameStrand    bool
	outFile       string
	maxK          int
	minHitLen     int
	minId         float64
	dpMinHitLen   int
	dpMinId       float64
	tubeOffset    int
	tmpDir        string
	tmpChunk      int
	tmpConcurrent bool
	threads       int
	maxMem        uint64
	logToFile     bool
	debug         bool
	verbose       bool
	cpuprofile    string
	logger        *log.Logger
)

func init() {
	flag.StringVar(&queryName, "query", "", "Filename for query sequence.")
	flag.StringVar(&targetName, "target", "", "Filename for target sequence.")
	flag.BoolVar(&selfCompare, "self", false, "Is this a self comparison?")
	flag.BoolVar(&sameStrand, "same", false, "Only compare same strand")

	flag.StringVar(&outFile, "out", "", "File to send output to.")

	flag.IntVar(&maxK, "k", -1, "Maximum kmer length (negative indicates automatic detection based on architecture).")
	flag.IntVar(&minHitLen, "filtlen", 400, "Minimum hit length for filter.")
	flag.Float64Var(&minId, "filtid", 0.94, "Minimum hit identity for filter.")
	flag.IntVar(&dpMinHitLen, "dplen", 0, "Minimum hit length for aligner.")
	flag.Float64Var(&dpMinId, "dpid", 0, "Minimum hit identity for aligner.")
	flag.IntVar(&tubeOffset, "tubeoffset", 0, "Tube offset - 0 indicate autotune.")

	flag.StringVar(&tmpDir, "tmp", "", "Path for temporary files.")
	flag.IntVar(&tmpChunk, "chunk", 1<<20, "Chunk size for morass.")
	flag.BoolVar(&tmpConcurrent, "tmpcon", false, "Process morass concurrently.")

	flag.IntVar(&threads, "threads", 1, "Number of threads to use for alignment.")
	flag.Uint64Var(&maxMem, "mem", 0, "Maximum nominal memory - 0 indicates unlimited.")

	flag.BoolVar(&logToFile, "log", false, "Log to file.")
	flag.BoolVar(&debug, "debug", false, "Include file names/lines in log.")
	flag.BoolVar(&verbose, "v", false, "Log additional information.")

	flag.StringVar(&cpuprofile, "cpuprofile", "", "write cpu profile to this file.")

	help := flag.Bool("help", false, "Print this help message.")

	flag.Parse()

	if *help {
		flag.Usage()
		os.Exit(1)
	}

	if maxMem == 0 {
		mem = nil
	} else {
		*mem = uintptr(maxMem)
	}

	runtime.GOMAXPROCS(threads)
}

func initLog(fileName string) {
	var w io.Writer = os.Stderr
	if fileName != "" {
		if file, err := os.Create(fileName); err == nil {
			fmt.Fprintln(file, strings.Join(os.Args, " "))
			w = io.MultiWriter(os.Stderr, file)
		} else {
			fmt.Printf("Error: Could not open log file: %v", err)
			os.Exit(1)
		}
	}

	logger = log.New(w, fmt.Sprintf("%s:", filepath.Base(os.Args[0])), log.Flags())
	if debug {
		logger.SetFlags(log.Flags() | log.Lshortfile)
	}
}

func main() {
	if cpuprofile != "" {
		profile, err := os.Create(cpuprofile)
		if err != nil {
			fmt.Fprintf(os.Stderr, "Error: %v.", err)
			os.Exit(0)
		}
		fmt.Fprintf(os.Stderr, "Writing CPU profile data to %s\n", cpuprofile)
		pprof.StartCPUProfile(profile)
		defer pprof.StopCPUProfile()
	}

	if logToFile {
		initLog("krishna-" + time.Now().Format(timeFormat) + "-" + strconv.Itoa(pid) + ".log")
	} else {
		initLog("")
	}

	logger.Println(os.Args)
	var target, query *seq.Seq
	if targetName != "" {
		target = packSequence(targetName)
	} else {
		logger.Fatalln("No target provided.")
	}

	var writer *pals.Writer
	if outFile == "" {
		writer = pals.NewWriter(os.Stdout, 2, 60, false)
	} else {
		var err error
		writer, err = pals.NewWriterName(outFile, 2, 60, false)
		if err != nil {
			log.Fatalf("Could not open output file: %v", err)
		}
	}
	defer writer.Close()

	if !selfCompare {
		if queryName != "" {
			query = packSequence(queryName)
		} else {
			logger.Fatalln("No query provided in non-self comparison.")
		}
	} else {
		query = target
	}

	if maxK > 0 {
		pals.MaxKmerLen = maxK
	}

	m, err := morass.New(filter.FilterHit{}, "krishna_"+strconv.Itoa(pid)+"_", tmpDir, tmpChunk, tmpConcurrent)
	if err != nil {
		logger.Fatalf("Error: %v", err)
	}
	pa := pals.New(target, query, selfCompare, m, threads, tubeOffset, mem, logger)

	if err = pa.Optimise(minHitLen, minId); err != nil {
		logger.Fatalf("Error: %v", err)
	}
	if dpMinHitLen != 0 && dpMinId != 0 {
		pa.DPParams.MinHitLength = minHitLen
		pa.DPParams.MinId = minId
	}
	logger.Printf("Using filter parameters:")
	logger.Printf("\tWordSize = %d", pa.FilterParams.WordSize)
	logger.Printf("\tMinMatch = %d", pa.FilterParams.MinMatch)
	logger.Printf("\tMaxError = %d", pa.FilterParams.MaxError)
	logger.Printf("\tTubeOffset = %d", pa.FilterParams.TubeOffset)
	logger.Printf("\tAvg List Length = %.3f", pa.AvgIndexListLength(pa.FilterParams))
	logger.Printf("Using dynamic programming parameters:")
	logger.Printf("\tMinLen = %d", pa.DPParams.MinHitLength)
	logger.Printf("\tMinID = %.1f%%", pa.DPParams.MinId*100)
	logger.Printf("Estimated minimum memory required = %dMiB", pa.MemRequired(pa.FilterParams)/(1<<20))
	logger.Printf("Building index for %s", target.ID)

	if err = pa.BuildIndex(); err != nil {
		logger.Fatalf("Error: %v", err)
	}

	both := !sameStrand
	for _, comp := range [...]bool{false, true} {
		if comp {
			logger.Println("Working on complementary strands")
		} else {
			logger.Println("Working on self strand")
		}
		if both || !comp {
			hits, err := pa.Align(comp)
			if err != nil {
				logger.Fatalf("Error: %v", err)
			}

			logger.Println("Writing results")
			n, err := WriteDPHits(writer, target, query, hits, comp)
			if err != nil {
				logger.Fatalf("Error: %v.", err)
			}
			logger.Printf("Wrote hits (%v bytes)", n)
		}
	}

	pa.CleanUp()
}
<|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 example

package main

import (
	"fmt"
	_ "image/png"
	"log"
	"math"
	"math/rand"

	"github.com/hajimehoshi/ebiten"
	"github.com/hajimehoshi/ebiten/ebitenutil"
)

const (
	screenWidth  = 320
	screenHeight = 240
	maxAngle     = 256
)

var (
	ebitenImage *ebiten.Image
)

type Sprite struct {
	imageWidth  int
	imageHeight int
	x           int
	y           int
	vx          int
	vy          int
	angle       int
}

func (s *Sprite) Update() {
	s.x += s.vx
	s.y += s.vy
	if s.x < 0 {
		s.x = -s.x
		s.vx = -s.vx
	} else if screenWidth <= s.x+s.imageWidth {
		s.x = 2*(screenWidth-s.imageWidth) - s.x
		s.vx = -s.vx
	}
	if s.y < 0 {
		s.y = -s.y
		s.vy = -s.vy
	} else if screenHeight <= s.y+s.imageHeight {
		s.y = 2*(screenHeight-s.imageHeight) - s.y
		s.vy = -s.vy
	}
	s.angle++
	s.angle %= maxAngle
}

type Sprites struct {
	sprites []*Sprite
	num     int
}

func (s *Sprites) Update() {
	for _, sprite := range s.sprites {
		sprite.Update()
	}
}

const (
	MinSprites = 0
	MaxSprites = 50000
)

var (
	sprites = &Sprites{make([]*Sprite, MaxSprites), 500}
	op      = &ebiten.DrawImageOptions{}
)

func update(screen *ebiten.Image) error {
	if ebiten.IsKeyPressed(ebiten.KeyLeft) {
		sprites.num -= 20
		if sprites.num < MinSprites {
			sprites.num = MinSprites
		}
	}
	if ebiten.IsKeyPressed(ebiten.KeyRight) {
		sprites.num += 20
		if MaxSprites < sprites.num {
			sprites.num = MaxSprites
		}
	}
	sprites.Update()

	if ebiten.IsRunningSlowly() {
		return nil
	}
	w, h := ebitenImage.Size()
	for i := 0; i < sprites.num; i++ {
		s := sprites.sprites[i]
		op.GeoM.Reset()
		op.GeoM.Translate(-float64(w)/2, -float64(h)/2)
		op.GeoM.Rotate(2 * math.Pi * float64(s.angle) / maxAngle)
		op.GeoM.Translate(float64(w)/2, float64(h)/2)
		op.GeoM.Translate(float64(s.x), float64(s.y))
		screen.DrawImage(ebitenImage, op)
	}
	msg := fmt.Sprintf(`FPS: %0.2f
Num of sprites: %d
Press <- or -> to change the number of sprites`, ebiten.CurrentFPS(), sprites.num)
	ebitenutil.DebugPrint(screen, msg)
	return nil
}

func main() {
	var err error
	img, _, err := ebitenutil.NewImageFromFile("_resources/images/ebiten.png", ebiten.FilterNearest)
	if err != nil {
		log.Fatal(err)
	}
	w, h := img.Size()
	ebitenImage, _ = ebiten.NewImage(w, h, ebiten.FilterNearest)
	op := &ebiten.DrawImageOptions{}
	op.ColorM.Scale(1, 1, 1, 0.5)
	ebitenImage.DrawImage(img, op)
	for i := range sprites.sprites {
		w, h := ebitenImage.Size()
		x, y := rand.Intn(screenWidth-w), rand.Intn(screenHeight-h)
		vx, vy := 2*rand.Intn(2)-1, 2*rand.Intn(2)-1
		a := rand.Intn(maxAngle)
		sprites.sprites[i] = &Sprite{
			imageWidth:  w,
			imageHeight: h,
			x:           x,
			y:           y,
			vx:          vx,
			vy:          vy,
			angle:       a,
		}
	}
	if err := ebiten.Run(update, screenWidth, screenHeight, 2, "Sprites (Ebiten Demo)"); err != nil {
		log.Fatal(err)
	}
}
<commit_msg>examples/sprites: Refactoring<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 example

package main

import (
	"fmt"
	_ "image/png"
	"log"
	"math"
	"math/rand"

	"github.com/hajimehoshi/ebiten"
	"github.com/hajimehoshi/ebiten/ebitenutil"
)

const (
	screenWidth  = 320
	screenHeight = 240
	maxAngle     = 256
)

var (
	ebitenImage *ebiten.Image
)

type Sprite struct {
	imageWidth  int
	imageHeight int
	x           int
	y           int
	vx          int
	vy          int
	angle       int
}

func (s *Sprite) Update() {
	s.x += s.vx
	s.y += s.vy
	if s.x < 0 {
		s.x = -s.x
		s.vx = -s.vx
	} else if screenWidth <= s.x+s.imageWidth {
		s.x = 2*(screenWidth-s.imageWidth) - s.x
		s.vx = -s.vx
	}
	if s.y < 0 {
		s.y = -s.y
		s.vy = -s.vy
	} else if screenHeight <= s.y+s.imageHeight {
		s.y = 2*(screenHeight-s.imageHeight) - s.y
		s.vy = -s.vy
	}
	s.angle++
	s.angle %= maxAngle
}

type Sprites struct {
	sprites []*Sprite
	num     int
}

func (s *Sprites) Update() {
	for _, sprite := range s.sprites {
		sprite.Update()
	}
}

const (
	MinSprites = 0
	MaxSprites = 50000
)

var (
	sprites = &Sprites{make([]*Sprite, MaxSprites), 500}
	op      = &ebiten.DrawImageOptions{}
)

func init() {
	img, _, err := ebitenutil.NewImageFromFile("_resources/images/ebiten.png", ebiten.FilterNearest)
	if err != nil {
		log.Fatal(err)
	}
	w, h := img.Size()
	ebitenImage, _ = ebiten.NewImage(w, h, ebiten.FilterNearest)
	op := &ebiten.DrawImageOptions{}
	op.ColorM.Scale(1, 1, 1, 0.5)
	ebitenImage.DrawImage(img, op)
	for i := range sprites.sprites {
		w, h := ebitenImage.Size()
		x, y := rand.Intn(screenWidth-w), rand.Intn(screenHeight-h)
		vx, vy := 2*rand.Intn(2)-1, 2*rand.Intn(2)-1
		a := rand.Intn(maxAngle)
		sprites.sprites[i] = &Sprite{
			imageWidth:  w,
			imageHeight: h,
			x:           x,
			y:           y,
			vx:          vx,
			vy:          vy,
			angle:       a,
		}
	}
}

func update(screen *ebiten.Image) error {
	// Decrease the nubmer of the sprites.
	if ebiten.IsKeyPressed(ebiten.KeyLeft) {
		sprites.num -= 20
		if sprites.num < MinSprites {
			sprites.num = MinSprites
		}
	}

	// Increase the nubmer of the sprites.
	if ebiten.IsKeyPressed(ebiten.KeyRight) {
		sprites.num += 20
		if MaxSprites < sprites.num {
			sprites.num = MaxSprites
		}
	}

	sprites.Update()

	if ebiten.IsRunningSlowly() {
		return nil
	}

	// Draw each sprite.
	// DrawImage can be called many many times, but in the implementation,
	// the actual draw call to GPU is very few since these calls satisfy
	// some conditions e.g. all the rendering sources and targets are same.
	// For more detail, see:
	// https://godoc.org/github.com/hajimehoshi/ebiten#Image.DrawImage
	w, h := ebitenImage.Size()
	for i := 0; i < sprites.num; i++ {
		s := sprites.sprites[i]
		op.GeoM.Reset()
		op.GeoM.Translate(-float64(w)/2, -float64(h)/2)
		op.GeoM.Rotate(2 * math.Pi * float64(s.angle) / maxAngle)
		op.GeoM.Translate(float64(w)/2, float64(h)/2)
		op.GeoM.Translate(float64(s.x), float64(s.y))
		screen.DrawImage(ebitenImage, op)
	}
	msg := fmt.Sprintf(`FPS: %0.2f
Num of sprites: %d
Press <- or -> to change the number of sprites`, ebiten.CurrentFPS(), sprites.num)
	ebitenutil.DebugPrint(screen, msg)
	return nil
}

func main() {
	if err := ebiten.Run(update, screenWidth, screenHeight, 2, "Sprites (Ebiten Demo)"); err != nil {
		log.Fatal(err)
	}
}
<|endoftext|>


<commit_before>// +build k8srequired

package clusterstate

import (
	"testing"

	"github.com/giantswarm/e2etests/clusterstate"

	"github.com/giantswarm/azure-operator/integration/env"
	"github.com/giantswarm/azure-operator/integration/setup"
)

var (
	config           setup.Config
	clusterStateTest *clusterstate.ClusterState
)

func init() {
	var err error

	{
		config, err = setup.NewConfig()
		if err != nil {
			panic(err.Error())
		}
	}

	var p *Provider
	{
		c := ProviderConfig{
			AzureClient: config.AzureClient,
			G8sClient:   config.Host.G8sClient(),
			Logger:      config.Logger,

			ClusterID: env.ClusterID(),
		}

		p, err = NewProvider(c)
		if err != nil {
			panic(err.Error())
		}
	}

	{
		c := clusterstate.Config{
			GuestFramework: config.Guest,
			Logger:         config.Logger,
			Provider:       p,
		}

		clusterStateTest, err = clusterstate.New(c)
		if err != nil {
			panic(err.Error())
		}
	}
}

// TestMain allows us to have common setup and teardown steps that are run
// once for all the tests https://golang.org/pkg/testing/#hdr-Main.
func TestMain(m *testing.M) {
	setup.WrapTestMain(m, config)
}
<commit_msg>fix e2e test (#532)<commit_after>// +build k8srequired

package clusterstate

import (
	"testing"

	"github.com/giantswarm/e2etests/clusterstate"

	"github.com/giantswarm/azure-operator/integration/env"
	"github.com/giantswarm/azure-operator/integration/setup"
)

var (
	config           setup.Config
	clusterStateTest *clusterstate.ClusterState
)

func init() {
	var err error

	{
		config, err = setup.NewConfig()
		if err != nil {
			panic(err.Error())
		}
	}

	var p *Provider
	{
		c := ProviderConfig{
			AzureClient: config.AzureClient,
			G8sClient:   config.Host.G8sClient(),
			Logger:      config.Logger,

			ClusterID: env.ClusterID(),
		}

		p, err = NewProvider(c)
		if err != nil {
			panic(err.Error())
		}
	}

	{
		c := clusterstate.Config{
			LegacyFramework: config.Guest,
			Logger:          config.Logger,
			Provider:        p,
		}

		clusterStateTest, err = clusterstate.New(c)
		if err != nil {
			panic(err.Error())
		}
	}
}

// TestMain allows us to have common setup and teardown steps that are run
// once for all the tests https://golang.org/pkg/testing/#hdr-Main.
func TestMain(m *testing.M) {
	setup.WrapTestMain(m, config)
}
<|endoftext|>


<commit_before>package expr

import (
	"bytes"
	"errors"
	"sort"
	"strings"

	"github.com/grafana/metrictank/api/models"
	schema "gopkg.in/raintank/schema.v1"
)

type FuncGroupByTags struct {
	in         GraphiteFunc
	aggregator string
	tags       []string
}

func NewGroupByTags() GraphiteFunc {
	return &FuncGroupByTags{}
}

func (s *FuncGroupByTags) Signature() ([]Arg, []Arg) {
	return []Arg{
		ArgSeriesList{val: &s.in},
		ArgString{val: &s.aggregator, validator: []Validator{IsAggFunc}},
		ArgStrings{val: &s.tags},
	}, []Arg{ArgSeries{}}
}

func (s *FuncGroupByTags) Context(context Context) Context {
	return context
}

func (s *FuncGroupByTags) Exec(cache map[Req][]models.Series) ([]models.Series, error) {
	series, err := s.in.Exec(cache)
	if err != nil {
		return nil, err
	}

	if len(s.tags) == 0 {
		return nil, errors.New("No tags specified")
	}

	groups := make(map[string][]models.Series)
	useName := false

	groupTags := s.tags
	for i, tag := range groupTags {
		if tag == "name" {
			// We handle name explicitly, remove it from tags
			useName = true
			groupTags = append(groupTags[:i], groupTags[i+1:]...)
			break
		}
	}

	nameReplace := ""
	if !useName {
		// if all series have the same name, name becomes one of our tags
		for _, serie := range series {
			thisName := strings.Split(serie.Target, ";")[0]
			if nameReplace == "" {
				nameReplace = thisName
			} else if nameReplace != thisName {
				nameReplace = s.aggregator
				break
			}
		}
	}

	// Tags need to be sorted
	sort.Strings(groupTags)

	// First pass - group our series together by key
	var buffer bytes.Buffer
	for _, serie := range series {
		name := strings.SplitN(serie.Target, ";", 2)[0]

		buffer.Reset()

		if useName {
			buffer.WriteString(name)
		} else {
			buffer.WriteString(nameReplace)
		}

		for _, goal := range groupTags {
			buffer.WriteRune(';')
			buffer.WriteString(goal)
			buffer.WriteRune('=')

			tagVal, ok := serie.Tags[goal]
			if ok {
				buffer.WriteString(tagVal)
			}
		}

		key := buffer.String()

		groups[key] = append(groups[key], serie)
	}

	output := make([]models.Series, 0, len(groups))
	aggFunc := getCrossSeriesAggFunc(s.aggregator)

	// Now, for each key perform the requested aggregation
	for name, groupSeries := range groups {
		tags := make(map[string]string, len(groupTags)+1)
		tagSplits := strings.Split(name, ";")

		tags["name"] = tagSplits[0]

		for _, split := range tagSplits[1:] {
			pair := strings.SplitN(split, "=", 2)
			tags[pair[0]] = pair[1]
		}

		cons, queryCons := summarizeCons(series)
		newSeries := models.Series{
			Target:       name,
			QueryPatt:    name,
			Tags:         tags,
			Interval:     series[0].Interval,
			Consolidator: cons,
			QueryCons:    queryCons,
		}

		newSeries.Datapoints = pointSlicePool.Get().([]schema.Point)
		aggFunc(groupSeries, &newSeries.Datapoints)
		cache[Req{}] = append(cache[Req{}], newSeries)

		output = append(output, newSeries)
	}

	return output, nil
}
<commit_msg>Use SetTags in groupByTags<commit_after>package expr

import (
	"bytes"
	"errors"
	"sort"
	"strings"

	"github.com/grafana/metrictank/api/models"
	schema "gopkg.in/raintank/schema.v1"
)

type FuncGroupByTags struct {
	in         GraphiteFunc
	aggregator string
	tags       []string
}

func NewGroupByTags() GraphiteFunc {
	return &FuncGroupByTags{}
}

func (s *FuncGroupByTags) Signature() ([]Arg, []Arg) {
	return []Arg{
		ArgSeriesList{val: &s.in},
		ArgString{val: &s.aggregator, validator: []Validator{IsAggFunc}},
		ArgStrings{val: &s.tags},
	}, []Arg{ArgSeries{}}
}

func (s *FuncGroupByTags) Context(context Context) Context {
	return context
}

func (s *FuncGroupByTags) Exec(cache map[Req][]models.Series) ([]models.Series, error) {
	series, err := s.in.Exec(cache)
	if err != nil {
		return nil, err
	}

	if len(s.tags) == 0 {
		return nil, errors.New("No tags specified")
	}

	groups := make(map[string][]models.Series)
	useName := false

	groupTags := s.tags
	for i, tag := range groupTags {
		if tag == "name" {
			// We handle name explicitly, remove it from tags
			useName = true
			groupTags = append(groupTags[:i], groupTags[i+1:]...)
			break
		}
	}

	nameReplace := ""
	if !useName {
		// if all series have the same name, name becomes one of our tags
		for _, serie := range series {
			thisName := strings.Split(serie.Target, ";")[0]
			if nameReplace == "" {
				nameReplace = thisName
			} else if nameReplace != thisName {
				nameReplace = s.aggregator
				break
			}
		}
	}

	// Tags need to be sorted
	sort.Strings(groupTags)

	// First pass - group our series together by key
	var buffer bytes.Buffer
	for _, serie := range series {
		name := strings.SplitN(serie.Target, ";", 2)[0]

		buffer.Reset()

		if useName {
			buffer.WriteString(name)
		} else {
			buffer.WriteString(nameReplace)
		}

		for _, goal := range groupTags {
			buffer.WriteRune(';')
			buffer.WriteString(goal)
			buffer.WriteRune('=')

			tagVal, ok := serie.Tags[goal]
			if ok {
				buffer.WriteString(tagVal)
			}
		}

		key := buffer.String()

		groups[key] = append(groups[key], serie)
	}

	output := make([]models.Series, 0, len(groups))
	aggFunc := getCrossSeriesAggFunc(s.aggregator)

	// Now, for each key perform the requested aggregation
	for name, groupSeries := range groups {
		cons, queryCons := summarizeCons(series)
		newSeries := models.Series{
			Target:       name,
			QueryPatt:    name,
			Interval:     series[0].Interval,
			Consolidator: cons,
			QueryCons:    queryCons,
		}
		newSeries.SetTags()

		newSeries.Datapoints = pointSlicePool.Get().([]schema.Point)
		aggFunc(groupSeries, &newSeries.Datapoints)
		cache[Req{}] = append(cache[Req{}], newSeries)

		output = append(output, newSeries)
	}

	return output, nil
}
<|endoftext|>


<commit_before>// +build linux,native darwin,native

package nativetest

import (
	"testing"

	"github.com/taskcluster/taskcluster-worker/worker/workertest"
)

func TestEnv(t *testing.T) {
	workertest.Case{
		Engine:      "native",
		Concurrency: 1,
		EngineConfig: `{
      "createUser": false
    }`,
		PluginConfig: `{
      "disabled": [],
      "artifacts": {},
      "env": {
        "extra": {"MY_STATIC_VAR": "static-value"}
      },
      "maxruntime": {
        "perTaskLimit": "require",
        "maxRunTime": "3 hours"
      },
			"livelog": {},
      "success": {}
    }`,
		Tasks: []workertest.Task{
			{
				Title:   "Access Extra Env Vars",
				Success: true,
				Payload: `{
					"command": ["sh", "-c", "echo $MY_STATIC_VAR"],
					"env": {},
					"maxRunTime": "10 minutes"
				}`,
				AllowAdditional: true, // Ignore additional artifacts
				Artifacts: workertest.ArtifactAssertions{
					"public/logs/live_backing.log": workertest.GrepArtifact("static-value"),
				},
			},
			{
				Title:   "Access Env Vars",
				Success: true,
				Payload: `{
					"command": ["sh", "-c", "echo $MY_ENV_VAR"],
					"env": {
            "MY_ENV_VAR": "hello-world"
          },
					"maxRunTime": "10 minutes"
				}`,
				AllowAdditional: true, // Ignore additional artifacts
				Artifacts: workertest.ArtifactAssertions{
					"public/logs/live_backing.log": workertest.GrepArtifact("hello-world"),
				},
			},
			{
				Title:   "Overwrite Static Env Vars",
				Success: true,
				Payload: `{
					"command": ["sh", "-c", "echo $MY_STATIC_VAR"],
					"env": {
            "MY_STATIC_VAR": "hello-world"
          },
					"maxRunTime": "10 minutes"
				}`,
				AllowAdditional: true, // Ignore additional artifacts
				Artifacts: workertest.ArtifactAssertions{
					"public/logs/live_backing.log": workertest.GrepArtifact("hello-world"),
				},
			},
			{
				Title:   "TASK_ID and RUN_ID",
				Success: true,
				Payload: `{
					"command": ["sh", "-c", "test -n \"$TASK_ID\" && test \"$RUN_ID\" = 0"],
					"env": {},
					"maxRunTime": "10 minutes"
				}`,
				AllowAdditional: true, // Ignore additional artifacts
			},
		},
	}.Test(t)
}
<commit_msg>Fixed indentation in JSON strings<commit_after>// +build linux,native darwin,native

package nativetest

import (
	"testing"

	"github.com/taskcluster/taskcluster-worker/worker/workertest"
)

func TestEnv(t *testing.T) {
	workertest.Case{
		Engine:      "native",
		Concurrency: 1,
		EngineConfig: `{
			"createUser": false
		}`,
		PluginConfig: `{
			"disabled": [],
			"artifacts": {},
			"env": {
				"extra": {"MY_STATIC_VAR": "static-value"}
			},
			"maxruntime": {
				"perTaskLimit": "require",
				"maxRunTime": "3 hours"
			},
			"livelog": {},
			"success": {}
		}`,
		Tasks: []workertest.Task{
			{
				Title:   "Access Extra Env Vars",
				Success: true,
				Payload: `{
					"command": ["sh", "-c", "echo $MY_STATIC_VAR"],
					"env": {},
					"maxRunTime": "10 minutes"
				}`,
				AllowAdditional: true, // Ignore additional artifacts
				Artifacts: workertest.ArtifactAssertions{
					"public/logs/live_backing.log": workertest.GrepArtifact("static-value"),
				},
			},
			{
				Title:   "Access Env Vars",
				Success: true,
				Payload: `{
					"command": ["sh", "-c", "echo $MY_ENV_VAR"],
					"env": {
						"MY_ENV_VAR": "hello-world"
					},
					"maxRunTime": "10 minutes"
				}`,
				AllowAdditional: true, // Ignore additional artifacts
				Artifacts: workertest.ArtifactAssertions{
					"public/logs/live_backing.log": workertest.GrepArtifact("hello-world"),
				},
			},
			{
				Title:   "Overwrite Static Env Vars",
				Success: true,
				Payload: `{
					"command": ["sh", "-c", "echo $MY_STATIC_VAR"],
					"env": {
						"MY_STATIC_VAR": "hello-world"
					},
					"maxRunTime": "10 minutes"
				}`,
				AllowAdditional: true, // Ignore additional artifacts
				Artifacts: workertest.ArtifactAssertions{
					"public/logs/live_backing.log": workertest.GrepArtifact("hello-world"),
				},
			},
			{
				Title:   "TASK_ID and RUN_ID",
				Success: true,
				Payload: `{
					"command": ["sh", "-c", "test -n \"$TASK_ID\" && test \"$RUN_ID\" = 0"],
					"env": {},
					"maxRunTime": "10 minutes"
				}`,
				AllowAdditional: true, // Ignore additional artifacts
			},
		},
	}.Test(t)
}
<|endoftext|>


<commit_before>package main

import "strings"
import "github.com/gedex/inflector"

var TypeIota int

type Type struct {
	Name, Push, Pop string
	Int int
	User bool
	List bool

	Super string

	Decimal bool

	Detail *UserType
	Interface *Interface
}

func (t Type) DefaultValue() string {
	switch t.Push {
		case "PUSH":
			return "0"
		case "SHARE":
			return "backup"
		case "RELAY":
			return "open"
	}
	return ""
}

func (t Type) IsUser() Type {
	if t.User {
		return t
	} else {
		return Undefined
	}
}

func (t Type) IsMatrix() Type {
	if t.Name == "matrix" {
		return t
	} else {
		return Undefined
	}
}

func (t Type) IsArray() Type {
	if t.Name == "array" {
		return t
	} else {
		return Undefined
	}
}

func (t Type) IsList() Type {
	if t.List {
		return t
	} else {
		return Undefined
	}
}

type UserType struct {
	Elements []Type
	Table map[string]int
	SubElements map[int]Type
}

func NewUserType(name string) Type {
	t := NewType(name, "SHARE", "GRAB")
	t.User = true
	t.Detail = new(UserType)
	t.Detail.Table = make(map[string]int)
	return t
}

var string2type = map[string]Type{}

func NewType(name string, options ...string) Type {
	var t Type
	t.Name = name

	if len(options) == 2 {
		t.Pop = options[1]
		t.Push = options[0]
	}

	t.Int = TypeIota
	TypeIota++

	string2type[name] = t

	return t
}

var Undefined = NewType("undefined")
var Number = NewType("number", "PUSH", "PULL")
var Decimal = NewType("decimal", "PUSH", "PULL")
var Letter = NewType("letter", "PUSH", "PULL")
var Text = NewType("text", "SHARE", "GRAB")
var Array = NewType("array", "SHARE", "GRAB")
var Matrix = NewType("matrix", "SHARE", "GRAB")

var Itype = NewType("type", "PUSH", "PULL")
var User = NewType("usertype", "SHARE", "GRAB")
var List = NewType("list", "SHARE", "GRAB")
var Pipe = NewType("pipe", "RELAY", "TAKE")
var Func = NewType("function", "RELAY", "TAKE")
var Something = NewUserType("Something")

var Variadic = NewFlag()

func (ic *Compiler) ScanSymbolicType() Type {
	var result Type = Undefined
	var symbol = ic.Scan(0)
	switch symbol {
		case "{":
			result = User
			t := ic.Scan(0)
			if t == "." {
				result = List
				ic.Scan('.')
				ic.Scan('}')
			} else if t != "}" {
				ic.RaiseError()
			}
		case "[":
			result = Array
			ic.Scan(']')
			if tok := ic.Scan(0); tok == "[" {
				result = Matrix
				ic.Scan(']')
			} else {
				ic.NextToken = tok
			}
		case "$":
			result = ic.ScanSymbolicType()
			result.Decimal = true
		case `""`:
			result = Text
		case "' '":
			result = Letter
		case "|":
			result = Pipe
			ic.Scan('|')
		case "(":
			result = Func
			ic.Scan(')')
		case "<":
			result = Itype
			ic.Scan('>')
		case ".":
			if tok := ic.Scan(0); tok == "." {
				result = Variadic
			} else {
				ic.NextToken = tok
				result = Decimal
			}
		default:
			result = Number
			ic.NextToken = symbol
			return result
	}
	return result
}

//Check if the given type exists or not.
func (ic *Compiler) TypeExists(name string) bool {
	_, ok := ic.DefinedTypes[name]
	return ok
}

//This scans a new type definition and creates the type.
//eg. type Point { x, y }
func (ic *Compiler) ScanType() {
	var name = ic.Scan(Name)

	//This is for the grate engine.
	//Are we declaring a game?
	if name == "Game" {
		ic.Game = true
	}

	t := NewUserType(name)

	switch ic.Scan(0) {
		case "{":
		case "is": //Inheritance eg. type WeightedPoint is Point { weight }
			super := ic.Scan(Name)
			t = ic.DefinedTypes[super]
			t.Super = t.Name
			t.Name = name
			switch ic.Scan(0) {
				case "\n":
					ic.DefinedTypes[name] = t
					ic.LastDefinedType = t
					return
				case "{":
				default:
					ic.RaiseError()
			}
		default:
			ic.RaiseError()
	}

	ic.InsertPlugins(name)
	//What are the elements?
	for {
		var token = ic.Scan(0)
		if token == "}" {
			break
		}
		if token != "," && token != "\n" {
			ic.NextToken = token
		}

		MemberType := ic.ScanSymbolicType()

		ident := ic.Scan(Name)
		if ident == "}" {
			break
		}

		//Embedded structs which are inferred.
		//eg.
		/*
			type Member {}
			type Base {
				Member() //This will be accessed as 'member'.
			}
		*/
		if ic.Peek() == "(" {
			if MemberType != Number {
				ic.RaiseError("Unexpected (")
			}
			ic.Scan('(')
			ic.Scan(')')
			var ok bool
			MemberType, ok = ic.DefinedTypes[ident]
			if !ok {
				ident := inflector.Singularize(ident)
				MemberType, ok = ic.DefinedTypes[ident]
				MemberType.List = true
				MemberType.User = false
				if !ok {
					ic.RaiseError("No such type! ", ident)
				}
			}
			ident = strings.ToLower(ident)
		}

		if ident != "\n" {
			t.Detail.Elements = append(t.Detail.Elements, MemberType)
			t.Detail.Table[ident] = len(t.Detail.Elements)-1
		}

	}
	ic.DefinedTypes[name] = t

	ic.LastDefinedType = t
}

func (ic *Compiler) NewListOf(t Type) string {
	t.List = true
	t.User = false
	ic.ExpressionType = t
	var list = ic.Tmp("list")
	ic.Assembly("ARRAY ", list)
	return list
}

func (ic *Compiler) ScanList() string {
	var name = ic.Scan(Name)

	t, ok := ic.DefinedTypes[name]
	if !ok {
		if i, ok := ic.DefinedInterfaces[name]; !ok {
			ic.RaiseError(name+" is an unrecognised type!")
		} else {
			t = i.GetType()
		}
	}
	t.List = true
	t.User = false

	var list = ic.Tmp("list")

	ic.Scan('(')
	if tok := ic.Scan(0); tok != "s" {
		ic.NextToken = tok
		size := ic.ScanExpression()
		if ic.ExpressionType != Number {
			ic.RaiseError("Expecting list size!")
		}
		ic.Assembly("PUSH ", size)
		ic.Assembly("MAKE")
		ic.Assembly("GRAB ", list)
	} else {
		ic.Assembly("ARRAY ", list)
	}
	ic.Scan(')')

	ic.ExpressionType = t

	return list
}

//This scans a type literal.
// eg.
/*
	type Object {value}

	software { var o = Object{22} }
*/
func (ic *Compiler) ScanTypeLiteral() string {
	return ic.ScanConstructor()
}

func (ic *Compiler) ScanConstructor() string {
	var name = ic.Scan(Name)

	if _, ok := ic.DefinedTypes[name]; !ok {
		ic.RaiseError(name+" is an unrecognised type!")
	}

	var token = ic.Scan(0)

	/*if ic.Peek() == ")" && token == "(" {
		ic.ExpressionType = InFunction
		ic.NextToken = "("
		return name
	}*/

	var array = ic.Tmp("constructor")

	ic.Assembly("ARRAY ", array)
	//This is effectively a constructor.
	if token == "{" {
		var i int
		for {

			var expr = ic.ScanExpression()
			ic.Assembly("PLACE ", array)
			if ic.ExpressionType.Push == "PUSH" {
				ic.Assembly("PUT %v", expr)
			} else {
				var tmp = ic.Tmp("heap")
				ic.Assembly(ic.ExpressionType.Push," ", expr)
				ic.Assembly("PUSH 0")
				if ic.ExpressionType.Push == "RELAY" {
					ic.Assembly("HEAPIT")
				} else {
					ic.Assembly("HEAP")
				}
				ic.Assembly("PULL ", tmp)
				ic.Assembly("PUT ", tmp)
			}
			if i >= len(ic.DefinedTypes[name].Detail.Elements) {
				ic.RaiseError("Too many arguments passed to constructor!")
			}
			if ic.ExpressionType != ic.DefinedTypes[name].Detail.Elements[i] {
				ic.RaiseError("Mismatched types! Argument (%v) of constructor should be '%v'", i+1,
					ic.DefinedTypes[name].Detail.Elements[i])
			}
			token = ic.Scan(0)
			for token == "\n" {
				token = ic.Scan(0)
			}
			if token == "}" {
				break
			} else if token != "," {
				ic.Expecting(",")
			}
			i++
		}
		for j := range ic.DefinedTypes[name].Detail.Elements {
			if j > i {
				ic.Assembly("PUT 0")
			}
		}
	} else if token == "\n" || token == ")" {
		for range ic.DefinedTypes[name].Detail.Elements {
			ic.Assembly("PUT 0")
		}
		if token == ")" {
			ic.NextToken = ")"
		}
	} else {
		ic.RaiseError()
	}
	ic.ExpressionType = ic.DefinedTypes[name]
	return array
}

func (ic *Compiler) IndexUserType(name, element string) string {
	var t UserType
	if ic.GetVariable(name) != Undefined {
		t = *ic.GetVariable(name).Detail
		ic.SetVariable(name+"_use", Used)
	} else {
		t = *ic.ExpressionType.Detail
	}

	//Deal with indexing Something types.
	/*if GetVariable(name) == SOMETHING {
		switch element {
			case "number":
				ExpressionType = NUMBER
				fmt.Fprintf(output, "PLACE %s\n", name)
				fmt.Fprintf(output, "PUSH 0\n")
				fmt.Fprintf(output, "GET %s%v\n", "i+user+", unique)
				return "i+user+"+fmt.Sprint(unique)
		}
	}*/

	if index, ok := t.Table[element]; !ok {
		ic.RaiseError(name+" does not have an element named "+element)
	} else {

		var tmp = ic.Tmp("index")
		ic.ExpressionType = t.Elements[index]

		switch t.Elements[index].Push {
			case "PUSH":
				ic.Assembly("PLACE ", name)
				ic.Assembly("PUSH ", index)
				ic.Assembly("GET ", tmp)
				return tmp

			case "SHARE", "RELAY":
				ic.Assembly("PLACE ", name)
				ic.Assembly("PUSH ", index)
				ic.Assembly("GET ", tmp)
				ic.Assembly("IF ",tmp)
				ic.GainScope()
				ic.Assembly("PUSH ", tmp)
				if t.Elements[index].Push == "RELAY" {
					ic.Assembly("HEAPIT")
				} else {
					ic.Assembly("HEAP")
				}
				tmp = ic.Tmp("index")
				ic.Assembly(t.Elements[index].Pop, " ", tmp)
				ic.Assembly(t.Elements[index].Push, " ", tmp)
				ic.LoseScope()
				ic.Assembly("ELSE")
				ic.GainScope()
				ic.Assembly("ARRAY ", tmp)
				if t.Elements[index].User {
				for range t.Elements[index].Detail.Elements {
					ic.Assembly("PUT 0")
				}
				}
				ic.Assembly("SHARE ", tmp)
				if t.Elements[index].Push == "RELAY" {
					ic.Assembly("OPEN")
				}
				ic.LoseScope()
				ic.Assembly("END")
				ic.Assembly(t.Elements[index].Pop, " ", tmp)

				return tmp

			default:
				ic.RaiseError(name+" cannot index "+element+", type is unindexable!!!")
		}
	}
	return ""
}

func (ic *Compiler) SetUserType(name, element, value string) {
	var t UserType
	if ic.GetVariable(name) != Undefined {
		t = *ic.GetVariable(name).Detail
		ic.SetVariable(name+"_use", Used)
	} else {
		ic.RaiseError("Cannot set type without type identity!")
	}

	if index, ok := t.Table[element]; !ok {
		ic.RaiseError(name+" does not have an element named "+element)
	} else {

		if t.Elements[index] == User || (t.Elements[index] == List && ic.ExpressionType.Push == "SHARE") || ic.ExpressionType.Name == "matrix" {
			t.Elements[index] = ic.ExpressionType

			if  ic.GetFlag(InMethod) {
				ic.Assembly("PLACE ", value)
				ic.Assembly("RENAME ", element)
				//ic.SetVariable(element, ic.ExpressionType)
			}
		}

		if ic.ExpressionType != t.Elements[index] {
			ic.RaiseError("Type mismatch, cannot assign '",ic.ExpressionType.Name,"', to a element of type '",t.Elements[index].Name,"'")
		}

		switch t.Elements[index].Push {
			case "PUSH":
				ic.Assembly("PLACE ", name)
				ic.Assembly("PUSH ", index)
				ic.Assembly("SET ", value)

			case "SHARE", "RELAY":

				//TODO garbage collect
				var tmp = ic.Tmp("index")
				ic.Assembly(t.Elements[index].Push, " ", value)
				ic.Assembly("PUSH 0")
				if t.Elements[index].Push == "RELAY" {
					ic.Assembly("HEAPIT")
				} else {
					ic.Assembly("HEAP")
				}
				ic.Assembly("PULL ", tmp)

				ic.Assembly("PLACE ", name)
				ic.Assembly("PUSH ", index)
				ic.Assembly("SET ", tmp)

			default:
				ic.RaiseError(name+" cannot index "+element+", type is unindexable!!!")
		}
	}
}
<commit_msg>Fix a list bug.<commit_after>package main

import "strings"
import "github.com/gedex/inflector"

var TypeIota int

type Type struct {
	Name, Push, Pop string
	Int int
	User bool
	List bool

	Super string

	Decimal bool

	Detail *UserType
	Interface *Interface
}

func (t Type) DefaultValue() string {
	switch t.Push {
		case "PUSH":
			return "0"
		case "SHARE":
			return "backup"
		case "RELAY":
			return "open"
	}
	return ""
}

func (t Type) IsUser() Type {
	if t.User {
		return t
	} else {
		return Undefined
	}
}

func (t Type) IsMatrix() Type {
	if t.Name == "matrix" {
		return t
	} else {
		return Undefined
	}
}

func (t Type) IsArray() Type {
	if t.Name == "array" {
		return t
	} else {
		return Undefined
	}
}

func (t Type) IsList() Type {
	if t.List {
		return t
	} else {
		return Undefined
	}
}

type UserType struct {
	Elements []Type
	Table map[string]int
	SubElements map[int]Type
}

func NewUserType(name string) Type {
	t := NewType(name, "SHARE", "GRAB")
	t.User = true
	t.Detail = new(UserType)
	t.Detail.Table = make(map[string]int)
	return t
}

var string2type = map[string]Type{}

func NewType(name string, options ...string) Type {
	var t Type
	t.Name = name

	if len(options) == 2 {
		t.Pop = options[1]
		t.Push = options[0]
	}

	t.Int = TypeIota
	TypeIota++

	string2type[name] = t

	return t
}

var Undefined = NewType("undefined")
var Number = NewType("number", "PUSH", "PULL")
var Decimal = NewType("decimal", "PUSH", "PULL")
var Letter = NewType("letter", "PUSH", "PULL")
var Text = NewType("text", "SHARE", "GRAB")
var Array = NewType("array", "SHARE", "GRAB")
var Matrix = NewType("matrix", "SHARE", "GRAB")

var Itype = NewType("type", "PUSH", "PULL")
var User = NewType("usertype", "SHARE", "GRAB")
var List = NewType("list", "SHARE", "GRAB")
var Pipe = NewType("pipe", "RELAY", "TAKE")
var Func = NewType("function", "RELAY", "TAKE")
var Something = NewUserType("Something")

var Variadic = NewFlag()

func (ic *Compiler) ScanSymbolicType() Type {
	var result Type = Undefined
	var symbol = ic.Scan(0)
	switch symbol {
		case "{":
			result = User
			t := ic.Scan(0)
			if t == "." {
				result = List
				ic.Scan('.')
				ic.Scan('}')
			} else if t != "}" {
				ic.RaiseError()
			}
		case "[":
			result = Array
			ic.Scan(']')
			if tok := ic.Scan(0); tok == "[" {
				result = Matrix
				ic.Scan(']')
			} else {
				ic.NextToken = tok
			}
		case "$":
			result = ic.ScanSymbolicType()
			result.Decimal = true
		case `""`:
			result = Text
		case "' '":
			result = Letter
		case "|":
			result = Pipe
			ic.Scan('|')
		case "(":
			result = Func
			ic.Scan(')')
		case "<":
			result = Itype
			ic.Scan('>')
		case ".":
			if tok := ic.Scan(0); tok == "." {
				result = Variadic
			} else {
				ic.NextToken = tok
				result = Decimal
			}
		default:
			result = Number
			ic.NextToken = symbol
			return result
	}
	return result
}

//Check if the given type exists or not.
func (ic *Compiler) TypeExists(name string) bool {
	_, ok := ic.DefinedTypes[name]
	return ok
}

//This scans a new type definition and creates the type.
//eg. type Point { x, y }
func (ic *Compiler) ScanType() {
	var name = ic.Scan(Name)

	//This is for the grate engine.
	//Are we declaring a game?
	if name == "Game" {
		ic.Game = true
	}

	t := NewUserType(name)

	switch ic.Scan(0) {
		case "{":
		case "is": //Inheritance eg. type WeightedPoint is Point { weight }
			super := ic.Scan(Name)
			t = ic.DefinedTypes[super]
			t.Super = t.Name
			t.Name = name
			switch ic.Scan(0) {
				case "\n":
					ic.DefinedTypes[name] = t
					ic.LastDefinedType = t
					return
				case "{":
				default:
					ic.RaiseError()
			}
		default:
			ic.RaiseError()
	}

	ic.InsertPlugins(name)
	//What are the elements?
	for {
		var token = ic.Scan(0)
		if token == "}" {
			break
		}
		if token != "," && token != "\n" {
			ic.NextToken = token
		}

		MemberType := ic.ScanSymbolicType()

		ident := ic.Scan(Name)
		if ident == "}" {
			break
		}

		//Embedded structs which are inferred.
		//eg.
		/*
			type Member {}
			type Base {
				Member() //This will be accessed as 'member'.
			}
		*/
		if ic.Peek() == "(" {
			if MemberType != Number {
				ic.RaiseError("Unexpected (")
			}
			ic.Scan('(')
			ic.Scan(')')
			var ok bool
			MemberType, ok = ic.DefinedTypes[ident]
			if !ok {
				ident := inflector.Singularize(ident)
				MemberType, ok = ic.DefinedTypes[ident]
				MemberType.List = true
				MemberType.User = false
				if !ok {
					ic.RaiseError("No such type! ", ident)
				}
			}
			ident = strings.ToLower(ident)
		}

		if ident != "\n" {
			t.Detail.Elements = append(t.Detail.Elements, MemberType)
			t.Detail.Table[ident] = len(t.Detail.Elements)-1
		}

	}
	ic.DefinedTypes[name] = t

	ic.LastDefinedType = t
}

func (ic *Compiler) NewListOf(t Type) string {
	t.List = true
	t.User = false
	ic.ExpressionType = t
	var list = ic.Tmp("list")
	ic.Assembly("ARRAY ", list)
	return list
}

func (ic *Compiler) ScanList() string {
	var name = ic.Scan(Name)

	t, ok := ic.DefinedTypes[name]
	if !ok {
		if i, ok := ic.DefinedInterfaces[name]; !ok {
			ic.RaiseError(name+" is an unrecognised type!")
		} else {
			t = i.GetType()
		}
	}
	t.List = true
	t.User = false

	var list = ic.Tmp("list")

	ic.Scan('(')
	if tok := ic.Scan(0); tok != "s" {
		ic.NextToken = tok
		size := ic.ScanExpression()
		if ic.ExpressionType != Number {
			ic.RaiseError("Expecting list size!")
		}
		ic.Assembly("PUSH ", size)
		ic.Assembly("MAKE")
		ic.Assembly("GRAB ", list)
	} else {
		ic.Assembly("ARRAY ", list)
	}
	ic.Scan(')')

	ic.ExpressionType = t

	return list
}

//This scans a type literal.
// eg.
/*
	type Object {value}

	software { var o = Object{22} }
*/
func (ic *Compiler) ScanTypeLiteral() string {
	return ic.ScanConstructor()
}

func (ic *Compiler) ScanConstructor() string {
	var name = ic.Scan(Name)

	if _, ok := ic.DefinedTypes[name]; !ok {
		ic.RaiseError(name+" is an unrecognised type!")
	}

	var token = ic.Scan(0)

	/*if ic.Peek() == ")" && token == "(" {
		ic.ExpressionType = InFunction
		ic.NextToken = "("
		return name
	}*/

	var array = ic.Tmp("constructor")

	ic.Assembly("ARRAY ", array)
	//This is effectively a constructor.
	if token == "{" {
		var i int
		for {

			var expr = ic.ScanExpression()
			ic.Assembly("PLACE ", array)
			if ic.ExpressionType.Push == "PUSH" {
				ic.Assembly("PUT %v", expr)
			} else {
				var tmp = ic.Tmp("heap")
				ic.Assembly(ic.ExpressionType.Push," ", expr)
				ic.Assembly("PUSH 0")
				if ic.ExpressionType.Push == "RELAY" {
					ic.Assembly("HEAPIT")
				} else {
					ic.Assembly("HEAP")
				}
				ic.Assembly("PULL ", tmp)
				ic.Assembly("PUT ", tmp)
			}
			if i >= len(ic.DefinedTypes[name].Detail.Elements) {
				ic.RaiseError("Too many arguments passed to constructor!")
			}
			if ic.ExpressionType != ic.DefinedTypes[name].Detail.Elements[i] {
				ic.RaiseError("Mismatched types! Argument (%v) of constructor should be '%v'", i+1,
					ic.DefinedTypes[name].Detail.Elements[i])
			}
			token = ic.Scan(0)
			for token == "\n" {
				token = ic.Scan(0)
			}
			if token == "}" {
				break
			} else if token != "," {
				ic.Expecting(",")
			}
			i++
		}
		for j := range ic.DefinedTypes[name].Detail.Elements {
			if j > i {
				ic.Assembly("PUT 0")
			}
		}
	} else if token == "\n" || token == ")" {
		for range ic.DefinedTypes[name].Detail.Elements {
			ic.Assembly("PUT 0")
		}
		if token == ")" {
			ic.NextToken = ")"
		}
	} else {
		ic.RaiseError()
	}
	ic.ExpressionType = ic.DefinedTypes[name]
	return array
}

func (ic *Compiler) IndexUserType(name, element string) string {
	var t UserType
	if ic.GetVariable(name) != Undefined {
		t = *ic.GetVariable(name).Detail
		ic.SetVariable(name+"_use", Used)
	} else {
		t = *ic.ExpressionType.Detail
	}

	//Deal with indexing Something types.
	/*if GetVariable(name) == SOMETHING {
		switch element {
			case "number":
				ExpressionType = NUMBER
				fmt.Fprintf(output, "PLACE %s\n", name)
				fmt.Fprintf(output, "PUSH 0\n")
				fmt.Fprintf(output, "GET %s%v\n", "i+user+", unique)
				return "i+user+"+fmt.Sprint(unique)
		}
	}*/

	if index, ok := t.Table[element]; !ok {
		ic.RaiseError(name+" does not have an element named "+element)
	} else {

		var tmp = ic.Tmp("index")
		ic.ExpressionType = t.Elements[index]

		switch t.Elements[index].Push {
			case "PUSH":
				ic.Assembly("PLACE ", name)
				ic.Assembly("PUSH ", index)
				ic.Assembly("GET ", tmp)
				return tmp

			case "SHARE", "RELAY":
				ic.Assembly("PLACE ", name) //The array we are indexing, the place.
				ic.Assembly("PUSH ", index) //Push the index onto the stack.
				ic.Assembly("GET ", tmp)	//Get the value of the array at the index on the stack.
				ic.Assembly("IF ",tmp)		//If there is a valid address, (greater than zero)
				ic.GainScope()

				//Retrieve the array.
				ic.Assembly("PUSH ", tmp)
				if t.Elements[index].Push == "RELAY" {
					ic.Assembly("HEAPIT")
				} else {
					ic.Assembly("HEAP")
				}
				tmp = ic.Tmp("index")
				ic.Assembly(t.Elements[index].Pop, " ", tmp)
				ic.Assembly(t.Elements[index].Push, " ", tmp)
				ic.LoseScope()

				ic.Assembly("ELSE") //We will return a new array.
				ic.GainScope()
				ic.Assembly("ARRAY ", tmp)
				if t.Elements[index].User {
				for range t.Elements[index].Detail.Elements {
					ic.Assembly("PUT 0")
				}
				}
				ic.Assembly("SHARE ", tmp)
				if t.Elements[index].Push == "RELAY" {
					ic.Assembly("OPEN")
				}
				ic.LoseScope()
				ic.Assembly("END")
				ic.Assembly(t.Elements[index].Pop, " ", tmp)

				return tmp

			default:
				ic.RaiseError(name+" cannot index "+element+", type is unindexable!!!")
		}
	}
	return ""
}

func (ic *Compiler) SetUserType(name, element, value string) {
	var t UserType
	if ic.GetVariable(name) != Undefined {
		t = *ic.GetVariable(name).Detail
		ic.SetVariable(name+"_use", Used)
	} else {
		ic.RaiseError("Cannot set type without type identity!")
	}

	if index, ok := t.Table[element]; !ok {
		ic.RaiseError(name+" does not have an element named "+element)
	} else {

		if t.Elements[index] == User || (t.Elements[index].List && ic.ExpressionType.Push == "SHARE") || ic.ExpressionType.Name == "matrix" {
			t.Elements[index] = ic.ExpressionType

			if  ic.GetFlag(InMethod) {
				ic.Assembly("PLACE ", value)
				ic.Assembly("RENAME ", element)
				//ic.SetVariable(element, ic.ExpressionType)
			}
		}

		if ic.ExpressionType != t.Elements[index] {
			ic.RaiseError("Type mismatch, cannot assign '",ic.ExpressionType.Name,"', to a element of type '",t.Elements[index].Name,"'")
		}

		switch t.Elements[index].Push {
			case "PUSH":
				ic.Assembly("PLACE ", name)
				ic.Assembly("PUSH ", index)
				ic.Assembly("SET ", value)

			case "SHARE", "RELAY":

				//TODO garbage collect
				var tmp = ic.Tmp("index")
				ic.Assembly(t.Elements[index].Push, " ", value)
				ic.Assembly("PUSH 0")
				if t.Elements[index].Push == "RELAY" {
					ic.Assembly("HEAPIT")
				} else {
					ic.Assembly("HEAP")
				}
				ic.Assembly("PULL ", tmp)

				ic.Assembly("PLACE ", name)
				ic.Assembly("PUSH ", index)
				ic.Assembly("SET ", tmp)

			default:
				ic.RaiseError(name+" cannot index "+element+", type is unindexable!!!")
		}
	}
}
<|endoftext|>