<commit_before>package storage

import (
	"database/sql"
	"io/ioutil"
	"os"
	"testing"

    "github.com/endophage/gotuf/data"
	"github.com/jinzhu/gorm"
	_ "github.com/mattn/go-sqlite3"
	"github.com/stretchr/testify/assert"
)

// GormTUFFile represents a TUF file in the database
type GormTUFFile struct {
	ID      int    `sql:"AUTO_INCREMENT" gorm:"primary_key"`
	Gun     string `sql:"type:varchar(255);not null"`
	Role    string `sql:"type:varchar(255);not null"`
	Version int
	Data    []byte `sql:"type:longblob"`
}

// TableName sets a specific table name for GormTUFFile
func (g GormTUFFile) TableName() string {
	return "tuf_files"
}

// GormTimestampKey represents a single timestamp key in the database
type GormTimestampKey struct {
	Gun    string `sql:"type:varchar(255)" gorm:"primary key"`
	Cipher string `sql:"type:varchar(30)"`
	Public []byte `sql:"type:blob;not null"`
}

// TableName sets a specific table name for our GormTimestampKey
func (g GormTimestampKey) TableName() string {
	return "timestamp_keys"
}

// SetUpSQLite creates a sqlite database for testing
func SetUpSQLite(t *testing.T) (*gorm.DB, *MySQLStorage) {
	tempBaseDir, err := ioutil.TempDir("", "notary-test-")
	defer os.RemoveAll(tempBaseDir)

	// We are using SQLite for the tests
	db, err := sql.Open("sqlite3", tempBaseDir+"test_db")
	assert.NoError(t, err)

	// Create the DB tables
	gormDB, _ := gorm.Open("sqlite3", db)
	query := gormDB.CreateTable(&GormTUFFile{})
	assert.NoError(t, query.Error)
	query = gormDB.Model(&GormTUFFile{}).AddUniqueIndex(
		"idx_gun", "gun", "role", "version")
	assert.NoError(t, query.Error)
	query = gormDB.CreateTable(&GormTimestampKey{})
	assert.NoError(t, query.Error)

	return &gormDB, NewMySQLStorage(db)
}

func TestMySQLUpdateCurrent(t *testing.T) {
	_, dbStore := SetUpSQLite(t)

	update := MetaUpdate{
		Role:    "root",
		Version: 0,
		Data:    []byte("1"),
	}
	err := dbStore.UpdateCurrent("testGUN", update)
	assert.NoError(t, err, "Creating a row in an empty DB failed.")

    err = dbStore.UpdateCurrent("testGUN", update)
	assert.Error(t, err, "Error should not be nil")
    assert.IsType(t, &ErrOldVersion{}, err,
                  "Expected ErrOldVersion error type, got: %v", err)
    dbStore.DB.Close()
}

func TestMySQLUpdateMany(t *testing.T) {
    _, dbStore := SetUpSQLite(t)

	update1 := MetaUpdate{
		Role:    "root",
		Version: 0,
		Data:    []byte("1"),
	}
	update2 := MetaUpdate{
		Role:    "targets",
		Version: 1,
		Data:    []byte("2"),
	}

    err := dbStore.UpdateMany("testGUN", []MetaUpdate{update1, update2})
    assert.NoError(t, err, "UpdateMany errored unexpectedly: %v", err)
    dbStore.DB.Close()
}

func TestMySQLUpdateManyDuplicateRollback(t *testing.T) {
    _, dbStore := SetUpSQLite(t)

    update := MetaUpdate{
        Role:    "root",
        Version: 0,
        Data:    []byte("1"),
    }

    err := dbStore.UpdateMany("testGUN", []MetaUpdate{update, update})
    assert.Error(t, err, "There should be an error updating twice.")
    // sqlite3 error and mysql error aren't compatible
    // assert.IsType(t, &ErrOldVersion{}, err,
    //               "UpdateMany returned wrong error type")

    // the whole transaction should have rolled back, so there should be
    // no entries.
    byt, err := dbStore.GetCurrent("testGUN", "root")
    assert.Nil(t, byt)
    assert.Error(t, err, "There should be an error Getting any entries")
    assert.IsType(t, &ErrNotFound{}, err, "Should get a not found error")

    dbStore.DB.Close()
}

func TestMySQLGetCurrent(t *testing.T) {
    _, dbStore := SetUpSQLite(t)

    byt, err := dbStore.GetCurrent("testGUN", "root")
    assert.Nil(t, byt)
    assert.Error(t, err, "There should be an error Getting an empty table")
    assert.IsType(t, &ErrNotFound{}, err, "Should get a not found error")

    // use UpdateCurrent to create one and test GetCurrent
    update := MetaUpdate{
        Role:    "root",
        Version: 0,
        Data:    []byte("1"),
    }
    err = dbStore.UpdateCurrent("testGUN", update)
    assert.NoError(t, err, "Creating a row in an empty DB failed.")

    byt, err = dbStore.GetCurrent("testGUN", "root")
    assert.NoError(t, err, "There should not be any errors getting.")
	assert.Equal(t, []byte("1"), byt, "Returned data was incorrect")

    dbStore.DB.Close()
}

func TestMySQLDelete(t *testing.T) {
    _, dbStore := SetUpSQLite(t)

    // Not testing deleting from an empty table, because that's not an error
    // in SQLite3

    // use UpdateCurrent to create one and test GetCurrent
    update := MetaUpdate{
        Role:    "root",
        Version: 0,
        Data:    []byte("1"),
    }
    err := dbStore.UpdateCurrent("testGUN", update)
    assert.NoError(t, err, "Creating a row in an empty DB failed.")

    err = dbStore.Delete("testGUN")
    assert.NoError(t, err, "There should not be any errors deleting.")

    dbStore.DB.Close()
}

func TestMySQLGetTimestampKeyNoKey(t *testing.T) {
    _, dbStore := SetUpSQLite(t)

    cipher, public, err := dbStore.GetTimestampKey("testGUN")
    assert.Equal(t, data.KeyAlgorithm(""), cipher)
    assert.Nil(t, public)
    assert.IsType(t, &ErrNoKey{}, err,
                  "Expected ErrNoKey from GetTimestampKey")

    err = dbStore.SetTimestampKey("testGUN", "testCipher", []byte("1"))
    assert.NoError(t, err, "Inserting timestamp into empty DB should succeed")

    cipher, public, err = dbStore.GetTimestampKey("testGUN")
    assert.Equal(t, data.KeyAlgorithm("testCipher"), cipher,
                 "Returned cipher was incorrect")
    assert.Equal(t, []byte("1"), public, "Returned pubkey was incorrect")
}

func TestMySQLSetTimestampKeyExists(t *testing.T) {
    _, dbStore := SetUpSQLite(t)

    err := dbStore.SetTimestampKey("testGUN", "testCipher", []byte("1"))
    assert.NoError(t, err, "Inserting timestamp into empty DB should succeed")

    err = dbStore.SetTimestampKey("testGUN", "testCipher", []byte("1"))
    // sqlite3 error and mysql error aren't compatible

    // assert.IsType(t, &ErrTimestampKeyExists{}, err,
    //               "Expected ErrTimestampKeyExists from SetTimestampKey")

    dbStore.DB.Close()
}
<commit_msg>Do more verifications on the server store DB tests using gorm<commit_after>package storage

import (
	"database/sql"
	"io/ioutil"
	"os"
	"testing"

	"github.com/endophage/gotuf/data"
	"github.com/jinzhu/gorm"
	_ "github.com/mattn/go-sqlite3"
	"github.com/stretchr/testify/assert"
)

// GormTUFFile represents a TUF file in the database
type GormTUFFile struct {
	ID      int    `sql:"AUTO_INCREMENT" gorm:"primary_key"`
	Gun     string `sql:"type:varchar(255);not null"`
	Role    string `sql:"type:varchar(255);not null"`
	Version int
	Data    []byte `sql:"type:longblob"`
}

// TableName sets a specific table name for GormTUFFile
func (g GormTUFFile) TableName() string {
	return "tuf_files"
}

// GormTimestampKey represents a single timestamp key in the database
type GormTimestampKey struct {
	Gun    string `sql:"type:varchar(255);unique" gorm:"primary key"`
	Cipher string `sql:"type:varchar(30)"`
	Public []byte `sql:"type:blob;not null"`
}

// TableName sets a specific table name for our GormTimestampKey
func (g GormTimestampKey) TableName() string {
	return "timestamp_keys"
}

// SetUpSQLite creates a sqlite database for testing
func SetUpSQLite(t *testing.T) (*gorm.DB, *MySQLStorage) {
	tempBaseDir, err := ioutil.TempDir("", "notary-test-")
	defer os.RemoveAll(tempBaseDir)

	// We are using SQLite for the tests
	db, err := sql.Open("sqlite3", tempBaseDir+"test_db")
	assert.NoError(t, err)

	// Create the DB tables
	gormDB, _ := gorm.Open("sqlite3", db)
	query := gormDB.CreateTable(&GormTUFFile{})
	assert.NoError(t, query.Error)
	query = gormDB.Model(&GormTUFFile{}).AddUniqueIndex(
		"idx_gun", "gun", "role", "version")
	assert.NoError(t, query.Error)
	query = gormDB.CreateTable(&GormTimestampKey{})
	assert.NoError(t, query.Error)

	// verify that the tables are empty
	var count int
	for _, model := range [2]interface{}{&GormTUFFile{}, &GormTimestampKey{}} {
		query = gormDB.Model(model).Count(&count)
		assert.NoError(t, query.Error)
		assert.Equal(t, 0, count)
	}

	return &gormDB, NewMySQLStorage(db)
}

func TestMySQLUpdateCurrent(t *testing.T) {
	gormDB, dbStore := SetUpSQLite(t)

    // UpdateCurrent should succeed
	update := MetaUpdate{
		Role:    "root",
		Version: 0,
		Data:    []byte("1"),
	}
	err := dbStore.UpdateCurrent("testGUN", update)
	assert.NoError(t, err, "Creating a row in an empty DB failed.")

    // There should just be one row
    var rows []GormTUFFile
    query := gormDB.Model(&GormTUFFile{}).Find(&rows)
    assert.NoError(t, query.Error)
    assert.Equal(
        t,
        []GormTUFFile{
            GormTUFFile{ID: 1, Gun: "testGUN", Role: "root", Version: 0,
                Data: []byte("1")},
        },
        rows)

	dbStore.DB.Close()
}

func TestMySQLUpdateCurrentError(t *testing.T) {
    gormDB, dbStore := SetUpSQLite(t)

    // insert row
    query := gormDB.Create(&GormTUFFile{
        Gun:     "testGUN",
        Role:    "root",
        Version: 0,
        Data:    []byte("1"),
    })
    assert.NoError(t, query.Error, "Creating a row in an empty DB failed.")

    // UpdateCurrent should fail due to clash with prevoius row
    update := MetaUpdate{
        Role:    "root",
        Version: 0,
        Data:    []byte("1"),
    }
    err := dbStore.UpdateCurrent("testGUN", update)
    assert.Error(t, err, "Error should not be nil")
    assert.IsType(t, &ErrOldVersion{}, err,
        "Expected ErrOldVersion error type, got: %v", err)

    // There should just be one row
    var rows []GormTUFFile
    query = gormDB.Model(&GormTUFFile{}).Find(&rows)
    assert.NoError(t, query.Error)
    assert.Equal(
        t,
        []GormTUFFile{
            GormTUFFile{ID: 1, Gun: "testGUN", Role: "root", Version: 0,
                Data: []byte("1")},
        },
        rows)

    dbStore.DB.Close()
}

func TestMySQLUpdateMany(t *testing.T) {
	gormDB, dbStore := SetUpSQLite(t)

	update1 := MetaUpdate{
		Role:    "root",
		Version: 0,
		Data:    []byte("1"),
	}
	update2 := MetaUpdate{
		Role:    "targets",
		Version: 1,
		Data:    []byte("2"),
	}

	expected := []GormTUFFile{
		GormTUFFile{ID: 1, Gun: "testGUN", Role: "root", Version: 0,
			Data: []byte("1")},
		GormTUFFile{ID: 2, Gun: "testGUN", Role: "targets", Version: 1,
			Data: []byte("2")},
	}

	err := dbStore.UpdateMany("testGUN", []MetaUpdate{update1, update2})
	assert.NoError(t, err, "UpdateMany errored unexpectedly: %v", err)

	var rows []GormTUFFile
	query := gormDB.Model(&GormTUFFile{}).Find(&rows)
	assert.NoError(t, query.Error)
	assert.Equal(t, 2, len(rows))
	assert.Equal(t, expected, rows)

	dbStore.DB.Close()
}

func TestMySQLUpdateManyDuplicateRollback(t *testing.T) {
	gormDB, dbStore := SetUpSQLite(t)

	update := MetaUpdate{
		Role:    "root",
		Version: 0,
		Data:    []byte("1"),
	}

	err := dbStore.UpdateMany("testGUN", []MetaUpdate{update, update})
	assert.Error(t, err, "There should be an error updating twice.")
	// sqlite3 error and mysql error aren't compatible
	// assert.IsType(t, &ErrOldVersion{}, err,
	//               "UpdateMany returned wrong error type")

	// the whole transaction should have rolled back, so there should be
	// no entries.
	var count int
	query := gormDB.Model(&GormTUFFile{}).Count(&count)
	assert.NoError(t, query.Error)
	assert.Equal(t, 0, count)

	dbStore.DB.Close()
}

func TestMySQLGetCurrent(t *testing.T) {
	gormDB, dbStore := SetUpSQLite(t)

	byt, err := dbStore.GetCurrent("testGUN", "root")
	assert.Nil(t, byt)
	assert.Error(t, err, "There should be an error Getting an empty table")
	assert.IsType(t, &ErrNotFound{}, err, "Should get a not found error")

	query := gormDB.Create(&GormTUFFile{
		Gun:     "testGUN",
		Role:    "root",
		Version: 0,
		Data:    []byte("1"),
	})
	assert.NoError(t, query.Error, "Creating a row in an empty DB failed.")

	byt, err = dbStore.GetCurrent("testGUN", "root")
	assert.NoError(t, err, "There should not be any errors getting.")
	assert.Equal(t, []byte("1"), byt, "Returned data was incorrect")

	dbStore.DB.Close()
}

