<commit_before>package main

import (
	"flag"
	"fmt"
	"log"
	"net/http"
	"os"

	"github.com/fweikert/continuous-integration/metrics/clients"
	"github.com/fweikert/continuous-integration/metrics/metrics"
	"github.com/fweikert/continuous-integration/metrics/publishers"
	"github.com/fweikert/continuous-integration/metrics/service"
)

var (
	projectID             = flag.String("project_id", "bazel-untrusted", "ID of the GCP project.")
	datastoreSettingsName = flag.String("datastore_settings_name", "MetricSettings", "Name of the settings entity in Datastore.")
	testMode              = flag.Bool("test", false, "If true, the service will collect and publish all metrics immediately and only once.")
)

const megaByte = 1024 * 1024

func handleError(metricName string, err error) {
	fmt.Printf("[%s] %v\n", metricName, err)
}

func handleRequest(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintln(w, "You should try https://bazel.build")
}

func main() {
	flag.Parse()

	settings, err := ReadSettingsFromDatastore(*projectID, *datastoreSettingsName)
	if err != nil {
		log.Fatalf("Could not read settings from Datastore: %v", err)
	}
	pipelines, err := settings.GetPipelineIDs()
	if err != nil {
		log.Fatalf("Could not get Buildkite pipeline IDs from Datastore: %v", err)
	}
	if len(pipelines) == 0 {
		log.Fatalf("No pipelines were specified.")
	}

	/*
		bk, err := clients.CreateBuildkiteClient(settings.BuildkiteApiToken, settings.BuildkiteDebug)
		if err != nil {
			log.Fatalf("Cannot create Buildkite client: %v", err)
		}
	*/

	gcs, err := clients.CreateGcsClient()
	if err != nil {
		log.Fatalf("Cannot create GCS client: %v", err)
	}

	/*
		stackdriverClient, err := clients.CreateStackdriverClient()
		if err != nil {
			log.Fatalf("Cannot create Stackdriver client: %v", err)
		}

		stackdriver := publishers.CreateStackdriverPublisher(stackdriverClient, *projectID)
	*/

	cloudSql, err := publishers.CreateCloudSqlPublisher(settings.CloudSqlUser, settings.CloudSqlPassword, settings.CloudSqlInstance, settings.CloudSqlDatabase, settings.CloudSqlLocalPort)
	if err != nil {
		log.Fatalf("Failed to set up Cloud SQL publisher: %v", err)
	}

	/*
		stdout := publishers.CreateStdoutPublisher(publishers.Csv)
	*/

	srv := service.CreateService(handleError)

	/*
		// TODO: support multiple organizations
		platformLoad := metrics.CreatePlatformLoad(bk, 100, settings.BuildkiteOrgs...)
		srv.AddMetric(platformLoad, 60, stackdriver)

		buildsPerChange := metrics.CreateBuildsPerChange(bk, 500, pipelines...)
		srv.AddMetric(buildsPerChange, 60, stdout)

		buildSuccess := metrics.CreateBuildSuccess(bk, 200, pipelines...)
		srv.AddMetric(buildSuccess, 60, stdout)
	*/

	flakiness := metrics.CreateFlakiness(gcs, "bazel-buildkite-stats", "flaky-tests-bep", pipelines...)
	srv.AddMetric(flakiness, 60, cloudSql)

	/*
		pid := &data.PipelineID{Org: "bazel", Slug: "google-bazel-presubmit"}

		macPerformance := metrics.CreateMacPerformance(bk, 20, pid) // TODO: pipelines...)
		srv.AddMetric(macPerformance, 60, stdout)

		pipelinePerformance := metrics.CreatePipelinePerformance(bk, 20, pipelines...)
		srv.AddMetric(pipelinePerformance, 60, stdout)

		platformSignificance := metrics.CreatePlatformSignificance(bk, 100, pipelines...)
		srv.AddMetric(platformSignificance, 24*60, stdout)

		platformUsage := metrics.CreatePlatformUsage(bk, 100, settings.BuildkiteOrgs...)
		srv.AddMetric(platformUsage, 60, stdout)

		releaseDownloads := metrics.CreateReleaseDownloads(settings.GitHubOrg,
			settings.GitHubRepo,
			settings.GitHubApiToken, megaByte)
		srv.AddMetric(releaseDownloads, 12*60, stdout)

		workerAvailability := metrics.CreateWorkerAvailability(bk, settings.BuildkiteOrgs...)
		srv.AddMetric(workerAvailability, 60, stdout)
	*/

	if *testMode {
		log.Println("[Test mode] Running all jobs exactly once...")
		srv.RunJobsOnce()
		os.Exit(0)
	}

	srv.Start()
	http.HandleFunc("/", handleRequest)

	port := os.Getenv("PORT")
	if port == "" {
		port = "8080"
	}
	log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), nil))
}
<commit_msg>Enable all metrics with the CloudSQL publisher<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"net/http"
	"os"

	"github.com/fweikert/continuous-integration/metrics/clients"
	"github.com/fweikert/continuous-integration/metrics/metrics"
	"github.com/fweikert/continuous-integration/metrics/publishers"
	"github.com/fweikert/continuous-integration/metrics/service"
)

var (
	projectID             = flag.String("project_id", "bazel-untrusted", "ID of the GCP project.")
	datastoreSettingsName = flag.String("datastore_settings_name", "MetricSettings", "Name of the settings entity in Datastore.")
	testMode              = flag.Bool("test", false, "If true, the service will collect and publish all metrics immediately and only once.")
)

const megaByte = 1024 * 1024

func handleError(metricName string, err error) {
	fmt.Printf("[%s] %v\n", metricName, err)
}

func handleRequest(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintln(w, "You should try https://bazel.build")
}

func main() {
	flag.Parse()

	settings, err := ReadSettingsFromDatastore(*projectID, *datastoreSettingsName)
	if err != nil {
		log.Fatalf("Could not read settings from Datastore: %v", err)
	}
	pipelines, err := settings.GetPipelineIDs()
	if err != nil {
		log.Fatalf("Could not get Buildkite pipeline IDs from Datastore: %v", err)
	}
	if len(pipelines) == 0 {
		log.Fatalf("No pipelines were specified.")
	}

	bk, err := clients.CreateBuildkiteClient(settings.BuildkiteApiToken, settings.BuildkiteDebug)
	if err != nil {
		log.Fatalf("Cannot create Buildkite client: %v", err)
	}

	gcs, err := clients.CreateGcsClient()
	if err != nil {
		log.Fatalf("Cannot create GCS client: %v", err)
	}

	/*
		stackdriverClient, err := clients.CreateStackdriverClient()
		if err != nil {
			log.Fatalf("Cannot create Stackdriver client: %v", err)
		}

		stackdriver := publishers.CreateStackdriverPublisher(stackdriverClient, *projectID)
	*/

	cloudSql, err := publishers.CreateCloudSqlPublisher(settings.CloudSqlUser, settings.CloudSqlPassword, settings.CloudSqlInstance, settings.CloudSqlDatabase, settings.CloudSqlLocalPort)
	if err != nil {
		log.Fatalf("Failed to set up Cloud SQL publisher: %v", err)
	}

	/*
		stdout := publishers.CreateStdoutPublisher(publishers.Csv)
	*/

	srv := service.CreateService(handleError)

	platformLoad := metrics.CreatePlatformLoad(bk, 100, settings.BuildkiteOrgs...)
	srv.AddMetric(platformLoad, 60, cloudSql)

	buildsPerChange := metrics.CreateBuildsPerChange(bk, 500, pipelines...)
	srv.AddMetric(buildsPerChange, 60, cloudSql)

	buildSuccess := metrics.CreateBuildSuccess(bk, 200, pipelines...)
	srv.AddMetric(buildSuccess, 60, cloudSql)

	flakiness := metrics.CreateFlakiness(gcs, "bazel-buildkite-stats", "flaky-tests-bep", pipelines...)
	srv.AddMetric(flakiness, 60, cloudSql)

	macPerformance := metrics.CreateMacPerformance(bk, 20, pipelines...)
	srv.AddMetric(macPerformance, 60, cloudSql)

	pipelinePerformance := metrics.CreatePipelinePerformance(bk, 20, pipelines...)
	srv.AddMetric(pipelinePerformance, 60, cloudSql)

	platformSignificance := metrics.CreatePlatformSignificance(bk, 100, pipelines...)
	srv.AddMetric(platformSignificance, 24*60, cloudSql)

	platformUsage := metrics.CreatePlatformUsage(bk, 100, settings.BuildkiteOrgs...)
	srv.AddMetric(platformUsage, 60, cloudSql)

	releaseDownloads := metrics.CreateReleaseDownloads(settings.GitHubOrg,
		settings.GitHubRepo,
		settings.GitHubApiToken, megaByte)
	srv.AddMetric(releaseDownloads, 12*60, cloudSql)

	workerAvailability := metrics.CreateWorkerAvailability(bk, settings.BuildkiteOrgs...)
	srv.AddMetric(workerAvailability, 60, cloudSql)

	if *testMode {
		log.Println("[Test mode] Running all jobs exactly once...")
		srv.RunJobsOnce()
		os.Exit(0)
	}

	srv.Start()
	http.HandleFunc("/", handleRequest)

	port := os.Getenv("PORT")
	if port == "" {
		port = "8080"
	}
	log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), nil))
}
<|endoftext|>


<commit_before>package mithril

import "testing"

func TestCreateElement(t *testing.T) {
	el := M("div#id-value.lol.class-name[data1='value1'][data2=\"value2\"][data3]")
	if el == nil {
		t.Fatalf("Expected element to be a VirtualElement object but it was nil")
	}
}

func TestElementTag(t *testing.T) {
	if el := M("li"); el.Tag != "li" {
		t.Fatalf("Expected element tag to be \"li\" but it was %s", el.Tag)
	}
}

func TestElementID(t *testing.T) {
	if el := M("div#id-value"); el.Attr("id") != "id-value" {
		t.Fatalf("Expected element ID to be id-value but it was %s", el.Attr("id"))
	}
}

func TestCreateElementChildren(t *testing.T) {
	el := M(
		"div#obj1",
		M("div#obj2"),
	)
	if _, ok := el.Children.(*VirtualElement); !ok {
		t.Fatalf("Expected element.Children to be a VirtualElement")
	}
}

func TestCreateElementWithAttr(t *testing.T) {
	el := M("ul", []Attribute{
		NewStringAttr("id", "listview"),
	})
	if el.Attr("id") != "listview" {
		t.Fatalf("Expected element ID to be a listview but it was %s", el.Attr("id"))
	}
}
<commit_msg>new css classes testing<commit_after>package mithril

import "testing"

func TestCreateElement(t *testing.T) {
	el := M("div#id-value.lol.class-name[data1='value1'][data2=\"value2\"][data3]")
	if el == nil {
		t.Fatalf("Expected element to be a VirtualElement object but it was nil")
	}
}

func TestElementTag(t *testing.T) {
	if el := M("li"); el.Tag != "li" {
		t.Fatalf("Expected element tag to be \"li\" but it was %s", el.Tag)
	}
}

func TestElementID(t *testing.T) {
	if el := M("div#id-value"); el.Attr("id") != "id-value" {
		t.Fatalf("Expected element ID to be id-value but it was %s", el.Attr("id"))
	}
}

func TestCreateElementChildren(t *testing.T) {
	el := M(
		"div#obj1",
		M("div#obj2"),
	)
	if _, ok := el.Children.(*VirtualElement); !ok {
		t.Fatalf("Expected element.Children to be a VirtualElement")
	}
}

func TestCreateElementWithAttr(t *testing.T) {
	el := M("ul", []Attribute{
		NewStringAttr("id", "listview"),
	})
	if el.Attr("id") != "listview" {
		t.Fatalf("Expected element ID to be a listview but it was %s", el.Attr("id"))
	}
}

func TestCreateElementWithClasses(t *testing.T) {
	el := M("ul", []Attribute{
		NewStringAttr("id", "listview"),
		NewClassAttr("class-1", "class-2", "class-3", "class-4"),
	})
	expected := "class-1 class-2 class-3 class-4"
	if el.Attr("class") != expected {
		t.Fatalf("Expected element class to be %s but it was %s", expected, el.Attr("class"))
	}
}
<|endoftext|>


<commit_before>package node

//IMPORT parts ----------------------------------------------------------
import (
	// ggv "code.google.com/p/gographviz"
	"fmt"
	sender "github.com/tgermain/grandRepositorySky/communicator/sender"
	"github.com/tgermain/grandRepositorySky/dht"
	"github.com/tgermain/grandRepositorySky/shared"
	"time"
)

//Const parts -----------------------------------------------------------
const SPACESIZE = 160
const UPDATEPERIOD = time.Minute
const HEARTBEATPERIOD = time.Second * 10
const HEARBEATTIMEOUT = time.Second * 2

//Gloabl var part -------------------------------------------------------

//Objects parts ---------------------------------------------------------
type DHTnode struct {
	fingers     []*fingerEntry
	Successor   *shared.DistantNode
	Predecessor *shared.DistantNode
	commLib     *sender.SenderLink
}

type fingerEntry struct {
	IdKey    string
	nodeResp *shared.DistantNode
}

//Method parts ----------------------------------------------------------

func (currentNode *DHTnode) JoinRing(newNode *shared.DistantNode) {
	currentNode.commLib.SendJoinRing(newNode)
}

func (currentNode *DHTnode) AddToRing(newNode *shared.DistantNode) {
	whereToInsert := currentNode.Lookup(newNode.Id)
	currentNode.commLib.SendUpdateSuccessor(whereToInsert, newNode)
}

//Tell your actual Successor that you are no longer its predecessor
//set your succesor to the new value
//tell to your new Successor that you are its predecessor
func (d *DHTnode) UpdateSuccessor(newNode *shared.DistantNode) {
	//possible TODO : condition on the origin of the message for this sending ?
	if d.Successor.Id != newNode.Id {
		// if d.Successor.Id != newNode.Id {
		d.commLib.SendUpdatePredecessor(d.Successor, newNode)
		// }

		d.Successor = newNode
		d.commLib.SendUpdatePredecessor(newNode, d.ToDistantNode())

	} else {
		shared.Logger.Info("Succesor stable !!")
		d.PrintNodeInfo()
	}
}

func (d *DHTnode) UpdatePredecessor(newNode *shared.DistantNode) {
	if d.Predecessor.Id != newNode.Id {

		d.Predecessor = newNode
		d.commLib.SendUpdateSuccessor(newNode, d.ToDistantNode())
		// d.UpdateFingerTable()

	} else {
		shared.Logger.Info("Predecessor stable !!")
		d.PrintNodeInfo()
	}
}

func (currentNode *DHTnode) ToDistantNode() *shared.DistantNode {
	return &shared.DistantNode{
		shared.LocalId,
		shared.LocalIp,
		shared.LocalPort,
	}
}

func (currentNode *DHTnode) IsResponsible(IdToSearch string) bool {
	switch {
	case shared.LocalId == currentNode.Successor.Id:
		{
			return true
		}
	case dht.Between(shared.LocalId, currentNode.Successor.Id, IdToSearch):
		{
			return true
		}
	default:
		{
			return false
		}
	}
}

func (currentNode *DHTnode) Lookup(IdToSearch string) *shared.DistantNode {
	shared.Logger.Info("Node [%s] made a lookup to [%s]\n", shared.LocalId, IdToSearch)
	// currentNode.PrintNodeInfo()
	if currentNode.IsResponsible(IdToSearch) {
		//replace with send
		return currentNode.ToDistantNode()
	} else {
		// fmt.Println("go to the next one")
		//TODO use the fingers table here
		responseChan := currentNode.commLib.SendLookup(currentNode.FindClosestNode(IdToSearch), IdToSearch)
		select {
		case res := <-responseChan:
			return &res
		//case of timeout ?
		case <-time.After(time.Second * 2):
			shared.Logger.Error("Lookup for %s timeout", IdToSearch)
			return nil
		}
	}

}

func (currentNode *DHTnode) FindClosestNode(IdToSearch string) *shared.DistantNode {
	bestFinger := currentNode.Successor

	minDistance := dht.Distance([]byte(currentNode.Successor.Id), []byte(IdToSearch), SPACESIZE)
	// fmt.Println("distance Successor " + minDistance.String())
	// var bestIndex int
	for _, v := range currentNode.fingers {
		if v != nil {
			if dht.Between(v.nodeResp.Id, shared.LocalId, IdToSearch) {

				//If the finger lead the node to itself, it's not an optimization
				if v.nodeResp.Id != shared.LocalId {

					//if a member of finger table brought closer than the actual one, we udate the value of minDistance and of the chosen finger
					currentDistance := dht.Distance([]byte(v.nodeResp.Id), []byte(IdToSearch), SPACESIZE)

					// x.cmp(y)
					// -1 if x <  y
					//  0 if x == y
					// +1 if x >  y

					if minDistance.Cmp(currentDistance) == 1 {
						fmt.Printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Better finger ellected ! Lookup for [%s] ->[%s] instead of [%s]\n", IdToSearch, v.nodeResp.Id, bestFinger.Id)
						// fmt.Println("Old best distance " + minDistance.String())
						// fmt.Println("New best distance " + currentDistance.String())
						// currentNode.PrintNodeInfo()
						// bestIndex = i
						// v.tmp.PrintNodeInfo()
						minDistance = currentDistance
						bestFinger = v.nodeResp
					}
				}
			}
		}
	}
	// fmt.Printf("From [%s] We have found the bes way to go to [%s] : we go throught finger[%d], [%s]\n", shared.LocalId, IdToSearch, bestIndex, bestFinger.Id)
	return bestFinger
}

func (node *DHTnode) UpdateFingerTable() {
	// fmt.Printf("****************************************************************Node [%s] : init finger table \n", shared.LocalId)
	for i := 0; i < SPACESIZE; i++ {
		// fmt.Printf("Calculatin fingers [%d]\n", i)
		//TODO make a condition to voId to always calculate the fingerId
		fingerId, _ := dht.CalcFinger([]byte(shared.LocalId), i+1, SPACESIZE)
		responsibleNode := node.Lookup(fingerId)
		node.fingers[i] = &fingerEntry{fingerId, &shared.DistantNode{responsibleNode.Id, responsibleNode.Ip, responsibleNode.Port}}

	}
	// fmt.Println("****************************************************************Fingers table init DONE : ")
}

func (node *DHTnode) PrintRing() {
	daString := ""
	node.PrintNodeName(&daString)
	node.commLib.SendPrintRing(node.Successor, &daString)
}

func (node *DHTnode) PrintNodeName(currentString *string) {
	*currentString += fmt.Sprintf("%s\n", shared.LocalId)
}

func (node *DHTnode) PrintNodeInfo() {
	shared.Logger.Info("---------------------------------")
	shared.Logger.Info("Node info")
	shared.Logger.Info("---------------------------------")
	shared.Logger.Info("	Id			%s", shared.LocalId)
	shared.Logger.Info("	Ip			%s", shared.LocalIp)
	shared.Logger.Info("	Port		%s", shared.LocalPort)
	shared.Logger.Info(" 	Succesor	%s", node.Successor.Id)
	shared.Logger.Info(" 	Predecesor	%s", node.Predecessor.Id)
	// fmt.Println("  Fingers table :")
	// fmt.Println("  ---------------------------------")
	// fmt.Println("  Index		Idkey			IdNode ")
	// for i, v := range node.fingers {
	// 	if v != nil {
	// 		fmt.Printf("  %d 		%s					%s\n", i, v.IdKey, v.IdResp)
	// 	}
	// }
	shared.Logger.Info("---------------------------------")
}

// func (node *DHTnode) gimmeGraph(g *ggv.Graph, firstNodeId *string) string {
// 	if &shared.LocalId == firstNodeId {
// 		return g.String()
// 	} else {
// 		if g == nil {
// 			g = ggv.NewGraph()
// 			g.SetName("DHTRing")
// 			g.SetDir(true)
// 		}
// 		if firstNodeId == nil {
// 			firstNodeId = &shared.LocalId
// 		}
// 		g.AddNode(g.Name, shared.LocalId, nil)
// 		g.AddNode(g.Name, node.Successor.Id, nil)
// 		g.AddNode(g.Name, node.predecessor.Id, nil)
// 		// g.AddEdge(shared.LocalId, node.Successor.Id, true, map[string]string{
// 		// 	"label": "succ",
// 		// })
// 		// g.AddEdge(shared.LocalId, node.predecessor.Id, true, map[string]string{
// 		// 	"label": "pred",
// 		// })

// 		for i, v := range node.fingers {
// 			g.AddEdge(shared.LocalId, v.IdKey, true, map[string]string{
// 				"label":         fmt.Sprintf("\"%s.%d\"", shared.LocalId, i),
// 				"label_scheme":  "3",
// 				"decorate":      "true",
// 				"labelfontsize": "5.0",
// 				"labelfloat":    "true",
// 				"color":         "blue",
// 			})
// 		}

// 		//recursion !
// 		//TODO Successor.tmp not accessible anymore later
// 		return node.Successor.tmp.gimmeGraph(g, firstNodeId)

// 	}
// }

func (d *DHTnode) updateFingersRoutine() {
	shared.Logger.Info("Starting update fingers table routing")
	for {
		time.Sleep(UPDATEPERIOD)
		shared.Logger.Info("Auto updating finger table of node %s", shared.LocalId)
		d.UpdateFingerTable()
	}
}

func (d *DHTnode) heartBeatRoutine() {
	shared.Logger.Info("Starting heartBeat routing")
	for {
		time.Sleep(HEARTBEATPERIOD)
		d.sendHeartBeat(d.Successor)
	}
}

func (d *DHTnode) sendHeartBeat(destination *shared.DistantNode) {

	responseChan := d.commLib.SendHeartBeat(d.Successor)
	select {
	case <-responseChan:
		{
			//Everything this node is alive. Do nothing more
		}
	//case of timeout ?
	case <-time.After(HEARBEATTIMEOUT):
		shared.Logger.Error("heartBeat to %s timeout", destination.Id)
		//DANGER
	}
}

//other functions parts --------------------------------------------------------
//Create the node with it's communication interface
//Does not start to liten for message
func MakeNode() (*DHTnode, *sender.SenderLink) {
	daComInterface := sender.NewSenderLink()
	daNode := DHTnode{
		fingers: make([]*fingerEntry, SPACESIZE),
		commLib: daComInterface,
	}
	mySelf := daNode.ToDistantNode()
	daNode.Successor = mySelf

	daNode.Predecessor = mySelf
	// initialization of fingers table is done while adding the node to the ring
	// The fingers table of the first node of a ring is initialized when a second node is added to the ring

	//Initialize the finger table with each finger pointing to the node frehly created itself
	shared.Logger.Info("New node [%.5s] createde", shared.LocalId)
	go daNode.heartBeatRoutine()
	go daNode.updateFingersRoutine()

	return &daNode, daComInterface
}
<commit_msg>adding consts for lookup timeout<commit_after>package node

//IMPORT parts ----------------------------------------------------------
import (
	// ggv "code.google.com/p/gographviz"
	"fmt"
	sender "github.com/tgermain/grandRepositorySky/communicator/sender"
	"github.com/tgermain/grandRepositorySky/dht"
	"github.com/tgermain/grandRepositorySky/shared"
	"time"
)

//Const parts -----------------------------------------------------------
const SPACESIZE = 160
const UPDATEPERIOD = time.Minute
const HEARTBEATPERIOD = time.Second * 10
const HEARBEATTIMEOUT = time.Second * 2
const LOOKUPTIMEOUT = time.Second * 2

//Gloabl var part -------------------------------------------------------

//Objects parts ---------------------------------------------------------
type DHTnode struct {
	fingers     []*fingerEntry
	Successor   *shared.DistantNode
	Predecessor *shared.DistantNode
	commLib     *sender.SenderLink
}

type fingerEntry struct {
	IdKey    string
	nodeResp *shared.DistantNode
}

//Method parts ----------------------------------------------------------

func (currentNode *DHTnode) JoinRing(newNode *shared.DistantNode) {
	currentNode.commLib.SendJoinRing(newNode)
}

func (currentNode *DHTnode) AddToRing(newNode *shared.DistantNode) {
	whereToInsert := currentNode.Lookup(newNode.Id)
	currentNode.commLib.SendUpdateSuccessor(whereToInsert, newNode)
}

//Tell your actual Successor that you are no longer its predecessor
//set your succesor to the new value
//tell to your new Successor that you are its predecessor
func (d *DHTnode) UpdateSuccessor(newNode *shared.DistantNode) {
	//possible TODO : condition on the origin of the message for this sending ?
	if d.Successor.Id != newNode.Id {
		// if d.Successor.Id != newNode.Id {
		d.commLib.SendUpdatePredecessor(d.Successor, newNode)
		// }

		d.Successor = newNode
		d.commLib.SendUpdatePredecessor(newNode, d.ToDistantNode())

	} else {
		shared.Logger.Info("Succesor stable !!")
		d.PrintNodeInfo()
	}
}

func (d *DHTnode) UpdatePredecessor(newNode *shared.DistantNode) {
	if d.Predecessor.Id != newNode.Id {

		d.Predecessor = newNode
		d.commLib.SendUpdateSuccessor(newNode, d.ToDistantNode())
		// d.UpdateFingerTable()

	} else {
		shared.Logger.Info("Predecessor stable !!")
		d.PrintNodeInfo()
	}
}

func (currentNode *DHTnode) ToDistantNode() *shared.DistantNode {
	return &shared.DistantNode{
		shared.LocalId,
		shared.LocalIp,
		shared.LocalPort,
	}
}

func (currentNode *DHTnode) IsResponsible(IdToSearch string) bool {
	switch {
	case shared.LocalId == currentNode.Successor.Id:
		{
			return true
		}
	case dht.Between(shared.LocalId, currentNode.Successor.Id, IdToSearch):
		{
			return true
		}
	default:
		{
			return false
		}
	}
}