func TestMySQLDelete(t *testing.T) {
	gormDB, dbStore := SetUpSQLite(t)

	// Not testing deleting from an empty table, because that's not an error
	// in SQLite3

	// use UpdateCurrent to create one and test GetCurrent
	query := gormDB.Create(&GormTUFFile{
		Gun:     "testGUN",
		Role:    "root",
		Version: 0,
		Data:    []byte("1"),
	})
	assert.NoError(t, query.Error, "Creating a row in an empty DB failed.")

	err := dbStore.Delete("testGUN")
	assert.NoError(t, err, "There should not be any errors deleting.")

	// verify deletion
	var count int
	query = gormDB.Model(&GormTUFFile{}).Count(&count)
	assert.NoError(t, query.Error)
	assert.Equal(t, 0, count)

	dbStore.DB.Close()
}

func TestMySQLGetTimestampKeyNoKey(t *testing.T) {
	gormDB, dbStore := SetUpSQLite(t)

	cipher, public, err := dbStore.GetTimestampKey("testGUN")
	assert.Equal(t, data.KeyAlgorithm(""), cipher)
	assert.Nil(t, public)
	assert.IsType(t, &ErrNoKey{}, err,
		"Expected ErrNoKey from GetTimestampKey")

	query := gormDB.Create(&GormTimestampKey{
		Gun:    "testGUN",
		Cipher: "testCipher",
		Public: []byte("1"),
	})
	assert.NoError(
		t, query.Error, "Inserting timestamp into empty DB should succeed")

	cipher, public, err = dbStore.GetTimestampKey("testGUN")
	assert.Equal(t, data.KeyAlgorithm("testCipher"), cipher,
		"Returned cipher was incorrect")
	assert.Equal(t, []byte("1"), public, "Returned pubkey was incorrect")
}

func TestMySQLSetTimestampKeyExists(t *testing.T) {
	gormDB, dbStore := SetUpSQLite(t)

	err := dbStore.SetTimestampKey("testGUN", "testCipher", []byte("1"))
	assert.NoError(t, err, "Inserting timestamp into empty DB should succeed")

	err = dbStore.SetTimestampKey("testGUN", "testCipher", []byte("1"))
	assert.Error(t, err)
	// sqlite3 error and mysql error aren't compatible

	// assert.IsType(t, &ErrTimestampKeyExists{}, err,
	//               "Expected ErrTimestampKeyExists from SetTimestampKey")

	var rows []GormTimestampKey
	query := gormDB.Model(&GormTimestampKey{}).Find(&rows)
	assert.NoError(t, query.Error)
	assert.Equal(t, 1, len(rows))
	assert.Equal(
		t,
		GormTimestampKey{Gun: "testGUN", Cipher: "testCipher",
			Public: []byte("1")},
		rows[0])

	dbStore.DB.Close()
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"log"
	"net/http"

	cb "github.com/couchbaselabs/go-couchbase"
)

// Take a stream of
func keyClumper(ch chan *namedFile, size int) chan []*namedFile {
	outch := make(chan []*namedFile)
	go func() {
		defer close(outch)
		res := make([]*namedFile, 0, size)
		for r := range ch {
			res = append(res, r)
			if len(res) == size {
				outch <- res
				res = make([]*namedFile, 0, size)
			}
			if len(res) > 0 {
				outch <- res
			}
		}
	}()

	return outch
}

func dofsck(w http.ResponseWriter, req *http.Request,
	path string) {

	errsOnly := req.FormValue("errsonly") != ""

	quit := make(chan bool)
	defer close(quit)
	ch := make(chan *namedFile)
	cherr := make(chan cb.ViewError)

	go pathGenerator(path, ch, cherr, quit)

	go func() {
		for e := range cherr {
			log.Printf("View error: %v", e)
		}
	}()

	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(200)

	e := json.NewEncoder(w)
	type status struct {
		Path  string `json:"path"`
		OID   string `json:"oid,omitempty"`
		Reps  int    `json:"reps,omitempty"`
		EType string `json:"etype,omitempty"`
		Error string `json:"error,omitempty"`
	}

	for nfc := range keyClumper(ch, 1000) {
		keys := []string{}
		fnmap := map[string]string{}
		unprocessed := map[string]string{}

		for _, nf := range nfc {
			if nf.err != nil {
				if err := e.Encode(status{
					Path:  nf.name,
					OID:   nf.meta.OID,
					EType: "file",
					Error: nf.err.Error(),
				}); err != nil {
					log.Printf("Error encoding: %v", err)
					return
				}
			}
			keys = append(keys, "/"+nf.meta.OID)
			unprocessed[nf.name] = nf.meta.OID
			fnmap[nf.meta.OID] = nf.name
		}

		for k, v := range couchbase.GetBulk(keys) {
			name := fnmap[k[1:]]
			delete(unprocessed, name)

			ownership := BlobOwnership{}
			err := json.Unmarshal(v.Body, &ownership)
			if err != nil {
				if err = e.Encode(status{
					Path:  name,
					OID:   k[1:],
					EType: "blob",
					Error: err.Error(),
				}); err != nil {
					log.Printf("Error encoding: %v", err)
					return
				}
			}

			if !errsOnly {
				if err := e.Encode(status{
					Path: name,
					OID:  k[1:],
					Reps: len(ownership.Nodes),
				}); err != nil {
					log.Printf("Error encoding: %v", err)
					return
				}
			}
		}

		for k, v := range unprocessed {
			if err := e.Encode(status{
				Path:  k,
				OID:   v,
				EType: "blob",
				Error: "not found",
			}); err != nil {
				log.Printf("Error encoding: %v", err)
				return
			}
		}
	}
}
<commit_msg>keyclump should send the last clump<commit_after>package main

import (
	"encoding/json"
	"log"
	"net/http"

	cb "github.com/couchbaselabs/go-couchbase"
)

// Take a stream of namedFiles and clump them into batches of at most
// the specified size
func keyClumper(ch chan *namedFile, size int) chan []*namedFile {
	outch := make(chan []*namedFile)
	go func() {
		defer close(outch)
		res := make([]*namedFile, 0, size)
		for r := range ch {
			res = append(res, r)
			if len(res) == size {
				outch <- res
				res = make([]*namedFile, 0, size)
			}
		}
		if len(res) > 0 {
			outch <- res
		}
	}()

	return outch
}