func (currentNode *DHTnode) Lookup(IdToSearch string) *shared.DistantNode {
	shared.Logger.Info("Node [%s] made a lookup to [%s]\n", shared.LocalId, IdToSearch)
	// currentNode.PrintNodeInfo()
	if currentNode.IsResponsible(IdToSearch) {
		//replace with send
		return currentNode.ToDistantNode()
	} else {
		// fmt.Println("go to the next one")
		//TODO use the fingers table here
		responseChan := currentNode.commLib.SendLookup(currentNode.FindClosestNode(IdToSearch), IdToSearch)
		select {
		case res := <-responseChan:
			return &res
		//case of timeout ?
		case <-time.After(LOOKUPTIMEOUT):
			shared.Logger.Error("Lookup for %s timeout", IdToSearch)
			return nil
		}
	}

}

func (currentNode *DHTnode) FindClosestNode(IdToSearch string) *shared.DistantNode {
	bestFinger := currentNode.Successor

	minDistance := dht.Distance([]byte(currentNode.Successor.Id), []byte(IdToSearch), SPACESIZE)
	// fmt.Println("distance Successor " + minDistance.String())
	// var bestIndex int
	for _, v := range currentNode.fingers {
		if v != nil {
			if dht.Between(v.nodeResp.Id, shared.LocalId, IdToSearch) {

				//If the finger lead the node to itself, it's not an optimization
				if v.nodeResp.Id != shared.LocalId {

					//if a member of finger table brought closer than the actual one, we udate the value of minDistance and of the chosen finger
					currentDistance := dht.Distance([]byte(v.nodeResp.Id), []byte(IdToSearch), SPACESIZE)

					// x.cmp(y)
					// -1 if x <  y
					//  0 if x == y
					// +1 if x >  y

					if minDistance.Cmp(currentDistance) == 1 {
						fmt.Printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Better finger ellected ! Lookup for [%s] ->[%s] instead of [%s]\n", IdToSearch, v.nodeResp.Id, bestFinger.Id)
						// fmt.Println("Old best distance " + minDistance.String())
						// fmt.Println("New best distance " + currentDistance.String())
						// currentNode.PrintNodeInfo()
						// bestIndex = i
						// v.tmp.PrintNodeInfo()
						minDistance = currentDistance
						bestFinger = v.nodeResp
					}
				}
			}
		}
	}
	// fmt.Printf("From [%s] We have found the bes way to go to [%s] : we go throught finger[%d], [%s]\n", shared.LocalId, IdToSearch, bestIndex, bestFinger.Id)
	return bestFinger
}

func (node *DHTnode) UpdateFingerTable() {
	// fmt.Printf("****************************************************************Node [%s] : init finger table \n", shared.LocalId)
	for i := 0; i < SPACESIZE; i++ {
		// fmt.Printf("Calculatin fingers [%d]\n", i)
		//TODO make a condition to voId to always calculate the fingerId
		fingerId, _ := dht.CalcFinger([]byte(shared.LocalId), i+1, SPACESIZE)
		responsibleNode := node.Lookup(fingerId)
		node.fingers[i] = &fingerEntry{fingerId, &shared.DistantNode{responsibleNode.Id, responsibleNode.Ip, responsibleNode.Port}}

	}
	// fmt.Println("****************************************************************Fingers table init DONE : ")
}

func (node *DHTnode) PrintRing() {
	daString := ""
	node.PrintNodeName(&daString)
	node.commLib.SendPrintRing(node.Successor, &daString)
}

func (node *DHTnode) PrintNodeName(currentString *string) {
	*currentString += fmt.Sprintf("%s\n", shared.LocalId)
}

func (node *DHTnode) PrintNodeInfo() {
	shared.Logger.Info("---------------------------------")
	shared.Logger.Info("Node info")
	shared.Logger.Info("---------------------------------")
	shared.Logger.Info("	Id			%s", shared.LocalId)
	shared.Logger.Info("	Ip			%s", shared.LocalIp)
	shared.Logger.Info("	Port		%s", shared.LocalPort)
	shared.Logger.Info(" 	Succesor	%s", node.Successor.Id)
	shared.Logger.Info(" 	Predecesor	%s", node.Predecessor.Id)
	// fmt.Println("  Fingers table :")
	// fmt.Println("  ---------------------------------")
	// fmt.Println("  Index		Idkey			IdNode ")
	// for i, v := range node.fingers {
	// 	if v != nil {
	// 		fmt.Printf("  %d 		%s					%s\n", i, v.IdKey, v.IdResp)
	// 	}
	// }
	shared.Logger.Info("---------------------------------")
}

// func (node *DHTnode) gimmeGraph(g *ggv.Graph, firstNodeId *string) string {
// 	if &shared.LocalId == firstNodeId {
// 		return g.String()
// 	} else {
// 		if g == nil {
// 			g = ggv.NewGraph()
// 			g.SetName("DHTRing")
// 			g.SetDir(true)
// 		}
// 		if firstNodeId == nil {
// 			firstNodeId = &shared.LocalId
// 		}
// 		g.AddNode(g.Name, shared.LocalId, nil)
// 		g.AddNode(g.Name, node.Successor.Id, nil)
// 		g.AddNode(g.Name, node.predecessor.Id, nil)
// 		// g.AddEdge(shared.LocalId, node.Successor.Id, true, map[string]string{
// 		// 	"label": "succ",
// 		// })
// 		// g.AddEdge(shared.LocalId, node.predecessor.Id, true, map[string]string{
// 		// 	"label": "pred",
// 		// })

// 		for i, v := range node.fingers {
// 			g.AddEdge(shared.LocalId, v.IdKey, true, map[string]string{
// 				"label":         fmt.Sprintf("\"%s.%d\"", shared.LocalId, i),
// 				"label_scheme":  "3",
// 				"decorate":      "true",
// 				"labelfontsize": "5.0",
// 				"labelfloat":    "true",
// 				"color":         "blue",
// 			})
// 		}

// 		//recursion !
// 		//TODO Successor.tmp not accessible anymore later
// 		return node.Successor.tmp.gimmeGraph(g, firstNodeId)

// 	}
// }

func (d *DHTnode) updateFingersRoutine() {
	shared.Logger.Info("Starting update fingers table routing")
	for {
		time.Sleep(UPDATEPERIOD)
		shared.Logger.Info("Auto updating finger table of node %s", shared.LocalId)
		d.UpdateFingerTable()
	}
}

func (d *DHTnode) heartBeatRoutine() {
	shared.Logger.Info("Starting heartBeat routing")
	for {
		time.Sleep(HEARTBEATPERIOD)
		d.sendHeartBeat(d.Successor)
	}
}

func (d *DHTnode) sendHeartBeat(destination *shared.DistantNode) {

	responseChan := d.commLib.SendHeartBeat(d.Successor)
	select {
	case <-responseChan:
		{
			//Everything this node is alive. Do nothing more
		}
	//case of timeout ?
	case <-time.After(HEARBEATTIMEOUT):
		shared.Logger.Error("heartBeat to %s timeout", destination.Id)
		//DANGER
	}
}

//other functions parts --------------------------------------------------------
//Create the node with it's communication interface
//Does not start to liten for message
func MakeNode() (*DHTnode, *sender.SenderLink) {
	daComInterface := sender.NewSenderLink()
	daNode := DHTnode{
		fingers: make([]*fingerEntry, SPACESIZE),
		commLib: daComInterface,
	}
	mySelf := daNode.ToDistantNode()
	daNode.Successor = mySelf

	daNode.Predecessor = mySelf
	// initialization of fingers table is done while adding the node to the ring
	// The fingers table of the first node of a ring is initialized when a second node is added to the ring

	//Initialize the finger table with each finger pointing to the node frehly created itself
	shared.Logger.Info("New node [%.5s] createde", shared.LocalId)
	go daNode.heartBeatRoutine()
	go daNode.updateFingersRoutine()

	return &daNode, daComInterface
}
<|endoftext|>


<commit_before>// Code generated by protoc-gen-go. DO NOT EDIT.
// source: github.com/google/cloudprober/message/message.proto

/*
Package message is a generated protocol buffer package.

It is generated from these files:
	github.com/google/cloudprober/message/message.proto

It has these top-level messages:
	Constants
	DataNode
	Message
*/
package message

import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"

// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package

type DataNode_Type int32

const (
	DataNode_UNKNOWN DataNode_Type = 0
	DataNode_CLIENT  DataNode_Type = 1
	DataNode_SERVER  DataNode_Type = 2
)

var DataNode_Type_name = map[int32]string{
	0: "UNKNOWN",
	1: "CLIENT",
	2: "SERVER",
}
var DataNode_Type_value = map[string]int32{
	"UNKNOWN": 0,
	"CLIENT":  1,
	"SERVER":  2,
}

func (x DataNode_Type) Enum() *DataNode_Type {
	p := new(DataNode_Type)
	*p = x
	return p
}
func (x DataNode_Type) String() string {
	return proto.EnumName(DataNode_Type_name, int32(x))
}
func (x *DataNode_Type) UnmarshalJSON(data []byte) error {
	value, err := proto.UnmarshalJSONEnum(DataNode_Type_value, data, "DataNode_Type")
	if err != nil {
		return err
	}
	*x = DataNode_Type(value)
	return nil
}
func (DataNode_Type) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 0} }

// Constants defines constants with default values.
type Constants struct {
	Magic            *uint64 `protobuf:"varint,1,opt,name=magic,def=257787339638762" json:"magic,omitempty"`
	XXX_unrecognized []byte  `json:"-"`
}

func (m *Constants) Reset()                    { *m = Constants{} }
func (m *Constants) String() string            { return proto.CompactTextString(m) }
func (*Constants) ProtoMessage()               {}
func (*Constants) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }

const Default_Constants_Magic uint64 = 257787339638762

func (m *Constants) GetMagic() uint64 {
	if m != nil && m.Magic != nil {
		return *m.Magic
	}
	return Default_Constants_Magic
}

// Datanode is something that see's a message AND can modify it.
type DataNode struct {
	Type *DataNode_Type `protobuf:"varint,1,opt,name=type,enum=message.DataNode_Type,def=1" json:"type,omitempty"`
	Name *string        `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"`
	// 8 bytes of timestamp in pcap-friendly network byte order.
	TimestampUsec    []byte `protobuf:"bytes,3,opt,name=timestamp_usec,json=timestampUsec" json:"timestamp_usec,omitempty"`
	XXX_unrecognized []byte `json:"-"`
}

func (m *DataNode) Reset()                    { *m = DataNode{} }
func (m *DataNode) String() string            { return proto.CompactTextString(m) }
func (*DataNode) ProtoMessage()               {}
func (*DataNode) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }

const Default_DataNode_Type DataNode_Type = DataNode_CLIENT

func (m *DataNode) GetType() DataNode_Type {
	if m != nil && m.Type != nil {
		return *m.Type
	}
	return Default_DataNode_Type
}

func (m *DataNode) GetName() string {
	if m != nil && m.Name != nil {
		return *m.Name
	}
	return ""
}

func (m *DataNode) GetTimestampUsec() []byte {
	if m != nil {
		return m.TimestampUsec
	}
	return nil
}

// Message is a message sent over the network.
// magic, seq, src and dst are required fields.
type Message struct {
	Magic *uint64 `protobuf:"fixed64,1,opt,name=magic" json:"magic,omitempty"`
	// 8 bytes of sequence in pcap-friendly network byte order.
	Seq []byte `protobuf:"bytes,2,opt,name=seq" json:"seq,omitempty"`
	// Datanodes seen by this message.
	Src              *DataNode   `protobuf:"bytes,3,opt,name=src" json:"src,omitempty"`
	Dst              *DataNode   `protobuf:"bytes,4,opt,name=dst" json:"dst,omitempty"`
	Nodes            []*DataNode `protobuf:"bytes,5,rep,name=nodes" json:"nodes,omitempty"`
	Pad              []byte      `protobuf:"bytes,99,opt,name=pad" json:"pad,omitempty"`
	XXX_unrecognized []byte      `json:"-"`
}

func (m *Message) Reset()                    { *m = Message{} }
func (m *Message) String() string            { return proto.CompactTextString(m) }
func (*Message) ProtoMessage()               {}
func (*Message) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }

func (m *Message) GetMagic() uint64 {
	if m != nil && m.Magic != nil {
		return *m.Magic
	}
	return 0
}

func (m *Message) GetSeq() []byte {
	if m != nil {
		return m.Seq
	}
	return nil
}

func (m *Message) GetSrc() *DataNode {
	if m != nil {
		return m.Src
	}
	return nil
}

func (m *Message) GetDst() *DataNode {
	if m != nil {
		return m.Dst
	}
	return nil
}

func (m *Message) GetNodes() []*DataNode {
	if m != nil {
		return m.Nodes
	}
	return nil
}

func (m *Message) GetPad() []byte {
	if m != nil {
		return m.Pad
	}
	return nil
}

func init() {
	proto.RegisterType((*Constants)(nil), "message.Constants")
	proto.RegisterType((*DataNode)(nil), "message.DataNode")
	proto.RegisterType((*Message)(nil), "message.Message")
	proto.RegisterEnum("message.DataNode_Type", DataNode_Type_name, DataNode_Type_value)
}

func init() {
	proto.RegisterFile("github.com/google/cloudprober/message/message.proto", fileDescriptor0)
}

var fileDescriptor0 = []byte{
	// 325 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x8f, 0xd1, 0x4e, 0xc2, 0x30,
	0x18, 0x85, 0x2d, 0x1b, 0x20, 0x3f, 0x88, 0xb3, 0x31, 0x66, 0x97, 0xcb, 0x0c, 0x91, 0xc4, 0x64,
	0x24, 0x5b, 0x64, 0xc8, 0x2d, 0x72, 0x61, 0xd4, 0x99, 0x54, 0xd0, 0x4b, 0x53, 0xd6, 0x66, 0x92,
	0xb0, 0xb5, 0xae, 0xe5, 0x82, 0x17, 0xf2, 0x11, 0x7c, 0x3e, 0xb3, 0x8d, 0x19, 0x13, 0xf5, 0xaa,
	0xa7, 0x3d, 0x5f, 0xff, 0xff, 0x1c, 0x08, 0x92, 0xb5, 0x7e, 0xdb, 0xae, 0xbc, 0x58, 0xa4, 0xa3,
	0x44, 0x88, 0x64, 0xc3, 0x47, 0xf1, 0x46, 0x6c, 0x99, 0xcc, 0xc5, 0x8a, 0xe7, 0xa3, 0x94, 0x2b,
	0x45, 0x13, 0x5e, 0x9f, 0x9e, 0xcc, 0x85, 0x16, 0xb8, 0xbd, 0xbf, 0xba, 0x3e, 0x74, 0x66, 0x22,
	0x53, 0x9a, 0x66, 0x5a, 0xe1, 0x01, 0x34, 0x53, 0x9a, 0xac, 0x63, 0x1b, 0x39, 0x68, 0x68, 0x4e,
	0x8f, 0xfd, 0xab, 0x30, 0x9c, 0x84, 0x41, 0x70, 0x3d, 0x0e, 0x26, 0xe1, 0xd8, 0x27, 0x95, 0xeb,
	0x7e, 0x20, 0x38, 0xbc, 0xa1, 0x9a, 0x46, 0x82, 0x71, 0xec, 0x83, 0xa9, 0x77, 0x92, 0x97, 0x5f,
	0xfa, 0xfe, 0x99, 0x57, 0xef, 0xa9, 0x01, 0x6f, 0xb1, 0x93, 0x7c, 0xda, 0x9a, 0xdd, 0xdf, 0xce,
	0xa3, 0x05, 0x29, 0x59, 0x8c, 0xc1, 0xcc, 0x68, 0xca, 0xed, 0x86, 0x83, 0x86, 0x1d, 0x52, 0x6a,
	0x3c, 0x80, 0xbe, 0x5e, 0xa7, 0x5c, 0x69, 0x9a, 0xca, 0xd7, 0xad, 0xe2, 0xb1, 0x6d, 0x38, 0x68,
	0xd8, 0x23, 0x47, 0xdf, 0xaf, 0x4b, 0xc5, 0x63, 0xf7, 0x12, 0xcc, 0x62, 0x20, 0xee, 0x42, 0x7b,
	0x19, 0xdd, 0x45, 0x8f, 0x2f, 0x91, 0x75, 0x80, 0x01, 0xf6, 0xf3, 0x2d, 0x54, 0xe8, 0xa7, 0x39,
	0x79, 0x9e, 0x13, 0xab, 0xe1, 0x7e, 0x22, 0x68, 0x3f, 0x54, 0x79, 0xf0, 0xe9, 0xcf, 0x6e, 0xad,
	0x7d, 0x15, 0x6c, 0x81, 0xa1, 0xf8, 0x7b, 0x19, 0xa4, 0x47, 0x0a, 0x89, 0xcf, 0xc1, 0x50, 0x79,
	0xb5, 0xbc, 0xeb, 0x9f, 0xfc, 0xaa, 0x43, 0x0a, 0xb7, 0x80, 0x98, 0xd2, 0xb6, 0xf9, 0x2f, 0xc4,
	0x94, 0xc6, 0x17, 0xd0, 0xcc, 0x04, 0xe3, 0xca, 0x6e, 0x3a, 0xc6, 0xdf, 0x58, 0xe5, 0x17, 0x21,
	0x24, 0x65, 0x76, 0x5c, 0x85, 0x90, 0x94, 0x7d, 0x05, 0x00, 0x00, 0xff, 0xff, 0x5e, 0x96, 0x1a,
	0x88, 0xd4, 0x01, 0x00, 0x00,
}
<commit_msg>Update protobufs' Go code.<commit_after>// Code generated by protoc-gen-go. DO NOT EDIT.
// source: github.com/google/cloudprober/message/message.proto

/*
Package message is a generated protocol buffer package.

It is generated from these files:
	github.com/google/cloudprober/message/message.proto

It has these top-level messages:
	Constants
	DataNode
	Msg
*/
package message

import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"

// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package

type DataNode_Type int32

const (
	DataNode_UNKNOWN DataNode_Type = 0
	DataNode_CLIENT  DataNode_Type = 1
	DataNode_SERVER  DataNode_Type = 2
)

var DataNode_Type_name = map[int32]string{
	0: "UNKNOWN",
	1: "CLIENT",
	2: "SERVER",
}
var DataNode_Type_value = map[string]int32{
	"UNKNOWN": 0,
	"CLIENT":  1,
	"SERVER":  2,
}

func (x DataNode_Type) Enum() *DataNode_Type {
	p := new(DataNode_Type)
	*p = x
	return p
}
func (x DataNode_Type) String() string {
	return proto.EnumName(DataNode_Type_name, int32(x))
}
func (x *DataNode_Type) UnmarshalJSON(data []byte) error {
	value, err := proto.UnmarshalJSONEnum(DataNode_Type_value, data, "DataNode_Type")
	if err != nil {
		return err
	}
	*x = DataNode_Type(value)
	return nil
}
func (DataNode_Type) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 0} }

// Constants defines constants with default values.
type Constants struct {
	Magic            *uint64 `protobuf:"varint,1,opt,name=magic,def=257787339638762" json:"magic,omitempty"`
	XXX_unrecognized []byte  `json:"-"`
}

func (m *Constants) Reset()                    { *m = Constants{} }
func (m *Constants) String() string            { return proto.CompactTextString(m) }
func (*Constants) ProtoMessage()               {}
func (*Constants) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }

const Default_Constants_Magic uint64 = 257787339638762

func (m *Constants) GetMagic() uint64 {
	if m != nil && m.Magic != nil {
		return *m.Magic
	}
	return Default_Constants_Magic
}

// Datanode is something that see's a message AND can modify it.
type DataNode struct {
	Type *DataNode_Type `protobuf:"varint,1,opt,name=type,enum=message.DataNode_Type,def=1" json:"type,omitempty"`
	Name *string        `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"`
	// 8 bytes of timestamp in pcap-friendly network byte order.
	TimestampUsec    []byte `protobuf:"bytes,3,opt,name=timestamp_usec,json=timestampUsec" json:"timestamp_usec,omitempty"`
	XXX_unrecognized []byte `json:"-"`
}

func (m *DataNode) Reset()                    { *m = DataNode{} }
func (m *DataNode) String() string            { return proto.CompactTextString(m) }
func (*DataNode) ProtoMessage()               {}
func (*DataNode) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }

const Default_DataNode_Type DataNode_Type = DataNode_CLIENT

func (m *DataNode) GetType() DataNode_Type {
	if m != nil && m.Type != nil {
		return *m.Type
	}
	return Default_DataNode_Type
}

func (m *DataNode) GetName() string {
	if m != nil && m.Name != nil {
		return *m.Name
	}
	return ""
}

func (m *DataNode) GetTimestampUsec() []byte {
	if m != nil {
		return m.TimestampUsec
	}
	return nil
}

// Msg is a message sent over the network.
// magic, seq, src and dst are required fields.
type Msg struct {
	Magic *uint64 `protobuf:"fixed64,1,opt,name=magic" json:"magic,omitempty"`
	// 8 bytes of sequence in pcap-friendly network byte order.
	Seq []byte `protobuf:"bytes,2,opt,name=seq" json:"seq,omitempty"`
	// Datanodes seen by this message.
	Src              *DataNode   `protobuf:"bytes,3,opt,name=src" json:"src,omitempty"`
	Dst              *DataNode   `protobuf:"bytes,4,opt,name=dst" json:"dst,omitempty"`
	Nodes            []*DataNode `protobuf:"bytes,5,rep,name=nodes" json:"nodes,omitempty"`
	Pad              []byte      `protobuf:"bytes,99,opt,name=pad" json:"pad,omitempty"`
	XXX_unrecognized []byte      `json:"-"`
}

func (m *Msg) Reset()                    { *m = Msg{} }
func (m *Msg) String() string            { return proto.CompactTextString(m) }
func (*Msg) ProtoMessage()               {}
func (*Msg) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }

func (m *Msg) GetMagic() uint64 {
	if m != nil && m.Magic != nil {
		return *m.Magic
	}
	return 0
}

func (m *Msg) GetSeq() []byte {
	if m != nil {
		return m.Seq
	}
	return nil
}

func (m *Msg) GetSrc() *DataNode {
	if m != nil {
		return m.Src
	}
	return nil
}

func (m *Msg) GetDst() *DataNode {
	if m != nil {
		return m.Dst
	}
	return nil
}

func (m *Msg) GetNodes() []*DataNode {
	if m != nil {
		return m.Nodes
	}
	return nil
}

func (m *Msg) GetPad() []byte {
	if m != nil {
		return m.Pad
	}
	return nil
}

func init() {
	proto.RegisterType((*Constants)(nil), "message.Constants")
	proto.RegisterType((*DataNode)(nil), "message.DataNode")
	proto.RegisterType((*Msg)(nil), "message.Msg")
	proto.RegisterEnum("message.DataNode_Type", DataNode_Type_name, DataNode_Type_value)
}

func init() {
	proto.RegisterFile("github.com/google/cloudprober/message/message.proto", fileDescriptor0)
}

var fileDescriptor0 = []byte{
	// 324 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x8f, 0xd1, 0x4e, 0xc2, 0x30,
	0x18, 0x85, 0x2d, 0x1b, 0x20, 0x3f, 0x88, 0xb3, 0x31, 0x66, 0x97, 0xcb, 0x0c, 0x91, 0xc4, 0x64,
	0x24, 0x5b, 0x64, 0xc8, 0x2d, 0x72, 0x61, 0xd4, 0x99, 0x54, 0xd0, 0x4b, 0x53, 0xd6, 0x66, 0x92,
	0xb0, 0xb5, 0xae, 0xe5, 0x82, 0x17, 0xf2, 0x01, 0x7c, 0x42, 0xb3, 0x8d, 0x19, 0x13, 0xf5, 0xaa,
	0xa7, 0x3d, 0x5f, 0xff, 0xff, 0x1c, 0x08, 0x92, 0xb5, 0x7e, 0xdb, 0xae, 0xbc, 0x58, 0xa4, 0xa3,
	0x44, 0x88, 0x64, 0xc3, 0x47, 0xf1, 0x46, 0x6c, 0x99, 0xcc, 0xc5, 0x8a, 0xe7, 0xa3, 0x94, 0x2b,
	0x45, 0x13, 0x5e, 0x9f, 0x9e, 0xcc, 0x85, 0x16, 0xb8, 0xbd, 0xbf, 0xba, 0x3e, 0x74, 0x66, 0x22,
	0x53, 0x9a, 0x66, 0x5a, 0xe1, 0x01, 0x34, 0x53, 0x9a, 0xac, 0x63, 0x1b, 0x39, 0x68, 0x68, 0x4e,
	0x8f, 0xfd, 0xab, 0x30, 0x9c, 0x84, 0x41, 0x70, 0x3d, 0x0e, 0x26, 0xe1, 0xd8, 0x27, 0x95, 0xeb,
	0x7e, 0x20, 0x38, 0xbc, 0xa1, 0x9a, 0x46, 0x82, 0x71, 0xec, 0x83, 0xa9, 0x77, 0x92, 0x97, 0x5f,
	0xfa, 0xfe, 0x99, 0x57, 0xef, 0xa9, 0x01, 0x6f, 0xb1, 0x93, 0x7c, 0xda, 0x9a, 0xdd, 0xdf, 0xce,
	0xa3, 0x05, 0x29, 0x59, 0x8c, 0xc1, 0xcc, 0x68, 0xca, 0xed, 0x86, 0x83, 0x86, 0x1d, 0x52, 0x6a,
	0x3c, 0x80, 0xbe, 0x5e, 0xa7, 0x5c, 0x69, 0x9a, 0xca, 0xd7, 0xad, 0xe2, 0xb1, 0x6d, 0x38, 0x68,
	0xd8, 0x23, 0x47, 0xdf, 0xaf, 0x4b, 0xc5, 0x63, 0xf7, 0x12, 0xcc, 0x62, 0x20, 0xee, 0x42, 0x7b,
	0x19, 0xdd, 0x45, 0x8f, 0x2f, 0x91, 0x75, 0x80, 0x01, 0xf6, 0xf3, 0x2d, 0x54, 0xe8, 0xa7, 0x39,
	0x79, 0x9e, 0x13, 0xab, 0xe1, 0x7e, 0x22, 0x30, 0x1e, 0x54, 0x82, 0x4f, 0x7f, 0xf6, 0x6a, 0xed,
	0x6b, 0x60, 0x0b, 0x0c, 0xc5, 0xdf, 0xcb, 0x10, 0x3d, 0x52, 0x48, 0x7c, 0x0e, 0x86, 0xca, 0xab,
	0xc5, 0x5d, 0xff, 0xe4, 0x57, 0x15, 0x52, 0xb8, 0x05, 0xc4, 0x94, 0xb6, 0xcd, 0x7f, 0x21, 0xa6,
	0x34, 0xbe, 0x80, 0x66, 0x26, 0x18, 0x57, 0x76, 0xd3, 0x31, 0xfe, 0xc6, 0x2a, 0xbf, 0x08, 0x21,
	0x29, 0xb3, 0xe3, 0x2a, 0x84, 0xa4, 0xec, 0x2b, 0x00, 0x00, 0xff, 0xff, 0x6e, 0x2a, 0x4b, 0xfe,
	0xd0, 0x01, 0x00, 0x00,
}
<|endoftext|>