func dofsck(w http.ResponseWriter, req *http.Request,
	path string) {

	errsOnly := req.FormValue("errsonly") != ""

	quit := make(chan bool)
	defer close(quit)
	ch := make(chan *namedFile)
	cherr := make(chan cb.ViewError)

	go pathGenerator(path, ch, cherr, quit)

	go func() {
		for e := range cherr {
			log.Printf("View error: %v", e)
		}
	}()

	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(200)

	e := json.NewEncoder(w)
	type status struct {
		Path  string `json:"path"`
		OID   string `json:"oid,omitempty"`
		Reps  int    `json:"reps,omitempty"`
		EType string `json:"etype,omitempty"`
		Error string `json:"error,omitempty"`
	}

	for nfc := range keyClumper(ch, 1000) {
		keys := []string{}
		fnmap := map[string]string{}
		unprocessed := map[string]string{}

		for _, nf := range nfc {
			if nf.err != nil {
				if err := e.Encode(status{
					Path:  nf.name,
					OID:   nf.meta.OID,
					EType: "file",
					Error: nf.err.Error(),
				}); err != nil {
					log.Printf("Error encoding: %v", err)
					return
				}
			}
			keys = append(keys, "/"+nf.meta.OID)
			unprocessed[nf.name] = nf.meta.OID
			fnmap[nf.meta.OID] = nf.name
		}

		for k, v := range couchbase.GetBulk(keys) {
			name := fnmap[k[1:]]
			delete(unprocessed, name)

			ownership := BlobOwnership{}
			err := json.Unmarshal(v.Body, &ownership)
			if err != nil {
				if err = e.Encode(status{
					Path:  name,
					OID:   k[1:],
					EType: "blob",
					Error: err.Error(),
				}); err != nil {
					log.Printf("Error encoding: %v", err)
					return
				}
			}

			if !errsOnly {
				if err := e.Encode(status{
					Path: name,
					OID:  k[1:],
					Reps: len(ownership.Nodes),
				}); err != nil {
					log.Printf("Error encoding: %v", err)
					return
				}
			}
		}

		for k, v := range unprocessed {
			if err := e.Encode(status{
				Path:  k,
				OID:   v,
				EType: "blob",
				Error: "not found",
			}); err != nil {
				log.Printf("Error encoding: %v", err)
				return
			}
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"
	"os"
	"strings"

	"github.com/linkosmos/gotldmap"
)

func main() {
	file, err := os.Open("input.txt")
	if err != nil {
		panic(err)
	}
	defer file.Close()
	var count int

	for _, position := range gotldmap.Map {
		if position >= count {
			count = position
		}
	}

	scanner := bufio.NewScanner(file)

	fmt.Println("package gotldmap")
	fmt.Println("")
	fmt.Println("// Generated; DO NOT EDIT")
	fmt.Println("")
	fmt.Println("")
	fmt.Println("// Map - map of top level domains with mark key")
	fmt.Println("var Map = map[string]int{")
	for scanner.Scan() {
		count++
		tld := strings.ToLower(scanner.Text())
		if gotldmap.TldExist(tld) {
			tldPos, _ := gotldmap.FindByTld(tld)
			fmt.Printf("\"%s\": %d,\n", tld, tldPos)
		} else {
			fmt.Printf("\"%s\": %d,\n", tld, count)
		}

	}
	fmt.Println("}")
	os.Exit(1)
}
<commit_msg>Generator extract function for finding last mark<commit_after>package main

import (
	"bufio"
	"fmt"
	"os"
	"strings"

	"github.com/linkosmos/gotldmap"
)

func newmark(mark int) int {
	_, err := gotldmap.FindByMark(mark)
	if err == nil {
		mark++
		return newmark(mark)
	}
	return mark
}

func main() {
	file, err := os.Open("input.txt")
	if err != nil {
		panic(err)
	}
	defer file.Close()
	var count int

	count = newmark(1) // Find last mark
	scanner := bufio.NewScanner(file)

	fmt.Println("package gotldmap")
	fmt.Println("")
	fmt.Println("// Generated; DO NOT EDIT")
	fmt.Println("")
	fmt.Println("")
	fmt.Println("// Map - map of top level domains with mark key")
	fmt.Println("var Map = map[string]int{")
	for scanner.Scan() {
		tld := strings.ToLower(scanner.Text())
		if gotldmap.TldExist(tld) {
			tldPos, _ := gotldmap.FindByTld(tld)
			fmt.Printf("\"%s\": %d,\n", tld, tldPos)
		} else {
			fmt.Printf("\"%s\": %d,\n", tld, count)
			count++
		}

	}
	fmt.Println("}")
	os.Exit(1)
}
<|endoftext|>


<commit_before>package hermes

import(
	"testing"
	"strconv"
)

func TestChecksum(t *testing.T){
	global_contents := "jhfvjhdfjhfjjhjhdfvjvcvfjh"
	want := "_68f3caf439065824dcf75651c202e9f7c28ebf07"  //expected checksum result
	file := HermesFile{}
	file.contents =  "jhfvjhdfjhfjjhjhdfvjvcvfjh"
	got := file.GenerateFileChecksum()
	if want != got {
		t.Errorf("GenerateFileChecksum() failed expected %v got %v", want, got)
	}
}

func TestFileName(t *testing.T){
	file := HermesFile{}
	file_id := 23;
	fake_checksum :="_abba"
	want :=  "Hermes_"+strconv.Itoa(file_ID)+"_abba" //expected file name result
	file.GenerateFileName(file_ID, fake_checksum)
	got := file.name
	if got != want {
		t.Errorf("GenerateFileName(%v, \"abba\") failed expected %v got %v", file_ID, want, got)
	}
	file_ID = 4;
	want = "Hermes_0"+strconv.Itoa(file_ID)+"_abba" //expected file name result
	file.GenerateFileName(file_ID, fake_checksum)
	got = file.name
	if got != want {
		t.Errorf("GenerateFileName(%v, \"abba\") failed expected %v got %v", file_ID, want, got)
	}
}
<commit_msg>Update file_gen_test.go<commit_after>package hermes

import(
	"testing"
	"strconv"
)

func TestChecksum(t *testing.T){

	want := "_68f3caf439065824dcf75651c202e9f7c28ebf07"  //expected checksum result
	file := HermesFile{}
	file.contents =  "jhfvjhdfjhfjjhjhdfvjvcvfjh"
	got := file.GenerateFileChecksum()
	if want != got {
		t.Errorf("GenerateFileChecksum() failed expected %v got %v", want, got)
	}
}

func TestFileName(t *testing.T){
	file := HermesFile{}
	file_id := 23;
	fake_checksum :="_abba"
	want :=  "Hermes_"+strconv.Itoa(file_ID)+"_abba" //expected file name result
	file.GenerateFileName(file_ID, fake_checksum)
	got := file.name
	if got != want {
		t.Errorf("GenerateFileName(%v, \"abba\") failed expected %v got %v", file_ID, want, got)
	}
	file_ID = 4;
	want = "Hermes_0"+strconv.Itoa(file_ID)+"_abba" //expected file name result
	file.GenerateFileName(file_ID, fake_checksum)
	got = file.name
	if got != want {
		t.Errorf("GenerateFileName(%v, \"abba\") failed expected %v got %v", file_ID, want, got)
	}
}
<|endoftext|>


<commit_before><commit_msg>Basic structure and grid initialization<commit_after>package main

type cell bool

type grid [][]cell

type game struct {
	Grid grid
}

func newGame() game {
	grid := make(grid, 20)
	for i := range grid {
		grid[i] = make([]cell, len(grid))
	}
	g := game{grid}
	return g
}

func init() {
}

func main() {
}
<|endoftext|>


<commit_before>/*
   Copyright 2013, 2016 Daniel Gruber, info@gridengine.eu

   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions are
   met:

      * Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
      * Redistributions in binary form must reproduce the above
   copyright notice, this list of conditions and the following disclaimer
   in the documentation and/or other materials provided with the
   distribution.

   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

   This module contains Grid Engine specific code for getting much
   more detailed job information than plain DRMAA1 is able to show.
   This is done by parsing the qstat -xml output.
*/

package gestatus

import (
	"github.com/dgruber/drmaa"
	"github.com/dgruber/drmaa/gestatus/private_gestatus"
	"strconv"
	"strings"
	"time"
)

// ClusterJobs contains all jobs found in the cluster.
type ClusterJobs struct {
	jobs []private_gestatus.QstatJob
}

// Job represents the state of a job and its properties.
type Job struct {
	Number    int64
	Priority  float64
	Name      string
	Owner     string
	State     string
	StartTime string
	QueueName string
	JobClass  string
	Slots     int64
}

func convertQstatJobToJob(qsj private_gestatus.QstatJob) (job Job) {
	job.Number = qsj.JB_job_number
	job.Priority = qsj.JAT_prio
	job.Name = qsj.JB_name
	job.Owner = qsj.JB_owner
	job.State = qsj.State
	qsj.JAT_start_time = strings.Replace(qsj.JAT_start_time, "T", "-", 1)
	job.StartTime = qsj.JAT_start_time
	job.QueueName = qsj.Queue_Name
	job.JobClass = qsj.JClass_Name
	job.Slots = qsj.Slots
	return job
}

// GetClusterJobs performs internally a job status call (qstat)
// to the cluster to get more detailed information about the job
// status then what plain DRMAA offers.
func GetClusterJobs() (clusterjobs ClusterJobs, err error) {
	if cjs, err := private_gestatus.GetClusterJobsStatus(); err == nil {
		if cjs.JobList != nil {
			clusterjobs.jobs = cjs.JobList
			return clusterjobs, nil
		} else {
			return clusterjobs, nil
		}
	}
	return clusterjobs, err
}

// AllJobs returns a new slice of jobs found in the cluster by qstat.
func (cjs *ClusterJobs) AllJobs() []Job {
	if cjs.jobs == nil {
		return nil
	}

	jobs := make([]Job, 0)

	for _, j := range cjs.jobs {
		jobs = append(jobs, convertQstatJobToJob(j))
	}

	return jobs
}

// ----------------------------------------------------------------------------

// JobStatus represents fine detailed job status information. It offers
// more details than the Job struct. The information is collected by calling
// qstat -j when using Grid Engine.
type JobStatus struct {
	/* hide internal job status */
	js private_gestatus.InternalJobStatus
}

// GetJob performs qstat -xml -j <jobid> and returns a JobStatus
// object for this job.
func GetJob(jobid string) (jobstat JobStatus, err error) {
	js, err := private_gestatus.GetJobStatusById(jobid)
	if err != nil {
		return jobstat, err
	}
	jobstat.js = js

	return jobstat, nil
}

// GetJobStatus returns the job status object, which contains all information
// about a job. In case of any error it is nil and a drmaa error
// is returned.
func GetJobStatus(session *drmaa.Session, jobId string) (jobstat JobStatus, err error) {
	js, err := private_gestatus.GetJobStatus(session, jobId)
	if err != nil {
		return jobstat, err
	}
	jobstat.js = js

	return jobstat, nil
}

/* Exported access methods for the JobInfo struct */

/* JobName returns the job name (given by -N submission option). */
func (js *JobStatus) JobName() string {
	return private_gestatus.GetJobName(&js.js)
}

/* JobID returns the unique Grid Engine job ID. */
func (js *JobStatus) JobID() int64 {
	return private_gestatus.GetJobNumber(&js.js)
}

/* execFileName is the GE internal script name which is executed on execd side */
func (js *JobStatus) execFileName() string {
	return private_gestatus.GetExecFileName(&js.js)
}

/* JobScript returns the job script name as string. */
func (js *JobStatus) JobScript() string {
	return private_gestatus.GetScriptFile(&js.js)
}

/* JobArgs returns the job arguments as string slice. */
func (js *JobStatus) JobArgs() []string {
	return private_gestatus.GetJobArgs(&js.js)
}

/* JobOwner returns the owner of the job as string. */
func (js *JobStatus) JobOwner() string {
	return private_gestatus.GetOwner(&js.js)
}

/* JobUID returns the ower of the job as Unix UID. */
func (js *JobStatus) JobUID() int {
	return private_gestatus.GetUID(&js.js)
}

// JobGroup returns the primary UNIX group of the job owner as string. */
func (js *JobStatus) JobGroup() string {
	return private_gestatus.GetGroup(&js.js)
}

// JobGID returns the primary UNIX group ID of the job owner as int. */
func (js *JobStatus) JobGID() int {
	return private_gestatus.GetGID(&js.js)
}

// JobAccountName returns the accounting string assigned to the job. /
func (js *JobStatus) JobAccountName() string {
	return private_gestatus.GetAccount(&js.js)
}

// IsImmediateJob returns true in case of an interactive job or a -now y batch job. */
func (js *JobStatus) IsImmediateJob() bool {
	return private_gestatus.IsImmediate(&js.js)
}

// HasReservation return true if the job requested a resource reservation.
func (js *JobStatus) HasReservation() bool {
	return private_gestatus.IsReservation(&js.js)
}

// IsBinaryJob returns the group of the job owner.
func (js *JobStatus) IsBinaryJob() bool {
	return private_gestatus.IsBinary(&js.js)
}

// HasNoShell returns true if the job had requested -shell no.
func (js *JobStatus) HasNoShell() bool {
	return private_gestatus.IsNoShell(&js.js)
}

// IsArrayJob returns true in case the job is an array job.
func (js *JobStatus) IsArrayJob() bool {
	return private_gestatus.IsArray(&js.js)
}

/* JobMergesStderr returns true if job merges stderr to stdout. */
func (js *JobStatus) JobMergesStderr() bool {
	return private_gestatus.IsMergeStderr(&js.js)
}

/* HasMemoryBinding returns true in case the job has memory binding requested. */
func (js *JobStatus) HasMemoryBinding() bool {
	if private_gestatus.GetMbind(&js.js) == "no_bind" {
		return false
	}
	return true
}

/* MemoryBinding returns the status of the actual memory binding done for the processes of the job. */
func (js *JobStatus) MemoryBinding() string {
	return private_gestatus.GetMbind(&js.js)
}

/* StartTime is when the job was dispatched to the execution host in order to start up the processes. */
func (js *JobStatus) StartTime() time.Time {
	return private_gestatus.GetStartTime(&js.js)
}

/* RunTime return since how long is the job running. Note that the run-time is dynamically
 * calculated assuming that the start time stamp in the cluster is in the same time zone
 * then the actual RunTime() call. */
func (js *JobStatus) RunTime() time.Duration {
	if js.StartTime().Unix() != 0 {
		return time.Since(js.StartTime())
	}
	d, _ := time.ParseDuration("0s")
	return d
}

/* TaskStartTime is the start time of a specific task of the job (for array jobs). */
func (js *JobStatus) TaskStartTime(taskId int) time.Time {
	return private_gestatus.GetTaskStartTime(&js.js, taskId)
}

/* executionTime is the end time of the job. */
func (js *JobStatus) executionTime() time.Time {
	return private_gestatus.GetExecutionTime(&js.js)
}

/* Submission time is the time when the job was submitted to the cluster. */
func (js *JobStatus) SubmissionTime() time.Time {
	return private_gestatus.GetSubmissionTime(&js.js)
}

/* JobDeadline returns if the job has set a deadline for starting up. */
func (js *JobStatus) JobDeadline() time.Time {
	return private_gestatus.GetDeadline(&js.js)
}

// PosixPriority returns the POSIX priority the job has requested.
// The default priority for the POSIX policy is 0 ranging from -1023
// till 1024. Only adminstrators can set a positive priority.
func (js *JobStatus) PosixPriority() int {
	// priority is returned as positiv integer 1024 for 0
	return private_gestatus.GetPosixPriority(&js.js) - 1024
}

// MailOptions returns the mail options which determines on which event
// emails about job status change is sent.
func (js *JobStatus) MailOptions() string {
	return private_gestatus.GetMailOptions(&js.js)
}

// AdvanceReservationID returns the ID of the advance reservation the
// job is running in. Note that this ID has no relationship to the
// job IDs.
func (js *JobStatus) AdvanceReservationID() int {
	return private_gestatus.GetAR(&js.js)
}

// JobClassName returns the name of the requested job class.
func (js *JobStatus) JobClassName() string {
	return private_gestatus.GetJobClassName(&js.js)
}

// MailAdresses returns all mail addresses the job is sending
// information about its state.
func (js *JobStatus) MailAdresses() []string {
	return private_gestatus.GetMailingAdresses(&js.js)
}

// HardRequests returns hard resource requests as name and value
// pairs. Names are the first slice the values are encoded in the
// second slice. TODO make a map of it...
func (js *JobStatus) HardRequests() ([]string, []string) {
	return private_gestatus.GetHardRequests(&js.js)
}

func (js *JobStatus) gdilQueueNames(what string, task int) []string {
	qil := make([]string, 16)

	gdil := private_gestatus.GetGDIL(&js.js, task)

	if gdil == nil {
		return nil
	}
	for i := range *gdil {
		if what == "QueueName" {
			qil = append(qil, (*gdil)[i].QueueName)
		} else if what == "HostName" {
			qi := strings.Split((*gdil)[i].QueueName, "@")
			if len(qi) == 2 {
				qil = append(qil, qi[1])
			}
		} else if what == "Slots" {
			qil = append(qil, strconv.Itoa((*gdil)[i].Slots))
		}
	}

	return qil
}

// DestinationQueueInstanceList returns all queue instance names where the job is running.
// A queue instance contains a host and a "@" queue part, where the job is scheduled to.
func (js *JobStatus) DestinationQueueInstanceList() []string {
	return js.gdilQueueNames("QueueName", 0)
}

// DestinationQueueInstanceListOfTask returns the queue instances of a particular
// array job task.
func (js *JobStatus) DestinationQueueInstanceListOfTask(task int) []string {
	return js.gdilQueueNames("QueueName", task)
}

// DestinationSlotsList returns a list of slots used on the queue instances.
func (js *JobStatus) DestinationSlotsList() []string {
	return js.gdilQueueNames("Slots", 0)
}

// DestinationHostList returns all host names where the job (the first task
// in case of array jobs) is running.
func (js *JobStatus) DestinationHostList() []string {
	return js.gdilQueueNames("HostName", 0)
}

// DestinationHostListOfTask returns all hosts a parallel array job
// task is running on.
func (js *JobStatus) DestinationHostListOfTask(task int) []string {
	return js.gdilQueueNames("HostName", task)
}

// TasksCount retursn the amount of array job tasks an
// job array consists of.
func (js *JobStatus) TasksCount() int {
	return private_gestatus.GetTaskCount(&js.js)
}

// ParallelEnvironment returns the name of the parallel environment
// requested by a job.
func (js *JobStatus) ParallelEnvironment() string {
	return private_gestatus.GetParallelEnvironmentRequest(&js.js)
}

// ParallelEnvironmentMin contains the amount of slots requested
// by a parallel jobs.
func (js *JobStatus) ParallelEnvironmentMin() int64 {
	return private_gestatus.GetParallelEnvironmentMin(&js.js)
}

// ParallelEnvironmentMax returns the maximum amount of slots
// required by the parallel job. It is equal to ParallelEnvironmentMin()
// in case of a fixed amount of slots were requested (which is
// the standard case).
func (js *JobStatus) ParallelEnvironmentMax() int64 {
	return private_gestatus.GetParallelEnvironmentMax(&js.js)
}

// ParallelEnvironmentStep is the step size of a slot range
// request of a parallel job.
func (js *JobStatus) ParallelEnvironmentStep() int64 {
	return private_gestatus.GetParallelEnvironmentStep(&js.js)
}

// ResourceUsage returns the measurements of resource consumption
// by the processes of a job.
func (js *JobStatus) ResourceUsage(task int) ([]string, []string) {
	return private_gestatus.GetUsageList(&js.js, task)
}
<commit_msg>DG: cleanup<commit_after>/*
   Copyright 2013, 2016 Daniel Gruber, info@gridengine.eu

   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions are
   met:

      * Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
      * Redistributions in binary form must reproduce the above
   copyright notice, this list of conditions and the following disclaimer
   in the documentation and/or other materials provided with the
   distribution.

   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

   This module contains Grid Engine specific code for getting much
   more detailed job information than plain DRMAA1 is able to show.
   This is done by parsing the qstat -xml output.
*/

package gestatus

import (
	"github.com/dgruber/drmaa"
	"github.com/dgruber/drmaa/gestatus/private_gestatus"
	"strconv"
	"strings"
	"time"
)

// ClusterJobs contains all jobs found in the cluster.
type ClusterJobs struct {
	jobs []private_gestatus.QstatJob
}

// Job represents the state of a job and its properties.
type Job struct {
	Number    int64
	Priority  float64
	Name      string
	Owner     string
	State     string
	StartTime string
	QueueName string
	JobClass  string
	Slots     int64
}

func convertQstatJobToJob(qsj private_gestatus.QstatJob) (job Job) {
	job.Number = qsj.JB_job_number
	job.Priority = qsj.JAT_prio
	job.Name = qsj.JB_name
	job.Owner = qsj.JB_owner
	job.State = qsj.State
	qsj.JAT_start_time = strings.Replace(qsj.JAT_start_time, "T", "-", 1)
	job.StartTime = qsj.JAT_start_time
	job.QueueName = qsj.Queue_Name
	job.JobClass = qsj.JClass_Name
	job.Slots = qsj.Slots
	return job
}

// GetClusterJobs performs internally a job status call (qstat)
// to the cluster to get more detailed information about the job
// status then what plain DRMAA offers.
func GetClusterJobs() (clusterjobs ClusterJobs, err error) {
	if cjs, err := private_gestatus.GetClusterJobsStatus(); err == nil {
		if cjs.JobList != nil {
			clusterjobs.jobs = cjs.JobList
		}
		return clusterjobs, nil
	}
	return clusterjobs, err
}

// AllJobs returns a new slice of jobs found in the cluster by qstat.
func (cjs *ClusterJobs) AllJobs() []Job {
	if cjs.jobs == nil {
		return nil
	}

	jobs := make([]Job, 0, len(cjs.jobs))

	for _, j := range cjs.jobs {
		jobs = append(jobs, convertQstatJobToJob(j))
	}

	return jobs
}

// ----------------------------------------------------------------------------

// JobStatus represents fine detailed job status information. It offers
// more details than the Job struct. The information is collected by calling
// qstat -j when using Grid Engine.
type JobStatus struct {
	/* hide internal job status */
	js private_gestatus.InternalJobStatus
}

// GetJob performs qstat -xml -j <jobid> and returns a JobStatus
// object for this job.
func GetJob(jobid string) (jobstat JobStatus, err error) {
	js, err := private_gestatus.GetJobStatusById(jobid)
	if err != nil {
		return jobstat, err
	}
	jobstat.js = js

	return jobstat, nil
}

// GetJobStatus returns the job status object, which contains all information
// about a job. In case of any error it is nil and a drmaa error
// is returned.
func GetJobStatus(session *drmaa.Session, jobID string) (jobstat JobStatus, err error) {
	js, err := private_gestatus.GetJobStatus(session, jobID)
	if err != nil {
		return jobstat, err
	}
	jobstat.js = js

	return jobstat, nil
}

/* Exported access methods for the JobInfo struct */

// JobName returns the job name (given by -N submission option).
func (js *JobStatus) JobName() string {
	return private_gestatus.GetJobName(&js.js)
}

// JobID returns the unique Grid Engine job ID.
func (js *JobStatus) JobID() int64 {
	return private_gestatus.GetJobNumber(&js.js)
}

// execFileName is the GE internal script name which is executed on execd side
func (js *JobStatus) execFileName() string {
	return private_gestatus.GetExecFileName(&js.js)
}

// JobScript returns the job script name as string.
func (js *JobStatus) JobScript() string {
	return private_gestatus.GetScriptFile(&js.js)
}

// JobArgs returns the job arguments as string slice.
func (js *JobStatus) JobArgs() []string {
	return private_gestatus.GetJobArgs(&js.js)
}

// JobOwner returns the owner of the job as string.
func (js *JobStatus) JobOwner() string {
	return private_gestatus.GetOwner(&js.js)
}

// JobUID returns the ower of the job as Unix UID.
func (js *JobStatus) JobUID() int {
	return private_gestatus.GetUID(&js.js)
}

// JobGroup returns the primary UNIX group of the job owner as string.
func (js *JobStatus) JobGroup() string {
	return private_gestatus.GetGroup(&js.js)
}

// JobGID returns the primary UNIX group ID of the job owner as int.
func (js *JobStatus) JobGID() int {
	return private_gestatus.GetGID(&js.js)
}

// JobAccountName returns the accounting string assigned to the job.
func (js *JobStatus) JobAccountName() string {
	return private_gestatus.GetAccount(&js.js)
}

// IsImmediateJob returns true in case of an interactive job or a -now y batch job.
func (js *JobStatus) IsImmediateJob() bool {
	return private_gestatus.IsImmediate(&js.js)
}

// HasReservation return true if the job requested a resource reservation.
func (js *JobStatus) HasReservation() bool {
	return private_gestatus.IsReservation(&js.js)
}

// IsBinaryJob returns the group of the job owner.
func (js *JobStatus) IsBinaryJob() bool {
	return private_gestatus.IsBinary(&js.js)
}

// HasNoShell returns true if the job had requested -shell no.
func (js *JobStatus) HasNoShell() bool {
	return private_gestatus.IsNoShell(&js.js)
}

// IsArrayJob returns true in case the job is an array job.
func (js *JobStatus) IsArrayJob() bool {
	return private_gestatus.IsArray(&js.js)
}

// JobMergesStderr returns true if job merges stderr to stdout.
func (js *JobStatus) JobMergesStderr() bool {
	return private_gestatus.IsMergeStderr(&js.js)
}

// HasMemoryBinding returns true in case the job has memory binding requested.
func (js *JobStatus) HasMemoryBinding() bool {
	if private_gestatus.GetMbind(&js.js) == "no_bind" {
		return false
	}
	return true
}

// MemoryBinding returns the status of the actual memory binding done for the processes of the job.
func (js *JobStatus) MemoryBinding() string {
	return private_gestatus.GetMbind(&js.js)
}

// StartTime is when the job was dispatched to the execution host in order to start up the processes.
func (js *JobStatus) StartTime() time.Time {
	return private_gestatus.GetStartTime(&js.js)
}

// RunTime return since how long is the job running. Note that the run-time is dynamically
// calculated assuming that the start time stamp in the cluster is in the same time zone
// then the actual RunTime() call. */
func (js *JobStatus) RunTime() time.Duration {
	if js.StartTime().Unix() != 0 {
		return time.Since(js.StartTime())
	}
	d, _ := time.ParseDuration("0s")
	return d
}

// TaskStartTime is the start time of a specific task of the job (for array jobs).
func (js *JobStatus) TaskStartTime(taskID int) time.Time {
	return private_gestatus.GetTaskStartTime(&js.js, taskID)
}

// executionTime is the end time of the job.
func (js *JobStatus) executionTime() time.Time {
	return private_gestatus.GetExecutionTime(&js.js)
}

// Submission time is the time when the job was submitted to the cluster.
func (js *JobStatus) SubmissionTime() time.Time {
	return private_gestatus.GetSubmissionTime(&js.js)
}

// JobDeadline returns if the job has set a deadline for starting up.
func (js *JobStatus) JobDeadline() time.Time {
	return private_gestatus.GetDeadline(&js.js)
}

// PosixPriority returns the POSIX priority the job has requested.
// The default priority for the POSIX policy is 0 ranging from -1023
// till 1024. Only adminstrators can set a positive priority.
func (js *JobStatus) PosixPriority() int {
	// priority is returned as positiv integer 1024 for 0
	return private_gestatus.GetPosixPriority(&js.js) - 1024
}

// MailOptions returns the mail options which determines on which event
// emails about job status change is sent.
func (js *JobStatus) MailOptions() string {
	return private_gestatus.GetMailOptions(&js.js)
}

// AdvanceReservationID returns the ID of the advance reservation the
// job is running in. Note that this ID has no relationship to the
// job IDs.
func (js *JobStatus) AdvanceReservationID() int {
	return private_gestatus.GetAR(&js.js)
}

// JobClassName returns the name of the requested job class.
func (js *JobStatus) JobClassName() string {
	return private_gestatus.GetJobClassName(&js.js)
}

// MailAdresses returns all mail addresses the job is sending
// information about its state.
func (js *JobStatus) MailAdresses() []string {
	return private_gestatus.GetMailingAdresses(&js.js)
}

// HardRequests returns hard resource requests as name and value
// pairs. Names are the first slice the values are encoded in the
// second slice. TODO make a map of it...
func (js *JobStatus) HardRequests() ([]string, []string) {
	return private_gestatus.GetHardRequests(&js.js)
}

func (js *JobStatus) gdilQueueNames(what string, task int) []string {
	qil := make([]string, 16)

	gdil := private_gestatus.GetGDIL(&js.js, task)

	if gdil == nil {
		return nil
	}
	for i := range *gdil {
		if what == "QueueName" {
			qil = append(qil, (*gdil)[i].QueueName)
		} else if what == "HostName" {
			qi := strings.Split((*gdil)[i].QueueName, "@")
			if len(qi) == 2 {
				qil = append(qil, qi[1])
			}
		} else if what == "Slots" {
			qil = append(qil, strconv.Itoa((*gdil)[i].Slots))
		}
	}

	return qil
}

// DestinationQueueInstanceList returns all queue instance names where the job is running.
// A queue instance contains a host and a "@" queue part, where the job is scheduled to.
func (js *JobStatus) DestinationQueueInstanceList() []string {
	return js.gdilQueueNames("QueueName", 0)
}

// DestinationQueueInstanceListOfTask returns the queue instances of a particular
// array job task.
func (js *JobStatus) DestinationQueueInstanceListOfTask(task int) []string {
	return js.gdilQueueNames("QueueName", task)
}

// DestinationSlotsList returns a list of slots used on the queue instances.
func (js *JobStatus) DestinationSlotsList() []string {
	return js.gdilQueueNames("Slots", 0)
}

// DestinationHostList returns all host names where the job (the first task
// in case of array jobs) is running.
func (js *JobStatus) DestinationHostList() []string {
	return js.gdilQueueNames("HostName", 0)
}

// DestinationHostListOfTask returns all hosts a parallel array job
// task is running on.
func (js *JobStatus) DestinationHostListOfTask(task int) []string {
	return js.gdilQueueNames("HostName", task)
}

// TasksCount retursn the amount of array job tasks an
// job array consists of.
func (js *JobStatus) TasksCount() int {
	return private_gestatus.GetTaskCount(&js.js)
}

// ParallelEnvironment returns the name of the parallel environment
// requested by a job.
func (js *JobStatus) ParallelEnvironment() string {
	return private_gestatus.GetParallelEnvironmentRequest(&js.js)
}

// ParallelEnvironmentMin contains the amount of slots requested
// by a parallel jobs.
func (js *JobStatus) ParallelEnvironmentMin() int64 {
	return private_gestatus.GetParallelEnvironmentMin(&js.js)
}

// ParallelEnvironmentMax returns the maximum amount of slots
// required by the parallel job. It is equal to ParallelEnvironmentMin()
// in case of a fixed amount of slots were requested (which is
// the standard case).
func (js *JobStatus) ParallelEnvironmentMax() int64 {
	return private_gestatus.GetParallelEnvironmentMax(&js.js)
}

// ParallelEnvironmentStep is the step size of a slot range
// request of a parallel job.
func (js *JobStatus) ParallelEnvironmentStep() int64 {
	return private_gestatus.GetParallelEnvironmentStep(&js.js)
}

// ResourceUsage returns the measurements of resource consumption
// by the processes of a job.
func (js *JobStatus) ResourceUsage(task int) ([]string, []string) {
	return private_gestatus.GetUsageList(&js.js, task)
}
<|endoftext|>


<commit_before>package pathfinderpkg

import (
	"math/rand"
	"reflect"
	"runtime"
	"testing"
)

func TestAbilityCost(t *testing.T) {
	// Costs outside of range
	if value, ok := AbilityCost(0); value != 0 || ok {
		t.Errorf("Expected AbilityCost(0) to yield 0/false, got %v/%v", value, ok)
	}
	if value, ok := AbilityCost(46); value != 0 || ok {
		t.Errorf("Expected AbilityCost(46) to yield 0/false, got %v/%v", value, ok)
	}
	for i := 1; i < 46; i++ {
		if value, ok := AbilityCost(i); !ok {
			t.Errorf("Expected AbilityCost(%v) to yield a valid value and true, got %v/%v", i, value, ok)
		}
	}
}

func TestAbilityModifier(t *testing.T) {
	// Modifier outside of range
	if value, ok := AbilityModifier(0); value != 0 || ok {
		t.Errorf("Expected AbilityModifier(0) to yield 0/false, got %v/%v", value, ok)
	}
	if value, ok := AbilityModifier(46); value != 0 || ok {
		t.Errorf("Expected AbilityModifier(46) to yield 0/false, got %v/%v", value, ok)
	}
	for i := 1; i < 46; i++ {
		if value, ok := AbilityModifier(i); !ok {
			t.Errorf("Expected AbilityModifier(%v) to yield a valid value and true, got %v/%v", i, value, ok)
		}
	}
}

func testAbilityFunctionOverRange(t *testing.T, hi, lo int, fn1 func(int) (int, bool), fn2 func(Abilities) int) {
	for i1 := lo; i1 < hi; i1++ {
		for i2 := lo; i2 < hi; i2++ {
			for i3 := lo; i3 < hi; i3++ {
				for i4 := lo; i4 < hi; i4++ {
					for i5 := lo; i5 < hi; i5++ {
						for i6 := 1; i6 < 46; i6++ {
							abilities := Abilities{i1, i2, i3, i4, i5, i6}
							expected := abilities.Map(func(x int) int { v, _ := fn1(x); return v }).Apply(0, func(x, y int) int { return x + y })
							got := fn2(abilities)
							if expected != got {
								t.Errorf("Expected %v(%v) to yield %v, got %v", runtime.FuncForPC(reflect.ValueOf(fn2).Pointer()).Name(), abilities, expected, got)
							}
						}
					}
				}
			}
		}
	}
}

func TestSumCostOfAbilitiesOutOfRange(t *testing.T) {
	// ability scores outside of range
	abilities := Abilities{0, 0, 0, 0, 0, 0}
	got := SumCostOfAbilities(abilities)
	if got != 0 {
		t.Errorf("Expected SumCostOfAbilities(%v) to be 0, got %v", abilities, got)
	}
	abilities = Abilities{46, 46, 46, 46, 46, 46}
	got = SumCostOfAbilities(abilities)
	if got != 0 {
		t.Errorf("Expected SumCostOfAbilities(%v) to be 0, got %v", abilities, got)
	}
}

func TestSumCostOfAbilities(t *testing.T) {
	max := 46
	rng := 10
	var hi, lo int
	if testing.Short() {
		lo = rand.Intn(max - rng)
		hi = lo + rng
		testAbilityFunctionOverRange(t, hi, lo, AbilityCost, SumCostOfAbilities)
	} else {
		t.Run("Full", func(t *testing.T) {
			t.Run("1", func(t *testing.T) { testAbilityFunctionOverRange(t, 9, 1, AbilityCost, SumCostOfAbilities) })
			t.Run("2", func(t *testing.T) { testAbilityFunctionOverRange(t, 18, 10, AbilityCost, SumCostOfAbilities) })
			t.Run("3", func(t *testing.T) { testAbilityFunctionOverRange(t, 27, 19, AbilityCost, SumCostOfAbilities) })
			t.Run("4", func(t *testing.T) { testAbilityFunctionOverRange(t, 36, 28, AbilityCost, SumCostOfAbilities) })
			t.Run("5", func(t *testing.T) { testAbilityFunctionOverRange(t, 46, 37, AbilityCost, SumCostOfAbilities) })
		})
	}
}

func TestSumModifiersFromAbilitiesOutOfRange(t *testing.T) {
	// ability scores outside of range
	abilities := Abilities{0, 0, 0, 0, 0, 0}
	got := SumModifiersFromAbilities(abilities)
	if got != 0 {
		t.Errorf("Expected SumModifiersFromAbilities(%v) to be 0, got %v", abilities, got)
	}
	abilities = Abilities{46, 46, 46, 46, 46, 46}
	got = SumModifiersFromAbilities(abilities)
	if got != 0 {
		t.Errorf("Expected SumModifiersFromAbilities(%v) to be 0, got %v", abilities, got)
	}
}

func TestSumModifiersFromAbilities(t *testing.T) {
	max := 46
	rng := 10
	var hi, lo int
	if testing.Short() {
		lo = rand.Intn(max - rng)
		hi = lo + rng
		testAbilityFunctionOverRange(t, hi, lo, AbilityModifier, SumModifiersFromAbilities)
	} else {
		t.Run("Full", func(t *testing.T) {
			t.Run("1", func(t *testing.T) { testAbilityFunctionOverRange(t, 9, 1, AbilityModifier, SumModifiersFromAbilities) })
			t.Run("2", func(t *testing.T) {
				testAbilityFunctionOverRange(t, 18, 10, AbilityModifier, SumModifiersFromAbilities)
			})
			t.Run("3", func(t *testing.T) {
				testAbilityFunctionOverRange(t, 27, 19, AbilityModifier, SumModifiersFromAbilities)
			})
			t.Run("4", func(t *testing.T) {
				testAbilityFunctionOverRange(t, 36, 28, AbilityModifier, SumModifiersFromAbilities)
			})
			t.Run("5", func(t *testing.T) {
				testAbilityFunctionOverRange(t, 46, 37, AbilityModifier, SumModifiersFromAbilities)
			})
		})
	}
}

func BenchmarkSumCostOfAbilities(b *testing.B) {
	abilities := Abilities{15, 14, 14, 14, 13, 12}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		SumCostOfAbilities(abilities)
	}
}

func BenchmarkSumModifierFromAbilities(b *testing.B) {
	abilities := Abilities{15, 14, 14, 14, 13, 12}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		SumModifiersFromAbilities(abilities)
	}
}