<commit_before>package user

import (
	"fmt"
	"github.com/stretchr/testify/assert"
	"gopkg.in/DATA-DOG/go-sqlmock.v1"
	"testing"

	"github.com/eirka/eirka-libs/config"
	"github.com/eirka/eirka-libs/db"
	e "github.com/eirka/eirka-libs/errors"
)

func init() {
	config.Settings.Limits.PasswordMinLength = 8
	config.Settings.Limits.PasswordMaxLength = 128
}

func TestDefaultUser(t *testing.T) {

	user := DefaultUser()

	assert.Equal(t, uint(1), user.Id, "default user id should be 1")

	assert.False(t, user.IsAuthenticated, "default user should not be authenticated")

}

func TestSetId(t *testing.T) {

	user := DefaultUser()

	user.SetId(2)

	assert.Equal(t, uint(2), user.Id, "user id should be 2")

}

func TestSetAuthenticated(t *testing.T) {

	user := DefaultUser()

	user.SetAuthenticated()

	assert.False(t, user.IsAuthenticated, "User should be not authorized")

	user.SetId(2)

	user.SetAuthenticated()

	assert.True(t, user.IsAuthenticated, "User should be authorized")

	assert.True(t, user.IsValid(), "Authed non-anon user should be valid")

}

func TestIsValid(t *testing.T) {

	user := DefaultUser()

	assert.True(t, user.IsValid(), "DefaultUser should be valid")

	user.SetId(2)

	assert.False(t, user.IsValid(), "Unauthenticated non-anon should be invalid")

	user.SetAuthenticated()

	assert.True(t, user.IsValid(), "Authed non-anon user should be valid")

	user.SetId(0)

	assert.False(t, user.IsValid(), "User zero should be invalid")

	user.SetId(1)

	assert.False(t, user.IsValid(), "An authenticated anon user should be invalid")

}

func TestIsValidName(t *testing.T) {

	assert.True(t, IsValidName("cooldude2"), "Name should validate")

	assert.True(t, IsValidName("cool dude"), "Name should validate")

	assert.True(t, IsValidName("cool_dude"), "Name should validate")

	assert.True(t, IsValidName("cool-dude"), "Name should validate")

	assert.False(t, IsValidName("cool.dude"), "Name should not validate")

	assert.False(t, IsValidName("cooldude!"), "Name should not validate")

	assert.False(t, IsValidName("admin"), "Name should not validate")

	assert.False(t, IsValidName("Admin"), "Name should not validate")

	assert.False(t, IsValidName("Admin "), "Name should not validate")

	assert.False(t, IsValidName(" Admin  "), "Name should not validate")

}

func TestPassword(t *testing.T) {

	_, err := HashPassword("")
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrPasswordEmpty, "Error should match")
	}

	_, err = HashPassword("heh")
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrPasswordShort, "Error should match")
	}

	_, err = HashPassword("k8dyuCqJfW9v5iFUeeS4YOeiuk5Wee6Q9tZvWFHqE10ftzhaxVzxlKzx4n7CcBpRcgtaX9dZ2lBIRrsvgqXPPvmjNpIgnrums2Xtst8FsZkpZo61u3ChCs7MEO1DGy4Qa")
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrPasswordLong, "Error should match")
	}

	password, err := HashPassword("testpassword")
	if assert.NoError(t, err, "An error was not expected") {
		assert.NotNil(t, password, "password should be returned")
	}

	user := DefaultUser()
	user.SetId(2)
	user.SetAuthenticated()

	assert.False(t, user.ComparePassword("atestpassword"), "Password should not validate")

	user.hash = password

	assert.False(t, user.ComparePassword(""), "Password should not validate")

	assert.False(t, user.ComparePassword("wrongpassword"), "Password should not validate")

	assert.True(t, user.ComparePassword("testpassword"), "Password should validate")

}

func TestCreateToken(t *testing.T) {

	Secret = ""

	user := DefaultUser()

	// secret must be set
	token, err := user.CreateToken()
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrNoSecret, "Error should match")
		assert.Empty(t, token, "Token should be empty")
	}

	Secret = "secret"

	// default user state should never get a token
	token, err = user.CreateToken()
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrUserNotValid, "Error should match")
		assert.Empty(t, token, "Token should be empty")
	}

	user.SetId(2)

	// a non authed user should never get a token
	token, err = user.CreateToken()
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrUserNotValid, "Error should match")
		assert.Empty(t, token, "Token should be empty")
	}

	user.SetAuthenticated()

	// a user that doesnt have a validated password should never get a token
	token, err = user.CreateToken()
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrInvalidPassword, "Error should match")
		assert.Empty(t, token, "Token should be empty")
	}

	user.hash, err = HashPassword("testpassword")
	if assert.NoError(t, err, "An error was not expected") {
		assert.NotNil(t, user.hash, "password should be returned")
	}

	assert.True(t, user.ComparePassword("testpassword"), "Password should validate")

	token, err = user.CreateToken()
	if assert.NoError(t, err, "An error was not expected") {
		assert.NotEmpty(t, token, "Token should not be empty")
	}

}

func TestCreateTokenAnonAuth(t *testing.T) {

	Secret = "secret"

	invalidUser := DefaultUser()
	invalidUser.SetId(1)
	invalidUser.SetAuthenticated()

	notoken, err := invalidUser.CreateToken()
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrUserNotValid, "Error should match")
		assert.Empty(t, notoken, "token should not be returned")
	}
}

func TestCreateTokenZeroAuth(t *testing.T) {

	Secret = "secret"

	invalidUser := DefaultUser()
	invalidUser.SetId(0)
	invalidUser.SetAuthenticated()

	notoken, err := invalidUser.CreateToken()
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrUserNotValid, "Error should match")
		assert.Empty(t, notoken, "token should not be returned")
	}
}

func TestCreateTokenZeroNoAuth(t *testing.T) {

	Secret = "secret"

	invalidUser := DefaultUser()
	invalidUser.SetId(0)

	notoken, err := invalidUser.CreateToken()
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrUserNotValid, "Error should match")
		assert.Empty(t, notoken, "token should not be returned")
	}
}

func TestUserPassword(t *testing.T) {

	Secret = "secret"

	user := DefaultUser()
	user.SetId(2)
	user.SetAuthenticated()

	password, err := HashPassword("testpassword")
	if assert.NoError(t, err, "An error was not expected") {
		assert.NotNil(t, password, "password should be returned")
	}

	mock, err := db.NewTestDb()
	assert.NoError(t, err, "An error was not expected")

	rows := sqlmock.NewRows([]string{"name", "password"}).AddRow("testaccount", password)

	mock.ExpectQuery("select user_name, user_password from users where user_id").WillReturnRows(rows)

	err = user.Password()
	if assert.NoError(t, err, "An error was not expected") {
		assert.Equal(t, user.Name, "testaccount", "Name should match")
		assert.True(t, user.ComparePassword("testpassword"), "Password should validate")
	}
}

func TestUserBadPassword(t *testing.T) {

	Secret = "secret"

	user := DefaultUser()
	user.SetId(2)
	user.SetAuthenticated()

	password, err := HashPassword("testpassword")
	if assert.NoError(t, err, "An error was not expected") {
		assert.NotNil(t, password, "password should be returned")
	}

	mock, err := db.NewTestDb()
	assert.NoError(t, err, "An error was not expected")

	rows := sqlmock.NewRows([]string{"name", "password"}).AddRow("testaccount", password)

	mock.ExpectQuery("select user_name, user_password from users where user_id").WillReturnRows(rows)

	err = user.Password()
	if assert.NoError(t, err, "An error was not expected") {
		assert.Equal(t, user.Name, "testaccount", "Name should match")
		assert.False(t, user.ComparePassword("badpassword"), "Password should not validate")
	}
}

func TestFromName(t *testing.T) {

	Secret = "secret"

	user := DefaultUser()

	password, err := HashPassword("testpassword")
	if assert.NoError(t, err, "An error was not expected") {
		assert.NotNil(t, password, "password should be returned")
	}

	mock, err := db.NewTestDb()
	assert.NoError(t, err, "An error was not expected")

	rows := sqlmock.NewRows([]string{"id", "password"}).AddRow(2, password)

	mock.ExpectQuery("select user_id, user_password from users where user_name").WillReturnRows(rows)

	err = user.FromName("testaccount")
	if assert.NoError(t, err, "An error was not expected") {
		assert.Equal(t, user.Id, uint(2), "Id should match")
		assert.True(t, user.IsAuthenticated, "User should be authenticated")
		assert.True(t, user.ComparePassword("testpassword"), "Password should validate")
	}

}

func TestFromNameEmptyName(t *testing.T) {

	Secret = "secret"

	user := DefaultUser()

	err := user.FromName("")
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrUserNotValid, "Error should match")
	}

}

func TestFromNameBadId(t *testing.T) {

	Secret = "secret"

	user := DefaultUser()

	password, err := HashPassword("testpassword")
	if assert.NoError(t, err, "An error was not expected") {
		assert.NotNil(t, password, "password should be returned")
	}

	mock, err := db.NewTestDb()
	assert.NoError(t, err, "An error was not expected")

	rows := sqlmock.NewRows([]string{"id", "password"}).AddRow(0, password)

	mock.ExpectQuery("select user_id, user_password from users where user_name").WillReturnRows(rows)

	err = user.FromName("test")
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrUserNotValid, "Error should match")
	}

}

func TestCheckDuplicateEmpty(t *testing.T) {

	assert.True(t, CheckDuplicate(""), "Should return true")

}

func TestCheckDuplicateGood(t *testing.T) {

	mock, err := db.NewTestDb()
	assert.NoError(t, err, "An error was not expected")

	rows := sqlmock.NewRows([]string{"count"}).AddRow(0)

	mock.ExpectQuery(`select count(\*) from users where user_name`).WillReturnRows(rows)

	fmt.Println(CheckDuplicate("test"))

	assert.False(t, CheckDuplicate("test"), "Should not be a duplicate")

}

func TestCheckDuplicateBad(t *testing.T) {

	mock, err := db.NewTestDb()
	assert.NoError(t, err, "An error was not expected")

	rows := sqlmock.NewRows([]string{"count"}).AddRow(1)

	mock.ExpectQuery(`select count(\*) from users where user_name`).WillReturnRows(rows)

	assert.True(t, CheckDuplicate("test"), "Should be a duplicate")

}

func TestIsAuthorizedInvalid(t *testing.T) {

	user := DefaultUser()

	assert.False(t, user.IsAuthorized(0), "Should not be authorized")

	assert.False(t, user.IsAuthorized(1), "Should not be authorized")

	user.SetAuthenticated()

	assert.False(t, user.IsAuthorized(1), "Should not be authorized")

	user.SetId(2)

	assert.False(t, user.IsAuthorized(1), "Should not be authorized")

}

func TestIsAuthorizedDefault(t *testing.T) {

	user := DefaultUser()

	mock, err := db.NewTestDb()
	assert.NoError(t, err, "An error was not expected")

	rows := sqlmock.NewRows([]string{"role"}).AddRow(1)

	mock.ExpectQuery(`SELECT COALESCE`).WillReturnRows(rows)

	assert.False(t, user.IsAuthorized(1), "Should not be authorized")

}

func TestIsAuthorizedAuth(t *testing.T) {

	user := DefaultUser()
	user.SetId(2)
	user.SetAuthenticated()

	mock, err := db.NewTestDb()
	assert.NoError(t, err, "An error was not expected")

	rows := sqlmock.NewRows([]string{"role"}).AddRow(2)

	mock.ExpectQuery(`SELECT COALESCE`).WillReturnRows(rows)

	assert.False(t, user.IsAuthorized(1), "Should not be authorized")

}

func TestIsAuthorizedMod(t *testing.T) {

	user := DefaultUser()
	user.SetId(2)
	user.SetAuthenticated()

	mock, err := db.NewTestDb()
	assert.NoError(t, err, "An error was not expected")

	rows := sqlmock.NewRows([]string{"role"}).AddRow(3)

	mock.ExpectQuery(`SELECT COALESCE`).WillReturnRows(rows)

	assert.True(t, user.IsAuthorized(1), "Should be authorized")

}

func TestIsAuthorizedAdmin(t *testing.T) {

	user := DefaultUser()
	user.SetId(2)
	user.SetAuthenticated()

	mock, err := db.NewTestDb()
	assert.NoError(t, err, "An error was not expected")

	rows := sqlmock.NewRows([]string{"role"}).AddRow(4)

	mock.ExpectQuery(`SELECT COALESCE`).WillReturnRows(rows)

	assert.True(t, user.IsAuthorized(1), "Should be authorized")

}
<commit_msg>add user password sql check<commit_after>package user

import (
	"fmt"
	"github.com/stretchr/testify/assert"
	"gopkg.in/DATA-DOG/go-sqlmock.v1"
	"testing"

	"github.com/eirka/eirka-libs/config"
	"github.com/eirka/eirka-libs/db"
	e "github.com/eirka/eirka-libs/errors"
)

func init() {
	config.Settings.Limits.PasswordMinLength = 8
	config.Settings.Limits.PasswordMaxLength = 128
}

func TestDefaultUser(t *testing.T) {

	user := DefaultUser()

	assert.Equal(t, uint(1), user.Id, "default user id should be 1")

	assert.False(t, user.IsAuthenticated, "default user should not be authenticated")

}

func TestSetId(t *testing.T) {

	user := DefaultUser()

	user.SetId(2)

	assert.Equal(t, uint(2), user.Id, "user id should be 2")

}

func TestSetAuthenticated(t *testing.T) {

	user := DefaultUser()

	user.SetAuthenticated()

	assert.False(t, user.IsAuthenticated, "User should be not authorized")

	user.SetId(2)

	user.SetAuthenticated()

	assert.True(t, user.IsAuthenticated, "User should be authorized")

	assert.True(t, user.IsValid(), "Authed non-anon user should be valid")

}

func TestIsValid(t *testing.T) {

	user := DefaultUser()

	assert.True(t, user.IsValid(), "DefaultUser should be valid")

	user.SetId(2)

	assert.False(t, user.IsValid(), "Unauthenticated non-anon should be invalid")

	user.SetAuthenticated()

	assert.True(t, user.IsValid(), "Authed non-anon user should be valid")

	user.SetId(0)

	assert.False(t, user.IsValid(), "User zero should be invalid")

	user.SetId(1)

	assert.False(t, user.IsValid(), "An authenticated anon user should be invalid")

}

func TestIsValidName(t *testing.T) {

	assert.True(t, IsValidName("cooldude2"), "Name should validate")

	assert.True(t, IsValidName("cool dude"), "Name should validate")

	assert.True(t, IsValidName("cool_dude"), "Name should validate")

	assert.True(t, IsValidName("cool-dude"), "Name should validate")

	assert.False(t, IsValidName("cool.dude"), "Name should not validate")

	assert.False(t, IsValidName("cooldude!"), "Name should not validate")

	assert.False(t, IsValidName("admin"), "Name should not validate")

	assert.False(t, IsValidName("Admin"), "Name should not validate")

	assert.False(t, IsValidName("Admin "), "Name should not validate")

	assert.False(t, IsValidName(" Admin  "), "Name should not validate")

}

func TestPassword(t *testing.T) {

	_, err := HashPassword("")
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrPasswordEmpty, "Error should match")
	}

	_, err = HashPassword("heh")
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrPasswordShort, "Error should match")
	}

	_, err = HashPassword("k8dyuCqJfW9v5iFUeeS4YOeiuk5Wee6Q9tZvWFHqE10ftzhaxVzxlKzx4n7CcBpRcgtaX9dZ2lBIRrsvgqXPPvmjNpIgnrums2Xtst8FsZkpZo61u3ChCs7MEO1DGy4Qa")
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrPasswordLong, "Error should match")
	}

	password, err := HashPassword("testpassword")
	if assert.NoError(t, err, "An error was not expected") {
		assert.NotNil(t, password, "password should be returned")
	}

	user := DefaultUser()
	user.SetId(2)
	user.SetAuthenticated()

	assert.False(t, user.ComparePassword("atestpassword"), "Password should not validate")

	user.hash = password

	assert.False(t, user.ComparePassword(""), "Password should not validate")

	assert.False(t, user.ComparePassword("wrongpassword"), "Password should not validate")

	assert.True(t, user.ComparePassword("testpassword"), "Password should validate")

}

func TestCreateToken(t *testing.T) {

	Secret = ""

	user := DefaultUser()

	// secret must be set
	token, err := user.CreateToken()
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrNoSecret, "Error should match")
		assert.Empty(t, token, "Token should be empty")
	}

	Secret = "secret"

	// default user state should never get a token
	token, err = user.CreateToken()
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrUserNotValid, "Error should match")
		assert.Empty(t, token, "Token should be empty")
	}

	user.SetId(2)

	// a non authed user should never get a token
	token, err = user.CreateToken()
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrUserNotValid, "Error should match")
		assert.Empty(t, token, "Token should be empty")
	}

	user.SetAuthenticated()

	// a user that doesnt have a validated password should never get a token
	token, err = user.CreateToken()
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrInvalidPassword, "Error should match")
		assert.Empty(t, token, "Token should be empty")
	}

	user.hash, err = HashPassword("testpassword")
	if assert.NoError(t, err, "An error was not expected") {
		assert.NotNil(t, user.hash, "password should be returned")
	}

	assert.True(t, user.ComparePassword("testpassword"), "Password should validate")

	token, err = user.CreateToken()
	if assert.NoError(t, err, "An error was not expected") {
		assert.NotEmpty(t, token, "Token should not be empty")
	}

}

func TestCreateTokenAnonAuth(t *testing.T) {

	Secret = "secret"

	invalidUser := DefaultUser()
	invalidUser.SetId(1)
	invalidUser.SetAuthenticated()

	notoken, err := invalidUser.CreateToken()
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrUserNotValid, "Error should match")
		assert.Empty(t, notoken, "token should not be returned")
	}
}

func TestCreateTokenZeroAuth(t *testing.T) {

	Secret = "secret"

	invalidUser := DefaultUser()
	invalidUser.SetId(0)
	invalidUser.SetAuthenticated()

	notoken, err := invalidUser.CreateToken()
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrUserNotValid, "Error should match")
		assert.Empty(t, notoken, "token should not be returned")
	}
}

func TestCreateTokenZeroNoAuth(t *testing.T) {

	Secret = "secret"

	invalidUser := DefaultUser()
	invalidUser.SetId(0)

	notoken, err := invalidUser.CreateToken()
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrUserNotValid, "Error should match")
		assert.Empty(t, notoken, "token should not be returned")
	}
}

func TestUserPassword(t *testing.T) {

	Secret = "secret"

	user := DefaultUser()
	user.SetId(2)
	user.SetAuthenticated()

	password, err := HashPassword("testpassword")
	if assert.NoError(t, err, "An error was not expected") {
		assert.NotNil(t, password, "password should be returned")
	}

	mock, err := db.NewTestDb()
	assert.NoError(t, err, "An error was not expected")

	rows := sqlmock.NewRows([]string{"name", "password"}).AddRow("testaccount", password)

	mock.ExpectQuery("select user_name, user_password from users where user_id").WillReturnRows(rows)

	err = user.Password()
	if assert.NoError(t, err, "An error was not expected") {
		assert.Equal(t, user.Name, "testaccount", "Name should match")
		assert.True(t, user.ComparePassword("testpassword"), "Password should validate")
	}
}

func TestUserBadPassword(t *testing.T) {

	Secret = "secret"

	user := DefaultUser()
	user.SetId(2)
	user.SetAuthenticated()

	password, err := HashPassword("testpassword")
	if assert.NoError(t, err, "An error was not expected") {
		assert.NotNil(t, password, "password should be returned")
	}

	mock, err := db.NewTestDb()
	assert.NoError(t, err, "An error was not expected")

	rows := sqlmock.NewRows([]string{"name", "password"}).AddRow("testaccount", password)

	mock.ExpectQuery("select user_name, user_password from users where user_id").WillReturnRows(rows)

	err = user.Password()
	if assert.NoError(t, err, "An error was not expected") {
		assert.Equal(t, user.Name, "testaccount", "Name should match")
		assert.False(t, user.ComparePassword("badpassword"), "Password should not validate")
	}
}

func TestFromName(t *testing.T) {

	Secret = "secret"

	user := DefaultUser()

	password, err := HashPassword("testpassword")
	if assert.NoError(t, err, "An error was not expected") {
		assert.NotNil(t, password, "password should be returned")
	}

	mock, err := db.NewTestDb()
	assert.NoError(t, err, "An error was not expected")

	rows := sqlmock.NewRows([]string{"id", "password"}).AddRow(2, password)

	mock.ExpectQuery("select user_id, user_password from users where user_name").WillReturnRows(rows)

	err = user.FromName("testaccount")
	if assert.NoError(t, err, "An error was not expected") {
		assert.Equal(t, user.Id, uint(2), "Id should match")
		assert.True(t, user.IsAuthenticated, "User should be authenticated")
		assert.True(t, user.ComparePassword("testpassword"), "Password should validate")
	}

}

func TestFromNameEmptyName(t *testing.T) {

	Secret = "secret"

	user := DefaultUser()

	err := user.FromName("")
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrUserNotValid, "Error should match")
	}

}

func TestFromNameBadId(t *testing.T) {

	Secret = "secret"

	user := DefaultUser()

	password, err := HashPassword("testpassword")
	if assert.NoError(t, err, "An error was not expected") {
		assert.NotNil(t, password, "password should be returned")
	}

	mock, err := db.NewTestDb()
	assert.NoError(t, err, "An error was not expected")

	rows := sqlmock.NewRows([]string{"id", "password"}).AddRow(0, password)

	mock.ExpectQuery("select user_id, user_password from users where user_name").WillReturnRows(rows)

	err = user.FromName("test")
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrUserNotValid, "Error should match")
	}

}

func TestCheckDuplicateEmpty(t *testing.T) {

	assert.True(t, CheckDuplicate(""), "Should return true")

}

func TestCheckDuplicateGood(t *testing.T) {

	mock, err := db.NewTestDb()
	assert.NoError(t, err, "An error was not expected")

	rows := sqlmock.NewRows([]string{"count"}).AddRow(0)

	mock.ExpectQuery(`select count\(\*\) from users where user_name`).WillReturnRows(rows)

	fmt.Println(CheckDuplicate("test"))

	assert.False(t, CheckDuplicate("test"), "Should not be a duplicate")

}

func TestCheckDuplicateBad(t *testing.T) {

	mock, err := db.NewTestDb()
	assert.NoError(t, err, "An error was not expected")

	rows := sqlmock.NewRows([]string{"count"}).AddRow(1)

	mock.ExpectQuery(`select count\(\*\) from users where user_name`).WillReturnRows(rows)

	assert.True(t, CheckDuplicate("test"), "Should be a duplicate")

}

func TestIsAuthorizedInvalid(t *testing.T) {

	user := DefaultUser()

	assert.False(t, user.IsAuthorized(0), "Should not be authorized")

	assert.False(t, user.IsAuthorized(1), "Should not be authorized")

	user.SetAuthenticated()

	assert.False(t, user.IsAuthorized(1), "Should not be authorized")

	user.SetId(2)

	assert.False(t, user.IsAuthorized(1), "Should not be authorized")

}

func TestIsAuthorizedDefault(t *testing.T) {

	user := DefaultUser()

	mock, err := db.NewTestDb()
	assert.NoError(t, err, "An error was not expected")

	rows := sqlmock.NewRows([]string{"role"}).AddRow(1)

	mock.ExpectQuery(`SELECT COALESCE`).WillReturnRows(rows)

	assert.False(t, user.IsAuthorized(1), "Should not be authorized")

}

func TestIsAuthorizedAuth(t *testing.T) {

	user := DefaultUser()
	user.SetId(2)
	user.SetAuthenticated()

	mock, err := db.NewTestDb()
	assert.NoError(t, err, "An error was not expected")

	rows := sqlmock.NewRows([]string{"role"}).AddRow(2)

	mock.ExpectQuery(`SELECT COALESCE`).WillReturnRows(rows)

	assert.False(t, user.IsAuthorized(1), "Should not be authorized")

}