func BenchmarkSumCostFunctional(b *testing.B) {
	abilities := Abilities{15, 14, 14, 14, 13, 12}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		abilities.Map(func(x int) int { v, _ := AbilityCost(x); return v }).Apply(0, func(x, y int) int { return x + y })
	}
}

func BenchmarkSumModifierFunctional(b *testing.B) {
	abilities := Abilities{15, 14, 14, 14, 13, 12}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		abilities.Map(func(x int) int { v, _ := AbilityModifier(x); return v }).Apply(0, func(x, y int) int { return x + y })
	}
}
<commit_msg>Simplify the tests due to faster execution...<commit_after>package pathfinderpkg

import (
	"math/rand"
	"reflect"
	"runtime"
	"testing"
)

func TestAbilityCost(t *testing.T) {
	// Costs outside of range
	if value, ok := AbilityCost(0); value != 0 || ok {
		t.Errorf("Expected AbilityCost(0) to yield 0/false, got %v/%v", value, ok)
	}
	if value, ok := AbilityCost(46); value != 0 || ok {
		t.Errorf("Expected AbilityCost(46) to yield 0/false, got %v/%v", value, ok)
	}
	for i := 1; i < 46; i++ {
		if value, ok := AbilityCost(i); !ok {
			t.Errorf("Expected AbilityCost(%v) to yield a valid value and true, got %v/%v", i, value, ok)
		}
	}
}