func TestIsAuthorizedMod(t *testing.T) {

	user := DefaultUser()
	user.SetId(2)
	user.SetAuthenticated()

	mock, err := db.NewTestDb()
	assert.NoError(t, err, "An error was not expected")

	rows := sqlmock.NewRows([]string{"role"}).AddRow(3)

	mock.ExpectQuery(`SELECT COALESCE`).WillReturnRows(rows)

	assert.True(t, user.IsAuthorized(1), "Should be authorized")

}

func TestIsAuthorizedAdmin(t *testing.T) {

	user := DefaultUser()
	user.SetId(2)
	user.SetAuthenticated()

	mock, err := db.NewTestDb()
	assert.NoError(t, err, "An error was not expected")

	rows := sqlmock.NewRows([]string{"role"}).AddRow(4)

	mock.ExpectQuery(`SELECT COALESCE`).WillReturnRows(rows)

	assert.True(t, user.IsAuthorized(1), "Should be authorized")

}
<|endoftext|>


<commit_before>package user

import (
	"github.com/stretchr/testify/assert"
	"gopkg.in/DATA-DOG/go-sqlmock.v1"
	"testing"

	"github.com/eirka/eirka-libs/config"
	"github.com/eirka/eirka-libs/db"
	e "github.com/eirka/eirka-libs/errors"
)

func init() {
	config.Settings.Limits.PasswordMinLength = 8
	config.Settings.Limits.PasswordMaxLength = 128
}

func TestDefaultUser(t *testing.T) {

	user := DefaultUser()

	assert.Equal(t, uint(1), user.Id, "default user id should be 1")

	assert.False(t, user.IsAuthenticated, "default user should not be authenticated")

}

func TestSetId(t *testing.T) {

	user := DefaultUser()

	user.SetId(2)

	assert.Equal(t, uint(2), user.Id, "user id should be 2")

}

func TestSetAuthenticated(t *testing.T) {

	user := DefaultUser()

	user.SetAuthenticated()

	assert.False(t, user.IsAuthenticated, "User should be not authorized")

	user.SetId(2)

	user.SetAuthenticated()

	assert.True(t, user.IsAuthenticated, "User should be authorized")

	assert.True(t, user.IsValid(), "Authed non-anon user should be valid")

}

func TestIsValid(t *testing.T) {

	user := DefaultUser()

	assert.True(t, user.IsValid(), "DefaultUser should be valid")

	user.SetId(2)

	assert.False(t, user.IsValid(), "Unauthenticated non-anon should be invalid")

	user.SetAuthenticated()

	assert.True(t, user.IsValid(), "Authed non-anon user should be valid")

	user.SetId(0)

	assert.False(t, user.IsValid(), "User zero should be invalid")

	user.SetId(1)

	assert.False(t, user.IsValid(), "An authenticated anon user should be invalid")

}

func TestIsValidName(t *testing.T) {

	assert.True(t, IsValidName("cooldude2"), "Name should validate")

	assert.True(t, IsValidName("cool dude"), "Name should validate")

	assert.True(t, IsValidName("cool_dude"), "Name should validate")

	assert.True(t, IsValidName("cool-dude"), "Name should validate")

	assert.False(t, IsValidName("cool.dude"), "Name should not validate")

	assert.False(t, IsValidName("cooldude!"), "Name should not validate")

	assert.False(t, IsValidName("admin"), "Name should not validate")

	assert.False(t, IsValidName("Admin"), "Name should not validate")

	assert.False(t, IsValidName("Admin "), "Name should not validate")

	assert.False(t, IsValidName(" Admin  "), "Name should not validate")

}

func TestPassword(t *testing.T) {

	_, err := HashPassword("")
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrPasswordEmpty, "Error should match")
	}

	_, err = HashPassword("heh")
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrPasswordShort, "Error should match")
	}

	_, err = HashPassword("k8dyuCqJfW9v5iFUeeS4YOeiuk5Wee6Q9tZvWFHqE10ftzhaxVzxlKzx4n7CcBpRcgtaX9dZ2lBIRrsvgqXPPvmjNpIgnrums2Xtst8FsZkpZo61u3ChCs7MEO1DGy4Qa")
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrPasswordLong, "Error should match")
	}

	password, err := HashPassword("testpassword")
	if assert.NoError(t, err, "An error was not expected") {
		assert.NotNil(t, password, "password should be returned")
	}

	user := DefaultUser()
	user.SetId(2)
	user.SetAuthenticated()

	assert.False(t, user.ComparePassword("atestpassword"), "Password should not validate")

	user.hash = password

	assert.False(t, user.ComparePassword(""), "Password should not validate")

	assert.False(t, user.ComparePassword("wrongpassword"), "Password should not validate")

	assert.True(t, user.ComparePassword("testpassword"), "Password should validate")

}

func TestCreateToken(t *testing.T) {

	Secret = ""

	user := DefaultUser()

	// secret must be set
	token, err := user.CreateToken()
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrNoSecret, "Error should match")
		assert.Empty(t, token, "Token should be empty")
	}

	Secret = "secret"

	// default user state should never get a token
	token, err = user.CreateToken()
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrUserNotValid, "Error should match")
		assert.Empty(t, token, "Token should be empty")
	}

	user.SetId(2)

	// a non authed user should never get a token
	token, err = user.CreateToken()
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrUserNotValid, "Error should match")
		assert.Empty(t, token, "Token should be empty")
	}

	user.SetAuthenticated()

	// a user that doesnt have a validated password should never get a token
	token, err = user.CreateToken()
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrInvalidPassword, "Error should match")
		assert.Empty(t, token, "Token should be empty")
	}

	user.hash, err = HashPassword("testpassword")
	if assert.NoError(t, err, "An error was not expected") {
		assert.NotNil(t, user.hash, "password should be returned")
	}

	assert.True(t, user.ComparePassword("testpassword"), "Password should validate")

	token, err = user.CreateToken()
	if assert.NoError(t, err, "An error was not expected") {
		assert.NotEmpty(t, token, "Token should not be empty")
	}

}

func TestCreateTokenAnonAuth(t *testing.T) {

	Secret = "secret"

	invalidUser := DefaultUser()
	invalidUser.SetId(1)
	invalidUser.SetAuthenticated()

	notoken, err := invalidUser.CreateToken()
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrUserNotValid, "Error should match")
		assert.Empty(t, notoken, "token should not be returned")
	}
}

func TestCreateTokenZeroAuth(t *testing.T) {

	Secret = "secret"

	invalidUser := DefaultUser()
	invalidUser.SetId(0)
	invalidUser.SetAuthenticated()

	notoken, err := invalidUser.CreateToken()
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrUserNotValid, "Error should match")
		assert.Empty(t, notoken, "token should not be returned")
	}
}

func TestCreateTokenZeroNoAuth(t *testing.T) {

	Secret = "secret"

	invalidUser := DefaultUser()
	invalidUser.SetId(0)

	notoken, err := invalidUser.CreateToken()
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrUserNotValid, "Error should match")
		assert.Empty(t, notoken, "token should not be returned")
	}
}

func TestUserPassword(t *testing.T) {

	Secret = "secret"

	user := DefaultUser()
	user.SetId(2)
	user.SetAuthenticated()

	password, err := HashPassword("testpassword")
	if assert.NoError(t, err, "An error was not expected") {
		assert.NotNil(t, password, "password should be returned")
	}

	mock, err := db.NewTestDb()
	assert.NoError(t, err, "An error was not expected")

	rows := sqlmock.NewRows([]string{"name", "password"}).AddRow("testaccount", password)

	mock.ExpectQuery("select user_name, user_password from users where user_id").WillReturnRows(rows)

	assert.NoError(t, user.Password(), "An error was not expected")

	assert.Equal(t, user.Name, "testaccount", "Name should match")

	assert.True(t, user.ComparePassword("testpassword"), "Password should validate")

}

func TestUserBadPassword(t *testing.T) {

	Secret = "secret"

	user := DefaultUser()
	user.SetId(2)
	user.SetAuthenticated()

	password, err := HashPassword("testpassword")
	if assert.NoError(t, err, "An error was not expected") {
		assert.NotNil(t, password, "password should be returned")
	}

	mock, err := db.NewTestDb()
	assert.NoError(t, err, "An error was not expected")

	rows := sqlmock.NewRows([]string{"name", "password"}).AddRow("testaccount", password)

	mock.ExpectQuery("select user_name, user_password from users where user_id").WillReturnRows(rows)

	assert.NoError(t, user.Password(), "An error was not expected")

	assert.Equal(t, user.Name, "testaccount", "Name should match")

	assert.False(t, user.ComparePassword("badpassword"), "Password should not validate")

}

func TestFromName(t *testing.T) {

	Secret = "secret"

	user := DefaultUser()

	password, err := HashPassword("testpassword")
	if assert.NoError(t, err, "An error was not expected") {
		assert.NotNil(t, password, "password should be returned")
	}

	mock, err := db.NewTestDb()
	assert.NoError(t, err, "An error was not expected")

	rows := sqlmock.NewRows([]string{"id", "password"}).AddRow(2, password)

	mock.ExpectQuery("select user_id, user_password from users where user_name").WillReturnRows(rows)

	assert.NoError(t, user.FromName("testaccount"), "An error was not expected")

	assert.Equal(t, user.Id, 2, "Id should match")

	assert.True(t, user.ComparePassword("testpassword"), "Password should validate")

}

func TestFromNameEmptyName(t *testing.T) {

	Secret = "secret"

	user := DefaultUser()

	assert.Error(t, user.FromName(""), "An error was expected")

}

func TestFromNameBadId(t *testing.T) {

	Secret = "secret"

	user := DefaultUser()

	password, err := HashPassword("testpassword")
	if assert.NoError(t, err, "An error was not expected") {
		assert.NotNil(t, password, "password should be returned")
	}

	mock, err := db.NewTestDb()
	assert.NoError(t, err, "An error was not expected")

	rows := sqlmock.NewRows([]string{"id", "password"}).AddRow(1, password)

	mock.ExpectQuery("select user_id, user_password from users where user_name").WillReturnRows(rows)

	assert.Error(t, user.FromName("testaccount"), "An error was expected")

}
<commit_msg>add user password sql check<commit_after>package user

import (
	"github.com/stretchr/testify/assert"
	"gopkg.in/DATA-DOG/go-sqlmock.v1"
	"testing"

	"github.com/eirka/eirka-libs/config"
	"github.com/eirka/eirka-libs/db"
	e "github.com/eirka/eirka-libs/errors"
)

func init() {
	config.Settings.Limits.PasswordMinLength = 8
	config.Settings.Limits.PasswordMaxLength = 128
}

func TestDefaultUser(t *testing.T) {

	user := DefaultUser()

	assert.Equal(t, uint(1), user.Id, "default user id should be 1")

	assert.False(t, user.IsAuthenticated, "default user should not be authenticated")

}

func TestSetId(t *testing.T) {

	user := DefaultUser()

	user.SetId(2)

	assert.Equal(t, uint(2), user.Id, "user id should be 2")

}

func TestSetAuthenticated(t *testing.T) {

	user := DefaultUser()

	user.SetAuthenticated()

	assert.False(t, user.IsAuthenticated, "User should be not authorized")

	user.SetId(2)

	user.SetAuthenticated()

	assert.True(t, user.IsAuthenticated, "User should be authorized")

	assert.True(t, user.IsValid(), "Authed non-anon user should be valid")

}

func TestIsValid(t *testing.T) {

	user := DefaultUser()

	assert.True(t, user.IsValid(), "DefaultUser should be valid")

	user.SetId(2)

	assert.False(t, user.IsValid(), "Unauthenticated non-anon should be invalid")

	user.SetAuthenticated()

	assert.True(t, user.IsValid(), "Authed non-anon user should be valid")

	user.SetId(0)

	assert.False(t, user.IsValid(), "User zero should be invalid")

	user.SetId(1)

	assert.False(t, user.IsValid(), "An authenticated anon user should be invalid")

}

func TestIsValidName(t *testing.T) {

	assert.True(t, IsValidName("cooldude2"), "Name should validate")

	assert.True(t, IsValidName("cool dude"), "Name should validate")

	assert.True(t, IsValidName("cool_dude"), "Name should validate")

	assert.True(t, IsValidName("cool-dude"), "Name should validate")

	assert.False(t, IsValidName("cool.dude"), "Name should not validate")

	assert.False(t, IsValidName("cooldude!"), "Name should not validate")

	assert.False(t, IsValidName("admin"), "Name should not validate")

	assert.False(t, IsValidName("Admin"), "Name should not validate")

	assert.False(t, IsValidName("Admin "), "Name should not validate")

	assert.False(t, IsValidName(" Admin  "), "Name should not validate")

}