func TestAbilityModifier(t *testing.T) {
	// Modifier outside of range
	if value, ok := AbilityModifier(0); value != 0 || ok {
		t.Errorf("Expected AbilityModifier(0) to yield 0/false, got %v/%v", value, ok)
	}
	if value, ok := AbilityModifier(46); value != 0 || ok {
		t.Errorf("Expected AbilityModifier(46) to yield 0/false, got %v/%v", value, ok)
	}
	for i := 1; i < 46; i++ {
		if value, ok := AbilityModifier(i); !ok {
			t.Errorf("Expected AbilityModifier(%v) to yield a valid value and true, got %v/%v", i, value, ok)
		}
	}
}

func testAbilityFunctionOverRange(t *testing.T, hi, lo int, fn1 func(int) (int, bool), fn2 func(Abilities) int) {
	for i1 := lo; i1 < hi; i1++ {
		for i2 := lo; i2 < hi; i2++ {
			for i3 := lo; i3 < hi; i3++ {
				for i4 := lo; i4 < hi; i4++ {
					for i5 := lo; i5 < hi; i5++ {
						for i6 := 1; i6 < 46; i6++ {
							abilities := Abilities{i1, i2, i3, i4, i5, i6}
							expected := abilities.Map(func(x int) int { v, _ := fn1(x); return v }).Apply(0, func(x, y int) int { return x + y })
							got := fn2(abilities)
							if expected != got {
								t.Errorf("Expected %v(%v) to yield %v, got %v", runtime.FuncForPC(reflect.ValueOf(fn2).Pointer()).Name(), abilities, expected, got)
							}
						}
					}
				}
			}
		}
	}
}

func TestSumCostOfAbilitiesOutOfRange(t *testing.T) {
	// ability scores outside of range
	abilities := Abilities{0, 0, 0, 0, 0, 0}
	got := SumCostOfAbilities(abilities)
	if got != 0 {
		t.Errorf("Expected SumCostOfAbilities(%v) to be 0, got %v", abilities, got)
	}
	abilities = Abilities{46, 46, 46, 46, 46, 46}
	got = SumCostOfAbilities(abilities)
	if got != 0 {
		t.Errorf("Expected SumCostOfAbilities(%v) to be 0, got %v", abilities, got)
	}
}

func TestSumCostOfAbilities(t *testing.T) {
	max := 46
	rng := 10
	var hi, lo int
	if testing.Short() {
		lo = rand.Intn(max - rng)
		hi = lo + rng
		testAbilityFunctionOverRange(t, hi, lo, AbilityCost, SumCostOfAbilities)
	} else {
		t.Run("Full", func(t *testing.T) {
			t.Run("1", func(t *testing.T) { testAbilityFunctionOverRange(t, 24, 1, AbilityCost, SumCostOfAbilities) })
			t.Run("2", func(t *testing.T) { testAbilityFunctionOverRange(t, 46, 24, AbilityCost, SumCostOfAbilities) })
		})
	}
}

func TestSumModifiersFromAbilitiesOutOfRange(t *testing.T) {
	// ability scores outside of range
	abilities := Abilities{0, 0, 0, 0, 0, 0}
	got := SumModifiersFromAbilities(abilities)
	if got != 0 {
		t.Errorf("Expected SumModifiersFromAbilities(%v) to be 0, got %v", abilities, got)
	}
	abilities = Abilities{46, 46, 46, 46, 46, 46}
	got = SumModifiersFromAbilities(abilities)
	if got != 0 {
		t.Errorf("Expected SumModifiersFromAbilities(%v) to be 0, got %v", abilities, got)
	}
}

func TestSumModifiersFromAbilities(t *testing.T) {
	max := 46
	rng := 10
	var hi, lo int
	if testing.Short() {
		lo = rand.Intn(max - rng)
		hi = lo + rng
		testAbilityFunctionOverRange(t, hi, lo, AbilityModifier, SumModifiersFromAbilities)
	} else {
		t.Run("Full", func(t *testing.T) {
			t.Run("1", func(t *testing.T) { testAbilityFunctionOverRange(t, 24, 1, AbilityModifier, SumModifiersFromAbilities) })
			t.Run("2", func(t *testing.T) {
				testAbilityFunctionOverRange(t, 46, 24, AbilityModifier, SumModifiersFromAbilities)
			})
		})
	}
}

func BenchmarkSumCostOfAbilities(b *testing.B) {
	abilities := Abilities{15, 14, 14, 14, 13, 12}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		SumCostOfAbilities(abilities)
	}
}

func BenchmarkSumModifierFromAbilities(b *testing.B) {
	abilities := Abilities{15, 14, 14, 14, 13, 12}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		SumModifiersFromAbilities(abilities)
	}
}

func BenchmarkSumCostFunctional(b *testing.B) {
	abilities := Abilities{15, 14, 14, 14, 13, 12}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		abilities.Map(func(x int) int { v, _ := AbilityCost(x); return v }).Apply(0, func(x, y int) int { return x + y })
	}
}

func BenchmarkSumModifierFunctional(b *testing.B) {
	abilities := Abilities{15, 14, 14, 14, 13, 12}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		abilities.Map(func(x int) int { v, _ := AbilityModifier(x); return v }).Apply(0, func(x, y int) int { return x + y })
	}
}
<|endoftext|>


<commit_before>package shell

import (
	"bufio"
	"io"
	"sync"
)

// UnixReader is a Reader implementation that automatically converts
// Windows line endings to Unix line endings.
type UnixReader struct {
	Reader io.Reader

	buf     []byte
	once    sync.Once
	scanner *bufio.Scanner
}

func (r *UnixReader) Read(p []byte) (n int, err error) {
	// Create the buffered reader once
	r.once.Do(func() {
		r.scanner = bufio.NewScanner(r.Reader)
		r.scanner.Split(scanUnixLine)
	})

	// If we have no data in our buffer, scan to the next token
	if len(r.buf) == 0 {
		if !r.scanner.Scan() {
			err = r.scanner.Err()
			if err == nil {
				err = io.EOF
			}

			return 0, err
		}

		r.buf = r.scanner.Bytes()
	}

	// Write out as much data as we can to the buffer, storing the rest
	// for the next read.
	n = len(p)
	if n > len(r.buf) {
		n = len(r.buf)
	}
	copy(p, r.buf)
	r.buf = r.buf[n:]

	return
}

// scanUnixLine is a bufio.Scanner SplitFunc. It tokenizes on lines, but
// only returns unix-style lines. So even if the line is "one\r\n", the
// token returned will be "one\n".
func scanUnixLine(data []byte, atEOF bool) (advance int, token []byte, err error) {
	advance, token, err = bufio.ScanLines(data, atEOF)
	if advance == 0 {
		return
	}
	return advance, append(token, '\n'), err
}
<commit_msg>provisioner/shell: comment on why we return right away if advance == 0<commit_after>package shell

import (
	"bufio"
	"io"
	"sync"
)

// UnixReader is a Reader implementation that automatically converts
// Windows line endings to Unix line endings.
type UnixReader struct {
	Reader io.Reader

	buf     []byte
	once    sync.Once
	scanner *bufio.Scanner
}

func (r *UnixReader) Read(p []byte) (n int, err error) {
	// Create the buffered reader once
	r.once.Do(func() {
		r.scanner = bufio.NewScanner(r.Reader)
		r.scanner.Split(scanUnixLine)
	})

	// If we have no data in our buffer, scan to the next token
	if len(r.buf) == 0 {
		if !r.scanner.Scan() {
			err = r.scanner.Err()
			if err == nil {
				err = io.EOF
			}

			return 0, err
		}

		r.buf = r.scanner.Bytes()
	}

	// Write out as much data as we can to the buffer, storing the rest
	// for the next read.
	n = len(p)
	if n > len(r.buf) {
		n = len(r.buf)
	}
	copy(p, r.buf)
	r.buf = r.buf[n:]

	return
}

// scanUnixLine is a bufio.Scanner SplitFunc. It tokenizes on lines, but
// only returns unix-style lines. So even if the line is "one\r\n", the
// token returned will be "one\n".
func scanUnixLine(data []byte, atEOF bool) (advance int, token []byte, err error) {
	advance, token, err = bufio.ScanLines(data, atEOF)
	if advance == 0 {
		// If we reached the end of a line without a newline, then
		// just return as it is. Otherwise the Scanner will keep trying
		// to scan, blocking forever.
		return
	}

	return advance, append(token, '\n'), err
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"log"
	"net/http"
	_ "net/http/pprof"
	"os"
	"os/signal"
	"runtime/pprof"
	"syscall"
	"time"

	alealog "github.com/aleasoluciones/goaleasoluciones/log"
	"github.com/aleasoluciones/http2amqp"
)

func init() {
	c := make(chan os.Signal, 1)
	signal.Notify(c, syscall.SIGHUP)

	go func() {
		for _ = range c {
			pprof.Lookup("goroutine").WriteTo(os.Stdout, 1)
		}
	}()
}

func main() {
	alealog.Init()
	alealog.DisableLogging()

	go func() {
		// HTTP server used to remote profiling
		http.ListenAndServe("127.0.0.1:16060", nil)
	}()

	amqpuri := flag.String("amqpuri", localBrokerUri(), "AMQP connection uri")
	address := flag.String("address", "0.0.0.0", "Listen address")
	port := flag.String("port", "18080", "Listen port")
	exchange := flag.String("exchange", "events", "AMQP exchange name")
	timeout := flag.Int("timeout", 1000, "Queries timeout in milliseconds")
	flag.Parse()

	service := http2amqp.NewService(*amqpuri, *exchange, time.Duration(*timeout)*time.Millisecond)

	http.HandleFunc("/", http2amqp.NewHTTPServerFunc(service))
	addressAndPort := fmt.Sprintf("%s:%s", *address, *port)
	log.Println("[http2amqp] Starting HTTP server at ", addressAndPort)
	http.ListenAndServe(addressAndPort, nil)
}

func localBrokerUri() string {
	brokerUri := os.Getenv("BROKER_URI")

	if len(brokerUri) == 0 {
		brokerUri = "amqp://guest:guest@localhost/"
	}

	return brokerUri
}
<commit_msg>http profiling ip changed to 0.0.0.0<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"net/http"
	_ "net/http/pprof"
	"os"
	"os/signal"
	"runtime/pprof"
	"syscall"
	"time"

	alealog "github.com/aleasoluciones/goaleasoluciones/log"
	"github.com/aleasoluciones/http2amqp"
)

func init() {
	c := make(chan os.Signal, 1)
	signal.Notify(c, syscall.SIGHUP)

	go func() {
		for _ = range c {
			pprof.Lookup("goroutine").WriteTo(os.Stdout, 1)
		}
	}()
}

func main() {
	alealog.Init()
	alealog.DisableLogging()

	go func() {
		// HTTP server used to remote profiling
		http.ListenAndServe("0.0.0.0:16060", nil)
	}()

	amqpuri := flag.String("amqpuri", localBrokerUri(), "AMQP connection uri")
	address := flag.String("address", "0.0.0.0", "Listen address")
	port := flag.String("port", "18080", "Listen port")
	exchange := flag.String("exchange", "events", "AMQP exchange name")
	timeout := flag.Int("timeout", 1000, "Queries timeout in milliseconds")
	flag.Parse()

	service := http2amqp.NewService(*amqpuri, *exchange, time.Duration(*timeout)*time.Millisecond)

	http.HandleFunc("/", http2amqp.NewHTTPServerFunc(service))
	addressAndPort := fmt.Sprintf("%s:%s", *address, *port)
	log.Println("[http2amqp] Starting HTTP server at ", addressAndPort)
	http.ListenAndServe(addressAndPort, nil)
}