func TestPassword(t *testing.T) {

	_, err := HashPassword("")
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrPasswordEmpty, "Error should match")
	}

	_, err = HashPassword("heh")
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrPasswordShort, "Error should match")
	}

	_, err = HashPassword("k8dyuCqJfW9v5iFUeeS4YOeiuk5Wee6Q9tZvWFHqE10ftzhaxVzxlKzx4n7CcBpRcgtaX9dZ2lBIRrsvgqXPPvmjNpIgnrums2Xtst8FsZkpZo61u3ChCs7MEO1DGy4Qa")
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrPasswordLong, "Error should match")
	}

	password, err := HashPassword("testpassword")
	if assert.NoError(t, err, "An error was not expected") {
		assert.NotNil(t, password, "password should be returned")
	}

	user := DefaultUser()
	user.SetId(2)
	user.SetAuthenticated()

	assert.False(t, user.ComparePassword("atestpassword"), "Password should not validate")

	user.hash = password

	assert.False(t, user.ComparePassword(""), "Password should not validate")

	assert.False(t, user.ComparePassword("wrongpassword"), "Password should not validate")

	assert.True(t, user.ComparePassword("testpassword"), "Password should validate")

}

func TestCreateToken(t *testing.T) {

	Secret = ""

	user := DefaultUser()

	// secret must be set
	token, err := user.CreateToken()
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrNoSecret, "Error should match")
		assert.Empty(t, token, "Token should be empty")
	}

	Secret = "secret"

	// default user state should never get a token
	token, err = user.CreateToken()
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrUserNotValid, "Error should match")
		assert.Empty(t, token, "Token should be empty")
	}

	user.SetId(2)

	// a non authed user should never get a token
	token, err = user.CreateToken()
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrUserNotValid, "Error should match")
		assert.Empty(t, token, "Token should be empty")
	}

	user.SetAuthenticated()

	// a user that doesnt have a validated password should never get a token
	token, err = user.CreateToken()
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrInvalidPassword, "Error should match")
		assert.Empty(t, token, "Token should be empty")
	}

	user.hash, err = HashPassword("testpassword")
	if assert.NoError(t, err, "An error was not expected") {
		assert.NotNil(t, user.hash, "password should be returned")
	}

	assert.True(t, user.ComparePassword("testpassword"), "Password should validate")

	token, err = user.CreateToken()
	if assert.NoError(t, err, "An error was not expected") {
		assert.NotEmpty(t, token, "Token should not be empty")
	}

}

func TestCreateTokenAnonAuth(t *testing.T) {

	Secret = "secret"

	invalidUser := DefaultUser()
	invalidUser.SetId(1)
	invalidUser.SetAuthenticated()

	notoken, err := invalidUser.CreateToken()
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrUserNotValid, "Error should match")
		assert.Empty(t, notoken, "token should not be returned")
	}
}

func TestCreateTokenZeroAuth(t *testing.T) {

	Secret = "secret"

	invalidUser := DefaultUser()
	invalidUser.SetId(0)
	invalidUser.SetAuthenticated()

	notoken, err := invalidUser.CreateToken()
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrUserNotValid, "Error should match")
		assert.Empty(t, notoken, "token should not be returned")
	}
}

func TestCreateTokenZeroNoAuth(t *testing.T) {

	Secret = "secret"

	invalidUser := DefaultUser()
	invalidUser.SetId(0)

	notoken, err := invalidUser.CreateToken()
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, e.ErrUserNotValid, "Error should match")
		assert.Empty(t, notoken, "token should not be returned")
	}
}

func TestUserPassword(t *testing.T) {

	Secret = "secret"

	user := DefaultUser()
	user.SetId(2)
	user.SetAuthenticated()

	password, err := HashPassword("testpassword")
	if assert.NoError(t, err, "An error was not expected") {
		assert.NotNil(t, password, "password should be returned")
	}

	mock, err := db.NewTestDb()
	assert.NoError(t, err, "An error was not expected")

	rows := sqlmock.NewRows([]string{"name", "password"}).AddRow("testaccount", password)

	mock.ExpectQuery("select user_name, user_password from users where user_id").WillReturnRows(rows)

	assert.NoError(t, user.Password(), "An error was not expected")

	assert.Equal(t, user.Name, "testaccount", "Name should match")

	assert.True(t, user.ComparePassword("testpassword"), "Password should validate")

}

func TestUserBadPassword(t *testing.T) {

	Secret = "secret"

	user := DefaultUser()
	user.SetId(2)
	user.SetAuthenticated()

	password, err := HashPassword("testpassword")
	if assert.NoError(t, err, "An error was not expected") {
		assert.NotNil(t, password, "password should be returned")
	}

	mock, err := db.NewTestDb()
	assert.NoError(t, err, "An error was not expected")

	rows := sqlmock.NewRows([]string{"name", "password"}).AddRow("testaccount", password)

	mock.ExpectQuery("select user_name, user_password from users where user_id").WillReturnRows(rows)

	assert.NoError(t, user.Password(), "An error was not expected")

	assert.Equal(t, user.Name, "testaccount", "Name should match")

	assert.False(t, user.ComparePassword("badpassword"), "Password should not validate")

}

func TestFromName(t *testing.T) {

	Secret = "secret"

	user := DefaultUser()

	password, err := HashPassword("testpassword")
	if assert.NoError(t, err, "An error was not expected") {
		assert.NotNil(t, password, "password should be returned")
	}

	mock, err := db.NewTestDb()
	assert.NoError(t, err, "An error was not expected")

	rows := sqlmock.NewRows([]string{"id", "password"}).AddRow(2, password)

	mock.ExpectQuery("select user_id, user_password from users where user_name").WillReturnRows(rows)

	assert.NoError(t, user.FromName("testaccount"), "An error was not expected")

	assert.Equal(t, user.Id, uint(2), "Id should match")

	assert.True(t, user.IsAuthenticated, "User should be authenticated")

	assert.True(t, user.ComparePassword("testpassword"), "Password should validate")

}

func TestFromNameEmptyName(t *testing.T) {

	Secret = "secret"

	user := DefaultUser()

	assert.Error(t, user.FromName(""), "An error was expected")

}

func TestFromNameBadId(t *testing.T) {

	Secret = "secret"

	user := DefaultUser()

	password, err := HashPassword("testpassword")
	if assert.NoError(t, err, "An error was not expected") {
		assert.NotNil(t, password, "password should be returned")
	}

	mock, err := db.NewTestDb()
	assert.NoError(t, err, "An error was not expected")

	rows := sqlmock.NewRows([]string{"id", "password"}).AddRow(1, password)

	mock.ExpectQuery("select user_id, user_password from users where user_name").WillReturnRows(rows)

	assert.Error(t, user.FromName("testaccount"), "An error was expected")

}
<|endoftext|>


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

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

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

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

package latest

import (
	"encoding/json"
	"testing"

	internal "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
	_ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1"
)

func TestResourceVersioner(t *testing.T) {
	pod := internal.Pod{ObjectMeta: internal.ObjectMeta{ResourceVersion: "10"}}
	version, err := accessor.ResourceVersion(&pod)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if version != "10" {
		t.Errorf("unexpected version %v", version)
	}

	podList := internal.PodList{ListMeta: internal.ListMeta{ResourceVersion: "10"}}
	version, err = accessor.ResourceVersion(&podList)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if version != "10" {
		t.Errorf("unexpected version %v", version)
	}
}

func TestCodec(t *testing.T) {
	pod := internal.Pod{}
	data, err := Codec.Encode(&pod)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	other := internal.Pod{}
	if err := json.Unmarshal(data, &other); err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if other.APIVersion != Version || other.Kind != "Pod" {
		t.Errorf("unexpected unmarshalled object %#v", other)
	}
}

func TestInterfacesFor(t *testing.T) {
	if _, err := InterfacesFor(""); err == nil {
		t.Fatalf("unexpected non-error: %v", err)
	}
	for i, version := range append([]string{Version, OldestVersion}, Versions...) {
		if vi, err := InterfacesFor(version); err != nil || vi == nil {
			t.Fatalf("%d: unexpected result: %v", i, err)
		}
	}
}

func TestRESTMapper(t *testing.T) {
	if v, k, err := RESTMapper.VersionAndKindForResource("replicationControllers"); err != nil || v != "v1beta3" || k != "ReplicationController" {
		t.Errorf("unexpected version mapping: %s %s %v", v, k, err)
	}
	if v, k, err := RESTMapper.VersionAndKindForResource("replicationcontrollers"); err != nil || v != "v1beta3" || k != "ReplicationController" {
		t.Errorf("unexpected version mapping: %s %s %v", v, k, err)
	}

	if m, err := RESTMapper.RESTMapping("PodTemplate", ""); err != nil || m.APIVersion != "v1beta3" || m.Resource != "podtemplates" {
		t.Errorf("unexpected version mapping: %#v %v", m, err)
	}

	for _, version := range Versions {
		mapping, err := RESTMapper.RESTMapping("ReplicationController", version)
		if err != nil {
			t.Errorf("unexpected error: %v", err)
		}

		if mapping.Resource != "replicationControllers" && mapping.Resource != "replicationcontrollers" {
			t.Errorf("incorrect resource name: %#v", mapping)
		}
		if mapping.APIVersion != version {
			t.Errorf("incorrect version: %v", mapping)
		}

		interfaces, _ := InterfacesFor(version)
		if mapping.Codec != interfaces.Codec {
			t.Errorf("unexpected codec: %#v, expected: %#v", mapping, interfaces)
		}

		rc := &internal.ReplicationController{ObjectMeta: internal.ObjectMeta{Name: "foo"}}
		name, err := mapping.MetadataAccessor.Name(rc)
		if err != nil {
			t.Errorf("unexpected error: %v", err)
		}
		if name != "foo" {
			t.Errorf("unable to retrieve object meta with: %v", mapping.MetadataAccessor)
		}
	}
}
<commit_msg>remove imports of v1 in latest_test.go<commit_after>/*
Copyright 2014 The Kubernetes Authors All rights reserved.

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

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

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

package latest

import (
	"encoding/json"
	"testing"

	internal "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
)

func TestResourceVersioner(t *testing.T) {
	pod := internal.Pod{ObjectMeta: internal.ObjectMeta{ResourceVersion: "10"}}
	version, err := accessor.ResourceVersion(&pod)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if version != "10" {
		t.Errorf("unexpected version %v", version)
	}

	podList := internal.PodList{ListMeta: internal.ListMeta{ResourceVersion: "10"}}
	version, err = accessor.ResourceVersion(&podList)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if version != "10" {
		t.Errorf("unexpected version %v", version)
	}
}

func TestCodec(t *testing.T) {
	pod := internal.Pod{}
	data, err := Codec.Encode(&pod)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	other := internal.Pod{}
	if err := json.Unmarshal(data, &other); err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if other.APIVersion != Version || other.Kind != "Pod" {
		t.Errorf("unexpected unmarshalled object %#v", other)
	}
}

func TestInterfacesFor(t *testing.T) {
	if _, err := InterfacesFor(""); err == nil {
		t.Fatalf("unexpected non-error: %v", err)
	}
	for i, version := range append([]string{Version, OldestVersion}, Versions...) {
		if vi, err := InterfacesFor(version); err != nil || vi == nil {
			t.Fatalf("%d: unexpected result: %v", i, err)
		}
	}
}

func TestRESTMapper(t *testing.T) {
	if v, k, err := RESTMapper.VersionAndKindForResource("replicationControllers"); err != nil || v != "v1beta3" || k != "ReplicationController" {
		t.Errorf("unexpected version mapping: %s %s %v", v, k, err)
	}
	if v, k, err := RESTMapper.VersionAndKindForResource("replicationcontrollers"); err != nil || v != "v1beta3" || k != "ReplicationController" {
		t.Errorf("unexpected version mapping: %s %s %v", v, k, err)
	}

	if m, err := RESTMapper.RESTMapping("PodTemplate", ""); err != nil || m.APIVersion != "v1beta3" || m.Resource != "podtemplates" {
		t.Errorf("unexpected version mapping: %#v %v", m, err)
	}

	for _, version := range Versions {
		mapping, err := RESTMapper.RESTMapping("ReplicationController", version)
		if err != nil {
			t.Errorf("unexpected error: %v", err)
		}

		if mapping.Resource != "replicationControllers" && mapping.Resource != "replicationcontrollers" {
			t.Errorf("incorrect resource name: %#v", mapping)
		}
		if mapping.APIVersion != version {
			t.Errorf("incorrect version: %v", mapping)
		}

		interfaces, _ := InterfacesFor(version)
		if mapping.Codec != interfaces.Codec {
			t.Errorf("unexpected codec: %#v, expected: %#v", mapping, interfaces)
		}

		rc := &internal.ReplicationController{ObjectMeta: internal.ObjectMeta{Name: "foo"}}
		name, err := mapping.MetadataAccessor.Name(rc)
		if err != nil {
			t.Errorf("unexpected error: %v", err)
		}
		if name != "foo" {
			t.Errorf("unable to retrieve object meta with: %v", mapping.MetadataAccessor)
		}
	}
}
<|endoftext|>