func localBrokerUri() string {
	brokerUri := os.Getenv("BROKER_URI")

	if len(brokerUri) == 0 {
		brokerUri = "amqp://guest:guest@localhost/"
	}

	return brokerUri
}
<|endoftext|>


<commit_before>//go:build linux

package termios

import (
	"golang.org/x/sys/unix"
)

const ioctlReadTermios = unix.TCGETS
const ioctlWriteTermios = unix.TCSETS

// State contains the state of a terminal.
type State struct {
	Termios unix.Termios
}

// IsTerminal returns true if the given file descriptor is a terminal.
func IsTerminal(fd int) bool {
	_, err := GetState(fd)
	return err == nil
}

// GetState returns the current state of a terminal which may be useful to restore the terminal after a signal.
func GetState(fd int) (*State, error) {
	termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
	if err != nil {
		return nil, err
	}

	state := State{}
	state.Termios = *termios

	return &state, nil
}

// GetSize returns the dimensions of the given terminal.
func GetSize(fd int) (int, int, error) {
	winsize, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ)
	if err != nil {
		return -1, -1, err
	}

	return int(winsize.Col), int(winsize.Row), nil
}

// MakeRaw put the terminal connected to the given file descriptor into raw mode and returns the previous state of the terminal so that it can be restored.
func MakeRaw(fd int) (*State, error) {
	oldState, err := GetState(fd)
	if err != nil {
		return nil, err
	}

	newState := *oldState

	// This attempts to replicate the behaviour documented for cfmakeraw in the termios(3) manpage.
	newState.Termios.Iflag &^= unix.BRKINT | unix.ICRNL | unix.INPCK | unix.ISTRIP | unix.IXON
	newState.Termios.Oflag &^= unix.OPOST
	newState.Termios.Cflag &^= unix.CSIZE | unix.PARENB
	newState.Termios.Cflag |= unix.CS8
	newState.Termios.Lflag &^= unix.ECHO | unix.ICANON | unix.IEXTEN | unix.ISIG
	newState.Termios.Cc[unix.VMIN] = 1
	newState.Termios.Cc[unix.VTIME] = 0

	err = Restore(fd, &newState)
	if err != nil {
		return nil, err
	}

	return oldState, nil
}

// Restore restores the terminal connected to the given file descriptor to a previous state.
func Restore(fd int, state *State) error {
	if err := unix.IoctlSetTermios(fd, ioctlWriteTermios, &state.Termios); err != nil {
		return err
	}

	return nil
}
<commit_msg>shared/termios: Removes all one-line assign and check statements.<commit_after>//go:build linux

package termios

import (
	"golang.org/x/sys/unix"
)

const ioctlReadTermios = unix.TCGETS
const ioctlWriteTermios = unix.TCSETS

// State contains the state of a terminal.
type State struct {
	Termios unix.Termios
}

// IsTerminal returns true if the given file descriptor is a terminal.
func IsTerminal(fd int) bool {
	_, err := GetState(fd)
	return err == nil
}

// GetState returns the current state of a terminal which may be useful to restore the terminal after a signal.
func GetState(fd int) (*State, error) {
	termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
	if err != nil {
		return nil, err
	}

	state := State{}
	state.Termios = *termios

	return &state, nil
}

// GetSize returns the dimensions of the given terminal.
func GetSize(fd int) (int, int, error) {
	winsize, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ)
	if err != nil {
		return -1, -1, err
	}

	return int(winsize.Col), int(winsize.Row), nil
}

// MakeRaw put the terminal connected to the given file descriptor into raw mode and returns the previous state of the terminal so that it can be restored.
func MakeRaw(fd int) (*State, error) {
	oldState, err := GetState(fd)
	if err != nil {
		return nil, err
	}

	newState := *oldState

	// This attempts to replicate the behaviour documented for cfmakeraw in the termios(3) manpage.
	newState.Termios.Iflag &^= unix.BRKINT | unix.ICRNL | unix.INPCK | unix.ISTRIP | unix.IXON
	newState.Termios.Oflag &^= unix.OPOST
	newState.Termios.Cflag &^= unix.CSIZE | unix.PARENB
	newState.Termios.Cflag |= unix.CS8
	newState.Termios.Lflag &^= unix.ECHO | unix.ICANON | unix.IEXTEN | unix.ISIG
	newState.Termios.Cc[unix.VMIN] = 1
	newState.Termios.Cc[unix.VTIME] = 0

	err = Restore(fd, &newState)
	if err != nil {
		return nil, err
	}

	return oldState, nil
}

// Restore restores the terminal connected to the given file descriptor to a previous state.
func Restore(fd int, state *State) error {
	err := unix.IoctlSetTermios(fd, ioctlWriteTermios, &state.Termios)
	if err != nil {
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>// Package shared contains shared data between the host and plugins.
package shared

import (
	"net/rpc"

	"google.golang.org/grpc"

	"github.com/hashicorp/go-plugin"
	"github.com/hashicorp/go-plugin/examples/grpc/proto"
)

// Handshake is a common handshake that is shared by plugin and host.
var Handshake = plugin.HandshakeConfig{
	ProtocolVersion:  1,
	MagicCookieKey:   "BASIC_PLUGIN",
	MagicCookieValue: "hello",
}

// PluginMap is the map of plugins we can dispense.
var PluginMap = map[string]plugin.Plugin{
	"kv": &KVPlugin{},
}

// KV is the interface that we're exposing as a plugin.
type KV interface {
	Put(key string, value []byte) error
	Get(key string) ([]byte, error)
}

// This is the implementation of plugin.Plugin so we can serve/consume this.
// We also implement GRPCPlugin so that this plugin can be served over
// gRPC.
type KVPlugin struct {
	// Concrete implementation, written in Go. This is only used for plugins
	// that are written in Go.
	Impl KV
}

func (p *KVPlugin) Server(*plugin.MuxBroker) (interface{}, error) {
	return &RPCServer{Impl: p.Impl}, nil
}

func (*KVPlugin) Client(b *plugin.MuxBroker, c *rpc.Client) (interface{}, error) {
	return &RPCClient{client: c}, nil
}

func (p *KVPlugin) GRPCServer(s *grpc.Server) error {
	proto.RegisterKVServer(s, &GRPCServer{Impl: p.Impl})
	return nil
}

func (p *KVPlugin) GRPCClient(c *grpc.ClientConn) (interface{}, error) {
	return &GRPCClient{client: proto.NewKVClient(c)}, nil
}
<commit_msg>Fix plugin-go-grpc example (#66)<commit_after>// Package shared contains shared data between the host and plugins.
package shared

import (
	"context"
	"net/rpc"

	"google.golang.org/grpc"

	"github.com/hashicorp/go-plugin"
	"github.com/hashicorp/go-plugin/examples/grpc/proto"
)

// Handshake is a common handshake that is shared by plugin and host.
var Handshake = plugin.HandshakeConfig{
	ProtocolVersion:  1,
	MagicCookieKey:   "BASIC_PLUGIN",
	MagicCookieValue: "hello",
}

// PluginMap is the map of plugins we can dispense.
var PluginMap = map[string]plugin.Plugin{
	"kv": &KVPlugin{},
}

// KV is the interface that we're exposing as a plugin.
type KV interface {
	Put(key string, value []byte) error
	Get(key string) ([]byte, error)
}

// This is the implementation of plugin.Plugin so we can serve/consume this.
// We also implement GRPCPlugin so that this plugin can be served over
// gRPC.
type KVPlugin struct {
	// Concrete implementation, written in Go. This is only used for plugins
	// that are written in Go.
	Impl KV
}

func (p *KVPlugin) Server(*plugin.MuxBroker) (interface{}, error) {
	return &RPCServer{Impl: p.Impl}, nil
}

func (*KVPlugin) Client(b *plugin.MuxBroker, c *rpc.Client) (interface{}, error) {
	return &RPCClient{client: c}, nil
}

func (p *KVPlugin) GRPCServer(broker *plugin.GRPCBroker, s *grpc.Server) error {
	proto.RegisterKVServer(s, &GRPCServer{Impl: p.Impl})
	return nil
}

func (p *KVPlugin) GRPCClient(ctx context.Context, broker *plugin.GRPCBroker, c *grpc.ClientConn) (interface{}, error) {
	return &GRPCClient{client: proto.NewKVClient(c)}, nil
}
<|endoftext|>


<commit_before>package newcot

import (
	"reflect"
	"testing"
)

func assertEqual(actual, expected interface{}, t *testing.T) {
	if !reflect.DeepEqual(actual, expected) {
		t.Fatalf("got '%v' instead of '%v'", actual, expected)
	}
}

func TestComputeNodes1D(t *testing.T) {
	grid := New(1)

	levels := []uint8{0, 1, 1, 2, 2, 3, 3, 3, 3}
	orders := []uint32{0, 0, 2, 1, 3, 1, 3, 5, 7}
	nodes := []float64{0.5, 0, 1, 0.25, 0.75, 0.125, 0.375, 0.625, 0.875}

	assertEqual(grid.ComputeNodes(levels, orders), nodes, t)
}

func TestComputeNodes2D(t *testing.T) {
	grid := New(2)

	levels := []uint8{
		0, 0,
		0, 1,
		0, 1,
		1, 0,
		1, 0,
		0, 2,
		0, 2,
		1, 1,
		1, 1,
		1, 1,
		1, 1,
		2, 0,
		2, 0,
	}

	orders := []uint32{
		0, 0,
		0, 0,
		0, 2,
		0, 0,
		2, 0,
		0, 1,
		0, 3,
		0, 0,
		0, 2,
		2, 0,
		2, 2,
		1, 0,
		3, 0,
	}

	nodes := []float64{
		0.50, 0.50,
		0.50, 0.00,
		0.50, 1.00,
		0.00, 0.50,
		1.00, 0.50,
		0.50, 0.25,
		0.50, 0.75,
		0.00, 0.00,
		0.00, 1.00,
		1.00, 0.00,
		1.00, 1.00,
		0.25, 0.50,
		0.75, 0.50,
	}

	assertEqual(grid.ComputeNodes(levels, orders), nodes, t)
}

func TestComputeChildren1D(t *testing.T) {
	grid := New(1)

	levels := []uint8{0, 1, 1, 2, 2, 3, 3, 3, 3}
	orders := []uint32{0, 0, 2, 1, 3, 1, 3, 5, 7}
	childLevels := []uint8{1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4}
	childOrders := []uint32{0, 2, 1, 3, 1, 3, 5, 7, 1, 3, 5, 7, 9, 11, 13, 15}

	levels, orders = grid.ComputeChildren(levels, orders)

	assertEqual(levels, childLevels, t)
	assertEqual(orders, childOrders, t)
}

func TestComputeChildren2D(t *testing.T) {
	grid := New(2)

	levels := []uint8{
		0, 0,
		0, 1,
		0, 1,
		1, 0,
		1, 0,
		0, 2,
		0, 2,
		1, 1,
		1, 1,
		1, 1,
		1, 1,
		2, 0,
		2, 0,
	}

	orders := []uint32{
		0, 0,
		0, 0,
		0, 2,
		0, 0,
		2, 0,
		0, 1,
		0, 3,
		0, 0,
		0, 2,
		2, 0,
		2, 2,
		1, 0,
		3, 0,
	}

	childLevels := []uint8{
		1, 0,
		1, 0,
		0, 1,
		0, 1,
		1, 1,
		1, 1,
		0, 2,
		1, 1,
		1, 1,
		0, 2,
		2, 0,
		2, 0,
		1, 2,
		1, 2,
		0, 3,
		0, 3,
		1, 2,
		1, 2,
		0, 3,
		0, 3,
		2, 1,
		2, 1,
		2, 1,
		2, 1,
		3, 0,
		3, 0,
		3, 0,
		3, 0,
	}

	childOrders := []uint32{
		0, 0,
		2, 0,
		0, 0,
		0, 2,
		0, 0,
		2, 0,
		0, 1,
		0, 2,
		2, 2,
		0, 3,
		1, 0,
		3, 0,
		0, 1,
		2, 1,
		0, 1,
		0, 3,
		0, 3,
		2, 3,
		0, 5,
		0, 7,
		1, 0,
		1, 2,
		3, 0,
		3, 2,
		1, 0,
		3, 0,
		5, 0,
		7, 0,
	}

	levels, orders = grid.ComputeChildren(levels, orders)

	assertEqual(levels, childLevels, t)
	assertEqual(orders, childOrders, t)
}

func BenchmarkComputeChildren(b *testing.B) {
	const (
		inputs      = 20
		targetLevel = 3
	)

	grid := New(inputs)

	// Level 0
	levels := make([]uint8, inputs)
	orders := make([]uint32, inputs)

	// Level 1, 2, …, (targetLevel - 1)
	for i := 1; i < targetLevel; i++ {
		levels, orders = grid.ComputeChildren(levels, orders)
	}

	b.ResetTimer()

	// Level targetLevel
	for i := 0; i < b.N; i++ {
		grid.ComputeChildren(levels, orders)
	}
}
<commit_msg>Made use of support/assert<commit_after>package newcot

import (
	"reflect"
	"testing"

	"github.com/go-math/support/assert"
)

func TestComputeNodes1D(t *testing.T) {
	grid := New(1)

	levels := []uint8{0, 1, 1, 2, 2, 3, 3, 3, 3}
	orders := []uint32{0, 0, 2, 1, 3, 1, 3, 5, 7}
	nodes := []float64{0.5, 0, 1, 0.25, 0.75, 0.125, 0.375, 0.625, 0.875}

	assert.Equal(grid.ComputeNodes(levels, orders), nodes, t)
}

func TestComputeNodes2D(t *testing.T) {
	grid := New(2)

	levels := []uint8{
		0, 0,
		0, 1,
		0, 1,
		1, 0,
		1, 0,
		0, 2,
		0, 2,
		1, 1,
		1, 1,
		1, 1,
		1, 1,
		2, 0,
		2, 0,
	}

	orders := []uint32{
		0, 0,
		0, 0,
		0, 2,
		0, 0,
		2, 0,
		0, 1,
		0, 3,
		0, 0,
		0, 2,
		2, 0,
		2, 2,
		1, 0,
		3, 0,
	}

	nodes := []float64{
		0.50, 0.50,
		0.50, 0.00,
		0.50, 1.00,
		0.00, 0.50,
		1.00, 0.50,
		0.50, 0.25,
		0.50, 0.75,
		0.00, 0.00,
		0.00, 1.00,
		1.00, 0.00,
		1.00, 1.00,
		0.25, 0.50,
		0.75, 0.50,
	}

	assert.Equal(grid.ComputeNodes(levels, orders), nodes, t)
}

func TestComputeChildren1D(t *testing.T) {
	grid := New(1)

	levels := []uint8{0, 1, 1, 2, 2, 3, 3, 3, 3}
	orders := []uint32{0, 0, 2, 1, 3, 1, 3, 5, 7}
	childLevels := []uint8{1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4}
	childOrders := []uint32{0, 2, 1, 3, 1, 3, 5, 7, 1, 3, 5, 7, 9, 11, 13, 15}

	levels, orders = grid.ComputeChildren(levels, orders)

	assert.Equal(levels, childLevels, t)
	assert.Equal(orders, childOrders, t)
}

func TestComputeChildren2D(t *testing.T) {
	grid := New(2)

	levels := []uint8{
		0, 0,
		0, 1,
		0, 1,
		1, 0,
		1, 0,
		0, 2,
		0, 2,
		1, 1,
		1, 1,
		1, 1,
		1, 1,
		2, 0,
		2, 0,
	}

	orders := []uint32{
		0, 0,
		0, 0,
		0, 2,
		0, 0,
		2, 0,
		0, 1,
		0, 3,
		0, 0,
		0, 2,
		2, 0,
		2, 2,
		1, 0,
		3, 0,
	}

	childLevels := []uint8{
		1, 0,
		1, 0,
		0, 1,
		0, 1,
		1, 1,
		1, 1,
		0, 2,
		1, 1,
		1, 1,
		0, 2,
		2, 0,
		2, 0,
		1, 2,
		1, 2,
		0, 3,
		0, 3,
		1, 2,
		1, 2,
		0, 3,
		0, 3,
		2, 1,
		2, 1,
		2, 1,
		2, 1,
		3, 0,
		3, 0,
		3, 0,
		3, 0,
	}

	childOrders := []uint32{
		0, 0,
		2, 0,
		0, 0,
		0, 2,
		0, 0,
		2, 0,
		0, 1,
		0, 2,
		2, 2,
		0, 3,
		1, 0,
		3, 0,
		0, 1,
		2, 1,
		0, 1,
		0, 3,
		0, 3,
		2, 3,
		0, 5,
		0, 7,
		1, 0,
		1, 2,
		3, 0,
		3, 2,
		1, 0,
		3, 0,
		5, 0,
		7, 0,
	}

	levels, orders = grid.ComputeChildren(levels, orders)

	assert.Equal(levels, childLevels, t)
	assert.Equal(orders, childOrders, t)
}

func BenchmarkComputeChildren(b *testing.B) {
	const (
		inputs      = 20
		targetLevel = 3
	)

	grid := New(inputs)

	// Level 0
	levels := make([]uint8, inputs)
	orders := make([]uint32, inputs)

	// Level 1, 2, …, (targetLevel - 1)
	for i := 1; i < targetLevel; i++ {
		levels, orders = grid.ComputeChildren(levels, orders)
	}

	b.ResetTimer()

	// Level targetLevel
	for i := 0; i < b.N; i++ {
		grid.ComputeChildren(levels, orders)
	}
}
<|endoftext|>


<commit_before>package hypervisor

import (
	"errors"
	"fmt"
	"syscall"
	"time"

	"github.com/golang/glog"
	hyperstartapi "github.com/hyperhq/runv/hyperstart/api/json"
)

// states
const (
	StateInit        = "INIT"
	StatePreparing   = "PREPARING"
	StateStarting    = "STARTING"
	StateRunning     = "RUNNING"
	StateCleaning    = "CLEANING"
	StateTerminating = "TERMINATING"
	StateDestroying  = "DESTROYING"
	StateNone        = "NONE"
)

func (ctx *VmContext) timedKill(seconds int) {
	ctx.timer = time.AfterFunc(time.Duration(seconds)*time.Second, func() {
		if ctx != nil && ctx.handler != nil {
			ctx.DCtx.Kill(ctx)
		}
	})
}

func (ctx *VmContext) newContainer(id string, result chan<- error) {
	ctx.lock.Lock()
	defer ctx.lock.Unlock()

	c, ok := ctx.containers[id]
	if ok {
		glog.Infof("start sending INIT_NEWCONTAINER")
		ctx.vm <- &hyperstartCmd{
			Code:    hyperstartapi.INIT_NEWCONTAINER,
			Message: c.VmSpec(),
			result:  result,
		}
		glog.Infof("sent INIT_NEWCONTAINER")
	} else {
		result <- fmt.Errorf("container %s not exist", id)
	}
}

func (ctx *VmContext) updateInterface(id string, result chan<- error) {
	if inf := ctx.networks.getInterface(id); inf == nil {
		result <- fmt.Errorf("can't find interface whose ID is %s", id)
		return
	} else {
		ctx.vm <- &hyperstartCmd{
			Code: hyperstartapi.INIT_SETUPINTERFACE,
			Message: hyperstartapi.NetworkInf{
				Device:    inf.DeviceName,
				IpAddress: inf.IpAddr,
				NetMask:   inf.NetMask,
			},
			result: result,
		}
	}
}

func (ctx *VmContext) setWindowSize4242(containerId, execId string, size *WindowSize) {
	var session uint64
	if execId != "init" {
		exec, ok := ctx.vmExec[execId]
		if !ok {
			glog.Errorf("cannot find exec %s", execId)
			return
		}

		session = exec.Process.Stdio
	} else if containerId != "" {
		ctx.lock.Lock()
		defer ctx.lock.Unlock()

		c, ok := ctx.containers[containerId]
		if !ok {
			glog.Errorf("cannot find container %s", containerId)
			return
		}

		session = c.process.Stdio
	} else {
		glog.Error("no container or exec is specified")
		return
	}

	if !ctx.ptys.isTty(session) {
		glog.Error("the session is not a tty, doesn't support resize.")
		return
	}
	cmd := map[string]interface{}{
		"seq":    session,
		"row":    size.Row,
		"column": size.Column,
	}

	ctx.vm <- &hyperstartCmd{
		Code:    hyperstartapi.INIT_WINSIZE,
		Message: cmd,
	}
}

func (ctx *VmContext) setWindowSize(containerId, execId string, size *WindowSize) {
	if ctx.vmHyperstartAPIVersion <= 4242 {
		ctx.setWindowSize4242(containerId, execId, size)
		return
	}
	cmd := hyperstartapi.WindowSizeMessage{
		Container: containerId,
		Process:   execId,
		Row:       size.Row,
		Column:    size.Column,
	}

	ctx.vm <- &hyperstartCmd{
		Code:    hyperstartapi.INIT_WINSIZE,
		Message: cmd,
	}
}

func (ctx *VmContext) onlineCpuMem(cmd *OnlineCpuMemCommand) {
	ctx.vm <- &hyperstartCmd{
		Code: hyperstartapi.INIT_ONLINECPUMEM,
	}
}

func (ctx *VmContext) execCmd(execId string, cmd *hyperstartapi.ExecCommand, tty *TtyIO, result chan<- error) {
	cmd.Process.Stdio = ctx.ptys.nextAttachId()
	if !cmd.Process.Terminal {
		cmd.Process.Stderr = ctx.ptys.nextAttachId()
	}
	ctx.lock.Lock()
	defer ctx.lock.Unlock()
	if _, existed := ctx.vmExec[execId]; existed || execId == "init" {
		result <- fmt.Errorf("process id conflicts, the process of the id %s already exists", execId)
		return
	}
	ctx.vmExec[execId] = cmd
	ctx.ptys.ptyConnect(false, cmd.Process.Terminal, cmd.Process.Stdio, cmd.Process.Stderr, tty)
	ctx.vm <- &hyperstartCmd{
		Code:    hyperstartapi.INIT_EXECCMD,
		Message: cmd,
		result:  result,
	}
}

func (ctx *VmContext) killCmd(container string, signal syscall.Signal, result chan<- error) {
	ctx.vm <- &hyperstartCmd{
		Code: hyperstartapi.INIT_KILLCONTAINER,
		Message: hyperstartapi.KillCommand{
			Container: container,
			Signal:    signal,
		},
		result: result,
	}
}

func (ctx *VmContext) attachCmd(cmd *AttachCommand, result chan<- error) {
	ctx.lock.Lock()
	defer ctx.lock.Unlock()

	c, ok := ctx.containers[cmd.Container]
	if !ok {
		estr := fmt.Sprintf("cannot find container %s to attach", cmd.Container)
		ctx.Log(ERROR, estr)
		result <- errors.New(estr)
		return
	}

	ctx.attachTty2Container(c.process, cmd)
	if cmd.Size != nil {
		ctx.setWindowSize(cmd.Container, "init", cmd.Size)
	}

	result <- nil
}

func (ctx *VmContext) attachTty2Container(process *hyperstartapi.Process, cmd *AttachCommand) {
	session := process.Stdio
	ctx.ptys.ptyConnect(true, process.Terminal, session, process.Stderr, cmd.Streams)
	glog.V(1).Infof("Connecting tty for %s on session %d", cmd.Container, session)
}

func (ctx *VmContext) startPod() {
	ctx.vm <- &hyperstartCmd{
		Code:    hyperstartapi.INIT_STARTPOD,
		Message: ctx.networks.sandboxInfo(),
	}
}

func (ctx *VmContext) shutdownVM(err bool, msg string) {
	if err {
		ctx.reportVmFault(msg)
		glog.Error("Shutting down because of an exception: ", msg)
	}
	ctx.setTimeout(10)
	ctx.vm <- &hyperstartCmd{Code: hyperstartapi.INIT_DESTROYPOD}
}

func (ctx *VmContext) poweroffVM(err bool, msg string) {
	if err {
		glog.Error("Shutting down because of an exception: ", msg)
	}
	//REFACTOR: kill directly instead of DCtx.Shutdown() and send shutdown information
	ctx.Log(INFO, "poweroff vm based on command: %s", msg)
	if ctx != nil && ctx.handler != nil {
		ctx.DCtx.Kill(ctx)
	}
}

func (ctx *VmContext) handleGenericOperation(goe *GenericOperation) {
	for _, allowd := range goe.State {
		if ctx.current == allowd {
			glog.V(3).Infof("handle GenericOperation(%s) on state(%s)", goe.OpName, ctx.current)
			goe.OpFunc(ctx, goe.Result)
			return
		}
	}

	glog.V(3).Infof("GenericOperation(%s) is unsupported on state(%s)", goe.OpName, ctx.current)
	goe.Result <- fmt.Errorf("GenericOperation(%s) is unsupported on state(%s)", goe.OpName, ctx.current)
}

// state machine
func unexpectedEventHandler(ctx *VmContext, ev VmEvent, state string) {
	switch ev.Event() {
	case COMMAND_SHUTDOWN,
		COMMAND_RELEASE,
		COMMAND_PAUSEVM:
		ctx.reportUnexpectedRequest(ev, state)
	default:
		glog.Warning("got unexpected event during ", state)
	}
}

func stateRunning(ctx *VmContext, ev VmEvent) {
	switch ev.Event() {
	case COMMAND_ONLINECPUMEM:
		ctx.onlineCpuMem(ev.(*OnlineCpuMemCommand))
	case COMMAND_WINDOWSIZE:
		cmd := ev.(*WindowSizeCommand)
		ctx.setWindowSize(cmd.ContainerId, cmd.ExecId, cmd.Size)
	case COMMAND_GET_POD_STATS:
		ctx.reportPodStats(ev)
	case COMMAND_SHUTDOWN:
		ctx.Log(INFO, "got shutdown command, shutting down")
		ctx.shutdownVM(false, "")
		ctx.Become(stateTerminating, StateTerminating)
	case COMMAND_RELEASE:
		ctx.Log(INFO, "pod is running, got release command, let VM fly")
		ctx.Become(nil, StateNone)
		ctx.reportSuccess("", nil)
	case COMMAND_ACK:
		ack := ev.(*CommandAck)
		ctx.Log(DEBUG, "[running] got hyperstart ack to %d", ack.reply.Code)
		switch ack.reply.Code {
		case hyperstartapi.INIT_STARTPOD:
			ctx.Log(INFO, "pod start success ", string(ack.msg))
			ctx.reportSuccess("Start POD success", []byte{})
			//TODO: the payload is the persist info, will deal with this later
		default:
		}
	case EVENT_INIT_CONNECTED:
		ctx.Log(INFO, "hyperstart is ready to accept vm commands")
		ctx.reportVmRun()
	case EVENT_VM_EXIT, ERROR_VM_START_FAILED:
		ctx.Log(INFO, "VM has exit, or not started at all (%d)", ev.Event())
		ctx.reportVmShutdown()
		ctx.Close()
	case EVENT_VM_TIMEOUT: // REFACTOR: we do not set timeout for prepare devices after the refactor, then we do not need wait this event any more
		ctx.Log(ERROR, "REFACTOR: should be no time in running state at all")
	case ERROR_INIT_FAIL: // VM connection Failure
		reason := ev.(*InitFailedEvent).Reason
		ctx.Log(ERROR, reason)
		ctx.poweroffVM(true, "connection to vm broken")
		ctx.Close()
	case ERROR_INTERRUPTED:
		glog.Info("Connection interrupted, quit...")
		ctx.poweroffVM(true, "connection to vm broken")
		ctx.Close()
	case ERROR_CMD_FAIL:
		ack := ev.(*CommandError)
		switch ack.reply.Code {
		case hyperstartapi.INIT_NEWCONTAINER:
			//TODO: report fail message to the caller
		case hyperstartapi.INIT_STARTPOD:
			reason := "Start POD failed"
			ctx.reportVmFault(reason)
			ctx.Log(ERROR, reason)
		default:
		}
	case GENERIC_OPERATION:
		ctx.handleGenericOperation(ev.(*GenericOperation))
	default:
		unexpectedEventHandler(ctx, ev, "pod running")
	}
}

func stateTerminating(ctx *VmContext, ev VmEvent) {
	switch ev.Event() {
	case EVENT_VM_EXIT:
		glog.Info("Got VM shutdown event while terminating, go to cleaning up")
		ctx.reportVmShutdown()
		ctx.Close()
	case EVENT_VM_KILL:
		glog.Info("Got VM force killed message, go to cleaning up")
		ctx.reportVmShutdown()
		ctx.Close()
	case COMMAND_RELEASE:
		glog.Info("vm terminating, got release")
	case COMMAND_ACK:
		ack := ev.(*CommandAck)
		glog.V(1).Infof("[Terminating] Got reply to %d: '%s'", ack.reply, string(ack.msg))
		if ack.reply.Code == hyperstartapi.INIT_DESTROYPOD {
			glog.Info("POD destroyed ", string(ack.msg))
			ctx.poweroffVM(false, "")
		}
	case ERROR_CMD_FAIL:
		ack := ev.(*CommandError)
		if ack.reply.Code == hyperstartapi.INIT_DESTROYPOD {
			glog.Warning("Destroy pod failed")
			ctx.poweroffVM(true, "Destroy pod failed")
			ctx.Close()
		}
	case EVENT_VM_TIMEOUT:
		glog.Warning("VM did not exit in time, try to stop it")
		ctx.poweroffVM(true, "vm terminating timeout")
		ctx.Close()
	case ERROR_INTERRUPTED:
		interruptEv := ev.(*Interrupted)
		glog.V(1).Info("Connection interrupted while terminating: %s", interruptEv.Reason)
	case GENERIC_OPERATION:
		ctx.handleGenericOperation(ev.(*GenericOperation))
	default:
		unexpectedEventHandler(ctx, ev, "terminating")
	}
}
<commit_msg>Fix wrong log format<commit_after>package hypervisor

import (
	"errors"
	"fmt"
	"syscall"
	"time"

	"github.com/golang/glog"
	hyperstartapi "github.com/hyperhq/runv/hyperstart/api/json"
)

// states
const (
	StateInit        = "INIT"
	StatePreparing   = "PREPARING"
	StateStarting    = "STARTING"
	StateRunning     = "RUNNING"
	StateCleaning    = "CLEANING"
	StateTerminating = "TERMINATING"
	StateDestroying  = "DESTROYING"
	StateNone        = "NONE"
)

func (ctx *VmContext) timedKill(seconds int) {
	ctx.timer = time.AfterFunc(time.Duration(seconds)*time.Second, func() {
		if ctx != nil && ctx.handler != nil {
			ctx.DCtx.Kill(ctx)
		}
	})
}

func (ctx *VmContext) newContainer(id string, result chan<- error) {
	ctx.lock.Lock()
	defer ctx.lock.Unlock()

	c, ok := ctx.containers[id]
	if ok {
		glog.Infof("start sending INIT_NEWCONTAINER")
		ctx.vm <- &hyperstartCmd{
			Code:    hyperstartapi.INIT_NEWCONTAINER,
			Message: c.VmSpec(),
			result:  result,
		}
		glog.Infof("sent INIT_NEWCONTAINER")
	} else {
		result <- fmt.Errorf("container %s not exist", id)
	}
}

func (ctx *VmContext) updateInterface(id string, result chan<- error) {
	if inf := ctx.networks.getInterface(id); inf == nil {
		result <- fmt.Errorf("can't find interface whose ID is %s", id)
		return
	} else {
		ctx.vm <- &hyperstartCmd{
			Code: hyperstartapi.INIT_SETUPINTERFACE,
			Message: hyperstartapi.NetworkInf{
				Device:    inf.DeviceName,
				IpAddress: inf.IpAddr,
				NetMask:   inf.NetMask,
			},
			result: result,
		}
	}
}

func (ctx *VmContext) setWindowSize4242(containerId, execId string, size *WindowSize) {
	var session uint64
	if execId != "init" {
		exec, ok := ctx.vmExec[execId]
		if !ok {
			glog.Errorf("cannot find exec %s", execId)
			return
		}

		session = exec.Process.Stdio
	} else if containerId != "" {
		ctx.lock.Lock()
		defer ctx.lock.Unlock()

		c, ok := ctx.containers[containerId]
		if !ok {
			glog.Errorf("cannot find container %s", containerId)
			return
		}

		session = c.process.Stdio
	} else {
		glog.Error("no container or exec is specified")
		return
	}

	if !ctx.ptys.isTty(session) {
		glog.Error("the session is not a tty, doesn't support resize.")
		return
	}
	cmd := map[string]interface{}{
		"seq":    session,
		"row":    size.Row,
		"column": size.Column,
	}

	ctx.vm <- &hyperstartCmd{
		Code:    hyperstartapi.INIT_WINSIZE,
		Message: cmd,
	}
}

func (ctx *VmContext) setWindowSize(containerId, execId string, size *WindowSize) {
	if ctx.vmHyperstartAPIVersion <= 4242 {
		ctx.setWindowSize4242(containerId, execId, size)
		return
	}
	cmd := hyperstartapi.WindowSizeMessage{
		Container: containerId,
		Process:   execId,
		Row:       size.Row,
		Column:    size.Column,
	}

	ctx.vm <- &hyperstartCmd{
		Code:    hyperstartapi.INIT_WINSIZE,
		Message: cmd,
	}
}

func (ctx *VmContext) onlineCpuMem(cmd *OnlineCpuMemCommand) {
	ctx.vm <- &hyperstartCmd{
		Code: hyperstartapi.INIT_ONLINECPUMEM,
	}
}

func (ctx *VmContext) execCmd(execId string, cmd *hyperstartapi.ExecCommand, tty *TtyIO, result chan<- error) {
	cmd.Process.Stdio = ctx.ptys.nextAttachId()
	if !cmd.Process.Terminal {
		cmd.Process.Stderr = ctx.ptys.nextAttachId()
	}
	ctx.lock.Lock()
	defer ctx.lock.Unlock()
	if _, existed := ctx.vmExec[execId]; existed || execId == "init" {
		result <- fmt.Errorf("process id conflicts, the process of the id %s already exists", execId)
		return
	}
	ctx.vmExec[execId] = cmd
	ctx.ptys.ptyConnect(false, cmd.Process.Terminal, cmd.Process.Stdio, cmd.Process.Stderr, tty)
	ctx.vm <- &hyperstartCmd{
		Code:    hyperstartapi.INIT_EXECCMD,
		Message: cmd,
		result:  result,
	}
}

func (ctx *VmContext) killCmd(container string, signal syscall.Signal, result chan<- error) {
	ctx.vm <- &hyperstartCmd{
		Code: hyperstartapi.INIT_KILLCONTAINER,
		Message: hyperstartapi.KillCommand{
			Container: container,
			Signal:    signal,
		},
		result: result,
	}
}

func (ctx *VmContext) attachCmd(cmd *AttachCommand, result chan<- error) {
	ctx.lock.Lock()
	defer ctx.lock.Unlock()

	c, ok := ctx.containers[cmd.Container]
	if !ok {
		estr := fmt.Sprintf("cannot find container %s to attach", cmd.Container)
		ctx.Log(ERROR, estr)
		result <- errors.New(estr)
		return
	}

	ctx.attachTty2Container(c.process, cmd)
	if cmd.Size != nil {
		ctx.setWindowSize(cmd.Container, "init", cmd.Size)
	}

	result <- nil
}

func (ctx *VmContext) attachTty2Container(process *hyperstartapi.Process, cmd *AttachCommand) {
	session := process.Stdio
	ctx.ptys.ptyConnect(true, process.Terminal, session, process.Stderr, cmd.Streams)
	glog.V(1).Infof("Connecting tty for %s on session %d", cmd.Container, session)
}

func (ctx *VmContext) startPod() {
	ctx.vm <- &hyperstartCmd{
		Code:    hyperstartapi.INIT_STARTPOD,
		Message: ctx.networks.sandboxInfo(),
	}
}

func (ctx *VmContext) shutdownVM(err bool, msg string) {
	if err {
		ctx.reportVmFault(msg)
		glog.Error("Shutting down because of an exception: ", msg)
	}
	ctx.setTimeout(10)
	ctx.vm <- &hyperstartCmd{Code: hyperstartapi.INIT_DESTROYPOD}
}

func (ctx *VmContext) poweroffVM(err bool, msg string) {
	if err {
		glog.Error("Shutting down because of an exception: ", msg)
	}
	//REFACTOR: kill directly instead of DCtx.Shutdown() and send shutdown information
	ctx.Log(INFO, "poweroff vm based on command: %s", msg)
	if ctx != nil && ctx.handler != nil {
		ctx.DCtx.Kill(ctx)
	}
}

func (ctx *VmContext) handleGenericOperation(goe *GenericOperation) {
	for _, allowd := range goe.State {
		if ctx.current == allowd {
			glog.V(3).Infof("handle GenericOperation(%s) on state(%s)", goe.OpName, ctx.current)
			goe.OpFunc(ctx, goe.Result)
			return
		}
	}

	glog.V(3).Infof("GenericOperation(%s) is unsupported on state(%s)", goe.OpName, ctx.current)
	goe.Result <- fmt.Errorf("GenericOperation(%s) is unsupported on state(%s)", goe.OpName, ctx.current)
}

// state machine
func unexpectedEventHandler(ctx *VmContext, ev VmEvent, state string) {
	switch ev.Event() {
	case COMMAND_SHUTDOWN,
		COMMAND_RELEASE,
		COMMAND_PAUSEVM:
		ctx.reportUnexpectedRequest(ev, state)
	default:
		glog.Warning("got unexpected event during ", state)
	}
}

func stateRunning(ctx *VmContext, ev VmEvent) {
	switch ev.Event() {
	case COMMAND_ONLINECPUMEM:
		ctx.onlineCpuMem(ev.(*OnlineCpuMemCommand))
	case COMMAND_WINDOWSIZE:
		cmd := ev.(*WindowSizeCommand)
		ctx.setWindowSize(cmd.ContainerId, cmd.ExecId, cmd.Size)
	case COMMAND_GET_POD_STATS:
		ctx.reportPodStats(ev)
	case COMMAND_SHUTDOWN:
		ctx.Log(INFO, "got shutdown command, shutting down")
		ctx.shutdownVM(false, "")
		ctx.Become(stateTerminating, StateTerminating)
	case COMMAND_RELEASE:
		ctx.Log(INFO, "pod is running, got release command, let VM fly")
		ctx.Become(nil, StateNone)
		ctx.reportSuccess("", nil)
	case COMMAND_ACK:
		ack := ev.(*CommandAck)
		ctx.Log(DEBUG, "[running] got hyperstart ack to %d", ack.reply.Code)
		switch ack.reply.Code {
		case hyperstartapi.INIT_STARTPOD:
			ctx.Log(INFO, "pod start success: %s", string(ack.msg))
			ctx.reportSuccess("Start POD success", []byte{})
			//TODO: the payload is the persist info, will deal with this later
		default:
		}
	case EVENT_INIT_CONNECTED:
		ctx.Log(INFO, "hyperstart is ready to accept vm commands")
		ctx.reportVmRun()
	case EVENT_VM_EXIT, ERROR_VM_START_FAILED:
		ctx.Log(INFO, "VM has exit, or not started at all (%d)", ev.Event())
		ctx.reportVmShutdown()
		ctx.Close()
	case EVENT_VM_TIMEOUT: // REFACTOR: we do not set timeout for prepare devices after the refactor, then we do not need wait this event any more
		ctx.Log(ERROR, "REFACTOR: should be no time in running state at all")
	case ERROR_INIT_FAIL: // VM connection Failure
		reason := ev.(*InitFailedEvent).Reason
		ctx.Log(ERROR, reason)
		ctx.poweroffVM(true, "connection to vm broken")
		ctx.Close()
	case ERROR_INTERRUPTED:
		glog.Info("Connection interrupted, quit...")
		ctx.poweroffVM(true, "connection to vm broken")
		ctx.Close()
	case ERROR_CMD_FAIL:
		ack := ev.(*CommandError)
		switch ack.reply.Code {
		case hyperstartapi.INIT_NEWCONTAINER:
			//TODO: report fail message to the caller
		case hyperstartapi.INIT_STARTPOD:
			reason := "Start POD failed"
			ctx.reportVmFault(reason)
			ctx.Log(ERROR, reason)
		default:
		}
	case GENERIC_OPERATION:
		ctx.handleGenericOperation(ev.(*GenericOperation))
	default:
		unexpectedEventHandler(ctx, ev, "pod running")
	}
}

func stateTerminating(ctx *VmContext, ev VmEvent) {
	switch ev.Event() {
	case EVENT_VM_EXIT:
		glog.Info("Got VM shutdown event while terminating, go to cleaning up")
		ctx.reportVmShutdown()
		ctx.Close()
	case EVENT_VM_KILL:
		glog.Info("Got VM force killed message, go to cleaning up")
		ctx.reportVmShutdown()
		ctx.Close()
	case COMMAND_RELEASE:
		glog.Info("vm terminating, got release")
	case COMMAND_ACK:
		ack := ev.(*CommandAck)
		glog.V(1).Infof("[Terminating] Got reply to %d: '%s'", ack.reply, string(ack.msg))
		if ack.reply.Code == hyperstartapi.INIT_DESTROYPOD {
			glog.Info("POD destroyed ", string(ack.msg))
			ctx.poweroffVM(false, "")
		}
	case ERROR_CMD_FAIL:
		ack := ev.(*CommandError)
		if ack.reply.Code == hyperstartapi.INIT_DESTROYPOD {
			glog.Warning("Destroy pod failed")
			ctx.poweroffVM(true, "Destroy pod failed")
			ctx.Close()
		}
	case EVENT_VM_TIMEOUT:
		glog.Warning("VM did not exit in time, try to stop it")
		ctx.poweroffVM(true, "vm terminating timeout")
		ctx.Close()
	case ERROR_INTERRUPTED:
		interruptEv := ev.(*Interrupted)
		glog.V(1).Info("Connection interrupted while terminating: %s", interruptEv.Reason)
	case GENERIC_OPERATION:
		ctx.handleGenericOperation(ev.(*GenericOperation))
	default:
		unexpectedEventHandler(ctx, ev, "terminating")
	}
}
<|endoftext|>