<commit_before>package agent

import (
	"encoding/json"
	"fmt"
	"github.com/zenoss/serviced"
	"github.com/zenoss/serviced/dao"
	"testing"
	"time"
)

const example_state = `
[{
    "ID": "af5163d96bdc1532875f0f0601ae32a7eafadfdd287d9df6cf2b2020ddfb930d",
    "Created": "2013-09-04T22:35:32.473288901-05:00",
    "Path": "/serviced/serviced",
    "Args": [
        "proxy",
        "dda3d6af-61ef-35ff-4632-086af9b78c90",
        "/bin/nc -l 3306"
    ],
    "Config": {
        "Hostname": "af5163d96bdc",
        "User": "",
        "Memory": 0,
        "MemorySwap": 0,
        "CpuShares": 0,
        "AttachStdin": false,
        "AttachStdout": false,
        "AttachStderr": false,
        "PortSpecs": [
            "3306"
        ],
        "Tty": false,
        "OpenStdin": false,
        "StdinOnce": false,
        "Env": null,
        "Cmd": [
            "/serviced/serviced",
            "proxy",
            "dda3d6af-61ef-35ff-4632-086af9b78c90",
            "/bin/nc -l 3306"
        ],
        "Dns": [
            "8.8.8.8",
            "8.8.4.4"
        ],
        "Image": "base",
        "Volumes": {
            "/serviced": {}
        },
        "VolumesFrom": "",
        "WorkingDir": "",
        "Entrypoint": [],
        "NetworkDisabled": false,
        "Privileged": false
    },
    "State": {
        "Running": true,
        "Pid": 5232,
        "ExitCode": 0,
        "StartedAt": "2013-09-04T22:35:32.485677934-05:00",
        "Ghost": false
    },
    "Image": "b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc",
    "NetworkSettings": {
        "IPAddress": "172.17.0.4",
        "IPPrefixLen": 16,
        "Gateway": "172.17.42.1",
        "Bridge": "docker0",
        "PortMapping": {
            "Tcp": {
                "3306": "49156"
            },
            "Udp": {}
        }
    },
    "SysInitPath": "/usr/bin/docker",
    "ResolvConfPath": "/var/lib/docker/containers/af5163d96bdc1532875f0f0601ae32a7eafadfdd287d9df6cf2b2020ddfb930d/resolv.conf",
    "Volumes": {
        "/serviced": "/home/daniel/mygo/src/github.com/zenoss/serviced/serviced"
    },
    "VolumesRW": {
        "/serviced": true
    }
}]
`

// Test parsing container state from docker.
func TestParseContainerState(t *testing.T) {
	var testState []serviced.ContainerState

	err := json.Unmarshal([]byte(example_state), &testState)
	if err != nil {
		t.Fatalf("Problem unmarshaling test state: ", err)
	}
	fmt.Printf("%s", testState)

}
<commit_msg>unit test was failing with unused imports<commit_after>package agent

import (
	"encoding/json"
	"fmt"
	"github.com/zenoss/serviced"
	"testing"
)

const example_state = `
[{
    "ID": "af5163d96bdc1532875f0f0601ae32a7eafadfdd287d9df6cf2b2020ddfb930d",
    "Created": "2013-09-04T22:35:32.473288901-05:00",
    "Path": "/serviced/serviced",
    "Args": [
        "proxy",
        "dda3d6af-61ef-35ff-4632-086af9b78c90",
        "/bin/nc -l 3306"
    ],
    "Config": {
        "Hostname": "af5163d96bdc",
        "User": "",
        "Memory": 0,
        "MemorySwap": 0,
        "CpuShares": 0,
        "AttachStdin": false,
        "AttachStdout": false,
        "AttachStderr": false,
        "PortSpecs": [
            "3306"
        ],
        "Tty": false,
        "OpenStdin": false,
        "StdinOnce": false,
        "Env": null,
        "Cmd": [
            "/serviced/serviced",
            "proxy",
            "dda3d6af-61ef-35ff-4632-086af9b78c90",
            "/bin/nc -l 3306"
        ],
        "Dns": [
            "8.8.8.8",
            "8.8.4.4"
        ],
        "Image": "base",
        "Volumes": {
            "/serviced": {}
        },
        "VolumesFrom": "",
        "WorkingDir": "",
        "Entrypoint": [],
        "NetworkDisabled": false,
        "Privileged": false
    },
    "State": {
        "Running": true,
        "Pid": 5232,
        "ExitCode": 0,
        "StartedAt": "2013-09-04T22:35:32.485677934-05:00",
        "Ghost": false
    },
    "Image": "b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc",
    "NetworkSettings": {
        "IPAddress": "172.17.0.4",
        "IPPrefixLen": 16,
        "Gateway": "172.17.42.1",
        "Bridge": "docker0",
        "PortMapping": {
            "Tcp": {
                "3306": "49156"
            },
            "Udp": {}
        }
    },
    "SysInitPath": "/usr/bin/docker",
    "ResolvConfPath": "/var/lib/docker/containers/af5163d96bdc1532875f0f0601ae32a7eafadfdd287d9df6cf2b2020ddfb930d/resolv.conf",
    "Volumes": {
        "/serviced": "/home/daniel/mygo/src/github.com/zenoss/serviced/serviced"
    },
    "VolumesRW": {
        "/serviced": true
    }
}]
`

// Test parsing container state from docker.
func TestParseContainerState(t *testing.T) {
	var testState []serviced.ContainerState

	err := json.Unmarshal([]byte(example_state), &testState)
	if err != nil {
		t.Fatalf("Problem unmarshaling test state: ", err)
	}
	fmt.Printf("%s", testState)

}
<|endoftext|>


<commit_before>package abbr

import (
	"strings"
)

var Names = map[string]string{
	"abbreviat":            "abbrev",
	"absolut":              "abs",
	"account":              "acct",
	"accumulat":            "accum",
	"accuracy":             "acc",
	"accurat":              "acc",
	"actual":               "act",
	"addend":               "adn",
	"address":              "addr",
	"aggregat":             "agg",
	"algebra":              "alg",
	"algorithm":            "algo",
	"ancestor":             "anc",
	"approximat":           "approx",
	"architect":            "arch",
	"argument":             "arg",
	"ascending":            "asc",
	"attribut":             "attr",
	"averag":               "avg",
	"binary":               "bin",
	"binomial":             "binom",
	"boolean":              "bool",
	"buffer":               "buf",
	"calculat":             "calc",
	"calculus":             "calc",
	"calendar":             "cal",
	"capacity":             "cap",
	"capitalization":       "cap",
	"capitaliz":            "cap",
	"ceiling":              "ceil",
	"certificat":           "cert",
	"certify":              "cert",
	"channel":              "chan",
	"character":            "char",
	"coefficient":          "coef",
	"collect":              "coll",
	"column":               "col",
	"combination":          "comb",
	"combin":               "comb",
	"command":              "cmd",
	"compar":               "comp",
	"compensat":            "comp",
	"complex":              "cop",
	"condition":            "cond",
	"configuration":        "conf",
	"configur":             "conf",
	"connect":              "conn",
	"constant":             "const",
	"contain":              "cont",
	"context":              "ctx",
	"continuation":         "cont",
	"continu":              "cont",
	"control":              "ctl",
	"conversion":           "conv",
	"convert":              "conv",
	"cosecant":             "csc",
	"cosin":                "cos",
	"cotangent":            "cot",
	"count":                "cnt",
	"current":              "cur",
	"decimal":              "dec",
	"declaration":          "decl",
	"declar":               "decl",
	"decod":                "dec",
	"decrement":            "dec",
	"decrypt":              "dec",
	"defin":                "def",
	"definition":           "def",
	"degre":                "deg",
	"delet":                "del",
	"deletion":             "del",
	"delimiter":            "delim",
	"denominat":            "den",
	"depend":               "dep",
	"descendant":           "des",
	"descending":           "desc",
	"describ":              "desc",
	"description":          "desc",
	"destination":          "dest",
	"destin":               "dest",
	"determinant":          "det",
	"develop":              "dev",
	"deviat":               "dev",
	"diagonal":             "diag",
	"diameter":             "diam",
	"dictionary":           "dict",
	"differenc":            "diff",
	"dimension":            "dim",
	"direct":               "dir",
	"discriminant":         "disc",
	"distanc":              "dist",
	"distribut":            "dist",
	"divid":                "div",
	"document":             "doc",
	"domain":               "dom",
	"duplicat":             "dupe",
	"element":              "elem",
	"employe":              "emp",
	"encod":                "enc",
	"encrypt":              "enc",
	"entropy":              "ent",
	"enumerat":             "enum",
	"environment":          "env",
	"equivalenc":           "equiv",
	"equivalent":           "equiv",
	"error":                "err",
	"escap":                "esc",
	"estimat":              "est",
	"evaluat":              "eval",
	"except":               "excp",
	"exclud":               "excl",
	"exclusion":            "excl",
	"exclusiveor":          "xor",
	"execut":               "exec",
	"execution":            "exec",
	"expect":               "exp",
	"exponent":             "exp",
	"express":              "expr",
	"extend":               "ext",
	"extension":            "ext",
	"external":             "ext",
	"factor":               "fac",
	"factorial":            "facl",
	"field":                "fld",
	"figur":                "fig",
	"floating":             "float",
	"format":               "fmt",
	"forward":              "fwd",
	"fraction":             "frac",
	"frequency":            "freq",
	"frequent":             "freq",
	"function":             "func",
	"general":              "gen",
	"generat":              "gen",
	"generic":              "gen",
	"geometric":            "geom",
	"guarante":             "guar",
	"handl":                "hdl",
	"harmonic":             "har",
	"header":               "hdr",
	"hexadecimal":          "hex",
	"horizontal":           "horiz",
	"identification":       "ident",
	"identifier":           "ident",
	"imag":                 "img",
	"imaginary":            "imag",
	"immediat":             "imm",
	"implement":            "imp",
	"includ":               "incl",
	"inclusion":            "incl",
	"increment":            "inc",
	"independent":          "indep",
	"indicat":              "ind",
	"indirect":             "ind",
	"information":          "info",
	"initial":              "init",
	"initialization":       "init",
	"input":                "in",
	"insert":               "ins",
	"instanc":              "inst",
	"instantiat":           "inst",
	"instruct":             "inst",
	"integer":              "int",
	"intercept":            "intc",
	"interfac":             "intf",
	"internal":             "int",
	"internationalization": "i18n",
	"intersection":         "intx",
	"invers":               "inv",
	"iterat":               "iter",
	"kurtosis":             "kurt",
	"languag":              "lang",
	"length":               "len",
	"lexicon":              "lex",
	"library":              "lib",
	"limit":                "lim",
	"linear":               "lin",
	"literal":              "lit",
	"localization":         "l10n",
	"locat":                "loc",
	"logarithm":            "log",
	"lowercas":             "low",
	"machin":               "mach",
	"mantissa":             "mant",
	"maximum":              "max",
	"median":               "med",
	"medium":               "med",
	"memory":               "mem",
	"messag":               "msg",
	"minimum":              "min",
	"minut":                "min",
	"modification":         "mod",
	"modify":               "mod",
	"modul":                "mod",
	"modulo":               "mod",
	"multipl":              "multi",
	"multiply":             "mul",
	"mutabl":               "mut",
	"mutat":                "mut",
	"mutual":               "mutl",
	"mutualexclusion":      "mutex",
	"natural":              "nat",
	"negat":                "neg",
	"negativ":              "neg",
	"network":              "net",
	"number":               "num",
	"numerat":              "num",
	"object":               "obj",
	"octal":                "oct",
	"operat":               "op",
	"option":               "opt",
	"original":             "orig",
	"originat":             "orig",
	"output":               "out",
	"overflow":             "ovfl",
	"packag":               "pkg",
	"paragraph":            "para",
	"parallel":             "parl",
	"parameter":            "param",
	"parent":               "par",
	"pattern":              "pat",
	"perform":              "perf",
	"perimeter":            "perim",
	"permanent":            "perm",
	"permutat":             "perm",
	"perpendicular":        "perp",
	"phonetic":             "phon",
	"pictur":               "pic",
	"pointer":              "ptr",
	"position":             "pos",
	"positiv":              "pos",
	"possibl":              "poss",
	"possibly":             "poss",
	"precis":               "prec",
	"precision":            "prec",
	"preparation":          "prep",
	"prepar":               "prep",
	"previous":             "prev",
	"primary":              "pri",
	"prioritiz":            "prio",
	"priority":             "prio",
	"privat":               "pri",
	"probability":          "prob",
	"procedur":             "proc",
	"process":              "proc",
	"product":              "prod",
	"profil":               "prof",
	"program":              "prog",
	"progress":             "prog",
	"project":              "proj",
	"pronounc":             "pron",
	"pronunciation":        "pron",
	"proportion":           "prop",
	"protocol":             "prot",
	"prototyp":             "proto",
	"punctuat":             "punct",
	"public":               "pub",
	"quadratic":            "quad",
	"query":                "qry",
	"quotient":             "quot",
	"random":               "rand",
	"ratio":                "rat",
	"receiv":               "recv",
	"record":               "rec",
	"rectangl":             "rect",
	"recursiv":             "rec",
	"referenc":             "ref",
	"register":             "reg",
	"regular":              "reg",
	"regularexpression":    "regexp",
	"relat":                "rel",
	"relativ":              "rel",
	"remainder":            "rem",
	"repeat":               "rep",
	"repetition":           "rep",
	"replac":               "repl",
	"repository":           "repo",
	"represent":            "rep",
	"requir":               "req",
	"resourc":              "res",
	"respond":              "resp",
	"respons":              "resp",
	"responsiv":            "resp",
	"result":               "res",
	"return":               "ret",
	"revers":               "rev",
	"sanitization":         "san",
	"sanitiz":              "san",
	"schedul":              "sched",
	"scienc":               "sci",
	"scientific":           "sci",
	"secant":               "sec",
	"second":               "sec",
	"section":              "sect",
	"secur":                "sec",
	"security":             "sec",
	"segment":              "seg",
	"select":               "sel",
	"sentenc":              "sent",
	"separat":              "sep",
	"sequenc":              "seq",
	"server":               "srv",
	"signal":               "sig",
	"signatur":             "sig",
	"sin":                  "sin",
	"socket":               "sock",
	"sourc":                "src",
	"specific":             "spec",
	"specify":              "spec",
	"standard":             "std",
	"statement":            "stm",
	"statistic":            "stat",
	"string":               "str",
	"structur":             "struct",
	"subtract":             "sub",
	"surfac":               "surf",
	"symbol":               "sym",
	"symmetry":             "symm",
	"synchroniz":           "sync",
	"system":               "sys",
	"tabl":                 "tbl",
	"tangent":              "tan",
	"technology":           "tech",
	"templat":              "temp",
	"temporary":            "temp",
	"terminal":             "term",
	"terminat":             "term",
	"token":                "tok",
	"transfer":             "xfer",
	"translat":             "xlat",
	"transmission":         "xmis",
	"transmit":             "xmit",
	"trigonometry":         "trig",
	"updat":                "upd",
	"uppercas":             "up",
	"utility":              "util",
	"validat":              "val",
	"valu":                 "val",
	"variabl":              "var",
	"varianc":              "var",
	"vector":               "vec",
	"verification":         "ver",
	"verify":               "ver",
	"version":              "ver",
	"vertical":             "vert",
	"visibility":           "vis",
	"visibl":               "vis",
	"volum":                "vol",
	"window":               "win",
}

// LookUp looks up a word to find its short form, if it is known.
func LookUp(word string) string {
	lowWord := strings.ToLower(word)
	for long, short := range Names {
		if strings.Contains(lowWord, long) {
			return short
		}
	}
	return ""
}
<commit_msg>Removing y<commit_after>package abbr

import (
	"strings"
)

var Names = map[string]string{
	"abbreviat":            "abbrev",
	"absolut":              "abs",
	"account":              "acct",
	"accumulat":            "accum",
	"accurac":              "acc",
	"accurat":              "acc",
	"actual":               "act",
	"addend":               "adn",
	"address":              "addr",
	"aggregat":             "agg",
	"algebra":              "alg",
	"algorithm":            "algo",
	"ancestor":             "anc",
	"approximat":           "approx",
	"architect":            "arch",
	"argument":             "arg",
	"ascending":            "asc",
	"attribut":             "attr",
	"averag":               "avg",
	"binar":                "bin",
	"binomial":             "binom",
	"boolean":              "bool",
	"buffer":               "buf",
	"calculat":             "calc",
	"calculus":             "calc",
	"calendar":             "cal",
	"capacit":              "cap",
	"capitalization":       "cap",
	"capitaliz":            "cap",
	"ceiling":              "ceil",
	"certificat":           "cert",
	"certif":               "cert",
	"channel":              "chan",
	"character":            "char",
	"coefficient":          "coef",
	"collect":              "coll",
	"column":               "col",
	"combination":          "comb",
	"combin":               "comb",
	"command":              "cmd",
	"compar":               "comp",
	"compensat":            "comp",
	"complex":              "cop",
	"condition":            "cond",
	"configuration":        "conf",
	"configur":             "conf",
	"connect":              "conn",
	"constant":             "const",
	"contain":              "cont",
	"context":              "ctx",
	"continuation":         "cont",
	"continu":              "cont",
	"control":              "ctl",
	"conversion":           "conv",
	"convert":              "conv",
	"cosecant":             "csc",
	"cosin":                "cos",
	"cotangent":            "cot",
	"count":                "cnt",
	"current":              "cur",
	"decimal":              "dec",
	"declaration":          "decl",
	"declar":               "decl",
	"decod":                "dec",
	"decrement":            "dec",
	"decrypt":              "dec",
	"defin":                "def",
	"definition":           "def",
	"degre":                "deg",
	"delet":                "del",
	"deletion":             "del",
	"delimiter":            "delim",
	"denominat":            "den",
	"depend":               "dep",
	"descendant":           "des",
	"descending":           "desc",
	"describ":              "desc",
	"description":          "desc",
	"destination":          "dest",
	"destin":               "dest",
	"determinant":          "det",
	"develop":              "dev",
	"deviat":               "dev",
	"diagonal":             "diag",
	"diameter":             "diam",
	"dictionar":            "dict",
	"differenc":            "diff",
	"dimension":            "dim",
	"direct":               "dir",
	"discriminant":         "disc",
	"distanc":              "dist",
	"distribut":            "dist",
	"divid":                "div",
	"document":             "doc",
	"domain":               "dom",
	"duplicat":             "dupe",
	"element":              "elem",
	"employe":              "emp",
	"encod":                "enc",
	"encrypt":              "enc",
	"entrop":               "ent",
	"enumerat":             "enum",
	"environment":          "env",
	"equivalenc":           "equiv",
	"equivalent":           "equiv",
	"error":                "err",
	"escap":                "esc",
	"estimat":              "est",
	"evaluat":              "eval",
	"except":               "excp",
	"exclud":               "excl",
	"exclusion":            "excl",
	"exclusiveor":          "xor",
	"execut":               "exec",
	"execution":            "exec",
	"expect":               "exp",
	"exponent":             "exp",
	"express":              "expr",
	"extend":               "ext",
	"extension":            "ext",
	"external":             "ext",
	"factor":               "fac",
	"factorial":            "facl",
	"field":                "fld",
	"figur":                "fig",
	"floating":             "float",
	"format":               "fmt",
	"forward":              "fwd",
	"fraction":             "frac",
	"frequenc":             "freq",
	"frequent":             "freq",
	"function":             "func",
	"general":              "gen",
	"generat":              "gen",
	"generic":              "gen",
	"geometric":            "geom",
	"guarante":             "guar",
	"handl":                "hdl",
	"harmonic":             "har",
	"header":               "hdr",
	"hexadecimal":          "hex",
	"horizontal":           "horiz",
	"identification":       "ident",
	"identifier":           "ident",
	"imag":                 "img",
	"imaginar":             "imag",
	"immediat":             "imm",
	"implement":            "imp",
	"includ":               "incl",
	"inclusion":            "incl",
	"increment":            "inc",
	"independent":          "indep",
	"indicat":              "ind",
	"indirect":             "ind",
	"information":          "info",
	"initial":              "init",
	"initialization":       "init",
	"input":                "in",
	"insert":               "ins",
	"instanc":              "inst",
	"instantiat":           "inst",
	"instruct":             "inst",
	"integer":              "int",
	"intercept":            "intc",
	"interfac":             "intf",
	"internal":             "int",
	"internationalization": "i18n",
	"intersection":         "intx",
	"invers":               "inv",
	"iterat":               "iter",
	"kurtosis":             "kurt",
	"languag":              "lang",
	"length":               "len",
	"lexicon":              "lex",
	"librar":               "lib",
	"limit":                "lim",
	"linear":               "lin",
	"literal":              "lit",
	"localization":         "l10n",
	"locat":                "loc",
	"logarithm":            "log",
	"lowercas":             "low",
	"machin":               "mach",
	"mantissa":             "mant",
	"maximum":              "max",
	"median":               "med",
	"medium":               "med",
	"memor":                "mem",
	"messag":               "msg",
	"minimum":              "min",
	"minut":                "min",
	"modif":                "mod",
	"modul":                "mod",
	"modulo":               "mod",
	"multipl":              "multi",
	"mutabl":               "mut",
	"mutat":                "mut",
	"mutual":               "mutl",
	"mutualexclusion":      "mutex",
	"natural":              "nat",
	"negat":                "neg",
	"negativ":              "neg",
	"network":              "net",
	"number":               "num",
	"numerat":              "num",
	"object":               "obj",
	"octal":                "oct",
	"operat":               "op",
	"option":               "opt",
	"original":             "orig",
	"originat":             "orig",
	"output":               "out",
	"overflow":             "ovfl",
	"packag":               "pkg",
	"paragraph":            "para",
	"parallel":             "parl",
	"parameter":            "param",
	"parent":               "par",
	"pattern":              "pat",
	"perform":              "perf",
	"perimeter":            "perim",
	"permanent":            "perm",
	"permutat":             "perm",
	"perpendicular":        "perp",
	"phonetic":             "phon",
	"pictur":               "pic",
	"pointer":              "ptr",
	"position":             "pos",
	"positiv":              "pos",
	"possibl":              "poss",
	"precis":               "prec",
	"precision":            "prec",
	"preparation":          "prep",
	"prepar":               "prep",
	"previous":             "prev",
	"primar":               "pri",
	"priorit":              "prio",
	"privat":               "pri",
	"probab":               "prob",
	"procedur":             "proc",
	"process":              "proc",
	"product":              "prod",
	"profil":               "prof",
	"program":              "prog",
	"progress":             "prog",
	"project":              "proj",
	"pronounc":             "pron",
	"pronunciation":        "pron",
	"proportion":           "prop",
	"protocol":             "prot",
	"prototyp":             "proto",
	"punctuat":             "punct",
	"public":               "pub",
	"quadratic":            "quad",
	"quer":                 "qry",
	"quotient":             "quot",
	"random":               "rand",
	"ratio":                "rat",
	"receiv":               "recv",
	"record":               "rec",
	"rectangl":             "rect",
	"recursiv":             "rec",
	"referenc":             "ref",
	"register":             "reg",
	"regular":              "reg",
	"regularexpression":    "regexp",
	"relat":                "rel",
	"relativ":              "rel",
	"remainder":            "rem",
	"repeat":               "rep",
	"repetition":           "rep",
	"replac":               "repl",
	"repositor":            "repo",
	"represent":            "rep",
	"requir":               "req",
	"resourc":              "res",
	"respond":              "resp",
	"respons":              "resp",
	"responsiv":            "resp",
	"result":               "res",
	"return":               "ret",
	"revers":               "rev",
	"sanitization":         "san",
	"sanitiz":              "san",
	"schedul":              "sched",
	"scienc":               "sci",
	"scientific":           "sci",
	"secant":               "sec",
	"second":               "sec",
	"section":              "sect",
	"secur":                "sec",
	"securit":              "sec",
	"segment":              "seg",
	"select":               "sel",
	"sentenc":              "sent",
	"separat":              "sep",
	"sequenc":              "seq",
	"server":               "srv",
	"signal":               "sig",
	"signatur":             "sig",
	"sin":                  "sin",
	"socket":               "sock",
	"sourc":                "src",
	"specif":               "spec",
	"standard":             "std",
	"statement":            "stm",
	"statistic":            "stat",
	"string":               "str",
	"structur":             "struct",
	"subtract":             "sub",
	"surfac":               "surf",
	"symbol":               "sym",
	"symmetr":              "symm",
	"synchroniz":           "sync",
	"system":               "sys",
	"tabl":                 "tbl",
	"tangent":              "tan",
	"technolog":            "tech",
	"templat":              "temp",
	"temporar":             "temp",
	"terminal":             "term",
	"terminat":             "term",
	"token":                "tok",
	"transfer":             "xfer",
	"translat":             "xlat",
	"transmission":         "xmis",
	"transmit":             "xmit",
	"trigonometr":          "trig",
	"updat":                "upd",
	"uppercas":             "up",
	"utilit":               "util",
	"validat":              "val",
	"valu":                 "val",
	"variabl":              "var",
	"varianc":              "var",
	"vector":               "vec",
	"verif":                "ver",
	"version":              "ver",
	"vertical":             "vert",
	"visibilit":            "vis",
	"visibl":               "vis",
	"volum":                "vol",
	"window":               "win",
}

// LookUp looks up a word to find its short form, if it is known.
func LookUp(word string) string {
	lowWord := strings.ToLower(word)
	for long, short := range Names {
		if strings.Contains(lowWord, long) {
			return short
		}
	}
	return ""
}
<|endoftext|>


<commit_before>package dht

import (
	"context"
	"fmt"
	"strings"

	cid "github.com/ipfs/go-cid"
	logging "github.com/ipfs/go-log"
	pb "github.com/libp2p/go-libp2p-kad-dht/pb"
	kb "github.com/libp2p/go-libp2p-kbucket"
	peer "github.com/libp2p/go-libp2p-peer"
	notif "github.com/libp2p/go-libp2p-routing/notifications"
)

func tryFormatLoggableKey(k string) (string, error) {
	if len(k) == 0 {
		return "", fmt.Errorf("loggableKey is empty")
	}
	var proto, cstr string
	if k[0] == '/' {
		// it's a path (probably)
		protoEnd := strings.IndexByte(k[1:], '/')
		if protoEnd < 0 {
			return k, fmt.Errorf("loggableKey starts with '/' but is not a path: %x", k)
		}
		proto = k[1 : protoEnd+1]
		cstr = k[protoEnd+2:]
	} else {
		proto = "provider"
		cstr = k
	}

	c, err := cid.Cast([]byte(cstr))
	if err != nil {
		return "", fmt.Errorf("loggableKey could not cast key to a CID: %x %v", k, err)
	}
	return fmt.Sprintf("/%s/%s", proto, c.String()), nil
}

func loggableKey(k string) logging.LoggableMap {
	newKey, err := tryFormatLoggableKey(k)
	if err != nil {
		log.Error(err)
	} else {
		k = newKey
	}

	return logging.LoggableMap{
		"key": k,
	}
}

// Kademlia 'node lookup' operation. Returns a channel of the K closest peers
// to the given key
func (dht *IpfsDHT) GetClosestPeers(ctx context.Context, key string) (<-chan peer.ID, error) {
	e := log.EventBegin(ctx, "getClosestPeers", loggableKey(key))
	tablepeers := dht.routingTable.NearestPeers(kb.ConvertKey(key), AlphaValue)
	if len(tablepeers) == 0 {
		return nil, kb.ErrLookupFailure
	}

	out := make(chan peer.ID, KValue)

	// since the query doesnt actually pass our context down
	// we have to hack this here. whyrusleeping isnt a huge fan of goprocess
	parent := ctx
	query := dht.newQuery(key, func(ctx context.Context, p peer.ID) (*dhtQueryResult, error) {
		// For DHT query command
		notif.PublishQueryEvent(parent, &notif.QueryEvent{
			Type: notif.SendingQuery,
			ID:   p,
		})

		pmes, err := dht.findPeerSingle(ctx, p, peer.ID(key))
		if err != nil {
			log.Debugf("error getting closer peers: %s", err)
			return nil, err
		}
		peers := pb.PBPeersToPeerInfos(pmes.GetCloserPeers())

		// For DHT query command
		notif.PublishQueryEvent(parent, &notif.QueryEvent{
			Type:      notif.PeerResponse,
			ID:        p,
			Responses: peers,
		})

		return &dhtQueryResult{closerPeers: peers}, nil
	})

	go func() {
		defer close(out)
		defer e.Done()
		// run it!
		res, err := query.Run(ctx, tablepeers)
		if err != nil {
			log.Debugf("closestPeers query run error: %s", err)
		}

		if res != nil && res.finalSet != nil {
			sorted := kb.SortClosestPeers(res.finalSet.Peers(), kb.ConvertKey(key))
			if len(sorted) > KValue {
				sorted = sorted[:KValue]
			}

			for _, p := range sorted {
				out <- p
			}
		}
	}()

	return out, nil
}
<commit_msg>downgrade Error log for loggable formatting<commit_after>package dht

import (
	"context"
	"fmt"
	"strings"

	cid "github.com/ipfs/go-cid"
	logging "github.com/ipfs/go-log"
	pb "github.com/libp2p/go-libp2p-kad-dht/pb"
	kb "github.com/libp2p/go-libp2p-kbucket"
	peer "github.com/libp2p/go-libp2p-peer"
	notif "github.com/libp2p/go-libp2p-routing/notifications"
)

func tryFormatLoggableKey(k string) (string, error) {
	if len(k) == 0 {
		return "", fmt.Errorf("loggableKey is empty")
	}
	var proto, cstr string
	if k[0] == '/' {
		// it's a path (probably)
		protoEnd := strings.IndexByte(k[1:], '/')
		if protoEnd < 0 {
			return k, fmt.Errorf("loggableKey starts with '/' but is not a path: %x", k)
		}
		proto = k[1 : protoEnd+1]
		cstr = k[protoEnd+2:]
	} else {
		proto = "provider"
		cstr = k
	}

	c, err := cid.Cast([]byte(cstr))
	if err != nil {
		return "", fmt.Errorf("loggableKey could not cast key to a CID: %x %v", k, err)
	}
	return fmt.Sprintf("/%s/%s", proto, c.String()), nil
}

func loggableKey(k string) logging.LoggableMap {
	newKey, err := tryFormatLoggableKey(k)
	if err != nil {
		log.Debug(err)
	} else {
		k = newKey
	}

	return logging.LoggableMap{
		"key": k,
	}
}

// Kademlia 'node lookup' operation. Returns a channel of the K closest peers
// to the given key
func (dht *IpfsDHT) GetClosestPeers(ctx context.Context, key string) (<-chan peer.ID, error) {
	e := log.EventBegin(ctx, "getClosestPeers", loggableKey(key))
	tablepeers := dht.routingTable.NearestPeers(kb.ConvertKey(key), AlphaValue)
	if len(tablepeers) == 0 {
		return nil, kb.ErrLookupFailure
	}

	out := make(chan peer.ID, KValue)

	// since the query doesnt actually pass our context down
	// we have to hack this here. whyrusleeping isnt a huge fan of goprocess
	parent := ctx
	query := dht.newQuery(key, func(ctx context.Context, p peer.ID) (*dhtQueryResult, error) {
		// For DHT query command
		notif.PublishQueryEvent(parent, &notif.QueryEvent{
			Type: notif.SendingQuery,
			ID:   p,
		})

		pmes, err := dht.findPeerSingle(ctx, p, peer.ID(key))
		if err != nil {
			log.Debugf("error getting closer peers: %s", err)
			return nil, err
		}
		peers := pb.PBPeersToPeerInfos(pmes.GetCloserPeers())

		// For DHT query command
		notif.PublishQueryEvent(parent, &notif.QueryEvent{
			Type:      notif.PeerResponse,
			ID:        p,
			Responses: peers,
		})

		return &dhtQueryResult{closerPeers: peers}, nil
	})

	go func() {
		defer close(out)
		defer e.Done()
		// run it!
		res, err := query.Run(ctx, tablepeers)
		if err != nil {
			log.Debugf("closestPeers query run error: %s", err)
		}

		if res != nil && res.finalSet != nil {
			sorted := kb.SortClosestPeers(res.finalSet.Peers(), kb.ConvertKey(key))
			if len(sorted) > KValue {
				sorted = sorted[:KValue]
			}

			for _, p := range sorted {
				out <- p
			}
		}
	}()

	return out, nil
}
<|endoftext|>


<commit_before>//   Copyright 2020 MSolution.IO
//
//   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 tagging

import (
	"context"
	"time"

	"github.com/trackit/jsonlog"

	"github.com/trackit/trackit/es"
)

const typeTaggingReport = "tagging-reports"
const indexPrefixTaggingReport = "tagging-reports"
const templateNameTaggingReport = "tagging-reports"

// put the ElasticSearch index for *-tagging-reports indices at startup.
func init() {
	ctx, ctxCancel := context.WithTimeout(context.Background(), 10*time.Second)
	res, err := es.Client.IndexPutTemplate(templateNameTaggingReport).BodyString(templateTaggingReport).Do(ctx)
	if err != nil {
		jsonlog.DefaultLogger.Error("Failed to put ES indext tagging-reports.", err)
		ctxCancel()
	} else {
		jsonlog.DefaultLogger.Info("Put ES index tagging-reports.", res)
		ctxCancel()
	}
}

const templateTaggingReport = `
{
    "template":"*-tagging-reports",
    "version":1,
    "mappings":{
        "tagging-reports":{
            "properties":{
                "account":{
                    "type":"keyword"
                },
                "region":{
                    "type":"keyword"
                },
                "reportDate":{
                    "type":"date"
                },
                "resourceId":{
                    "type":"keyword"
                },
                "resourceType":{
                    "type":"keyword"
                },
                "tags":{
                    "type":"nested",
                    "properties":{
                        "key":{
                            "type":"keyword"
                        },
                        "value":{
                            "type":"keyword"
                        }
                    }
                },
                "url":{
                    "type":"keyword"
                }
            },
            "_all": {
                "enabled": false
            },
            "date_detection": false,
            "numeric_detection": false
        }
    }
}
`

const typeTaggingCompliance = "tagging-compliance"
const indexPrefixTaggingCompliance = "tagging-compliance"
const templateNameTaggingCompliance = "tagging-compliance"

// put the ElasticSearch index for *-tagging-compliance indices at startup.
func init() {
	ctx, ctxCancel := context.WithTimeout(context.Background(), 10*time.Second)
	res, err := es.Client.IndexPutTemplate(templateNameTaggingCompliance).BodyString(templateTaggingCompliance).Do(ctx)
	if err != nil {
		jsonlog.DefaultLogger.Error("Failed to put ES index tagging-compliance.", err)
		ctxCancel()
	} else {
		jsonlog.DefaultLogger.Info("Put ES index tagging-compliance.", res)
		ctxCancel()
	}
}

const templateTaggingCompliance = `
{
    "template":"*-tagging-compliance",
    "version":1,
    "mappings":{
        "tagging-reports":{
            "properties":{
                "account":{
                    "type":"keyword"
                },
                "reportDate":{
                    "type":"date"
                },
                "total":{
                    "type":"long"
                },
                "totallyTagged":{
                    "type":"long"
                },
                "partiallyTagged":{
                    "type":"long"
                },
                "notTagged":{
                    "type":"long"
                }
            },
            "_all": {
                "enabled": false
            },
            "date_detection": false,
            "numeric_detection": false
        }
    }
}
`
<commit_msg>Fixed ES mapping for tagging compliance<commit_after>//   Copyright 2020 MSolution.IO
//
//   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 tagging

import (
	"context"
	"time"

	"github.com/trackit/jsonlog"

	"github.com/trackit/trackit/es"
)

const typeTaggingReport = "tagging-reports"
const indexPrefixTaggingReport = "tagging-reports"
const templateNameTaggingReport = "tagging-reports"

// put the ElasticSearch index for *-tagging-reports indices at startup.
func init() {
	ctx, ctxCancel := context.WithTimeout(context.Background(), 10*time.Second)
	res, err := es.Client.IndexPutTemplate(templateNameTaggingReport).BodyString(templateTaggingReport).Do(ctx)
	if err != nil {
		jsonlog.DefaultLogger.Error("Failed to put ES index tagging-reports.", err)
		ctxCancel()
	} else {
		jsonlog.DefaultLogger.Info("Put ES index tagging-reports.", res)
		ctxCancel()
	}
}

const templateTaggingReport = `
{
    "template":"*-tagging-reports",
    "version":1,
    "mappings":{
        "tagging-reports":{
            "properties":{
                "account":{
                    "type":"keyword"
                },
                "region":{
                    "type":"keyword"
                },
                "reportDate":{
                    "type":"date"
                },
                "resourceId":{
                    "type":"keyword"
                },
                "resourceType":{
                    "type":"keyword"
                },
                "tags":{
                    "type":"nested",
                    "properties":{
                        "key":{
                            "type":"keyword"
                        },
                        "value":{
                            "type":"keyword"
                        }
                    }
                },
                "url":{
                    "type":"keyword"
                }
            },
            "_all": {
                "enabled": false
            },
            "date_detection": false,
            "numeric_detection": false
        }
    }
}
`

const typeTaggingCompliance = "tagging-compliance"
const indexPrefixTaggingCompliance = "tagging-compliance"
const templateNameTaggingCompliance = "tagging-compliance"

// put the ElasticSearch index for *-tagging-compliance indices at startup.
func init() {
	ctx, ctxCancel := context.WithTimeout(context.Background(), 10*time.Second)
	res, err := es.Client.IndexPutTemplate(templateNameTaggingCompliance).BodyString(templateTaggingCompliance).Do(ctx)
	if err != nil {
		jsonlog.DefaultLogger.Error("Failed to put ES index tagging-compliance.", err)
		ctxCancel()
	} else {
		jsonlog.DefaultLogger.Info("Put ES index tagging-compliance.", res)
		ctxCancel()
	}
}

const templateTaggingCompliance = `
{
    "template":"*-tagging-compliance",
    "version":1,
    "mappings":{
        "tagging-compliance":{
            "properties":{
                "account":{
                    "type":"keyword"
                },
                "reportDate":{
                    "type":"date"
                },
                "total":{
                    "type":"long"
                },
                "totallyTagged":{
                    "type":"long"
                },
                "partiallyTagged":{
                    "type":"long"
                },
                "notTagged":{
                    "type":"long"
                }
            },
            "_all": {
                "enabled": false
            },
            "date_detection": false,
            "numeric_detection": false
        }
    }
}
`
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"os"
	"runtime"
	"sync"
	"time"

	"github.com/voxelbrain/goptions"
)

const (
	VERSION = "1.1.1"
)

var (
	DefaultFilesize  = 10 * GigaByte
	DefaultBlocksize = 4 * KiloByte
	options          = struct {
		Cores     int           `goptions:"-c, --cores, description='Number of cores to use'"`
		Threads   int           `goptions:"-t, --threads, description='Number of threads to use'"`
		Blocksize *Datasize     `goptions:"-b, --block-size, description='Number of bytes to write with each call'"`
		Filesize  *Datasize     `goptions:"-f, --file-size, description='Number of zeroes to write to each file'"`
		KeepFiles bool          `goptions:"-k, --keep-files, description='Dont delete files when done'"`
		Sync      bool          `goptions:"-s, --sync, description='Sync after every written block'"`
		Help      goptions.Help `goptions:"-h, --help, description='Show this help'"`
	}{
		Cores:     runtime.NumCPU(),
		Threads:   runtime.NumCPU(),
		Filesize:  &DefaultFilesize,
		Blocksize: &DefaultBlocksize,
	}
)

func init() {
	goptions.ParseAndFail(&options)
}

type Result struct {
	Index    int
	Duration time.Duration
}

func main() {
	runtime.GOMAXPROCS(options.Cores)
	log.Printf("Starting %d workers on %d cores writing %s bytes (%s per call)...", options.Threads, options.Cores, options.Filesize, options.Blocksize)

	results := make(chan Result, options.Threads)
	wg := &sync.WaitGroup{}
	wg.Add(options.Threads)
	for i := 0; i < options.Threads; i++ {
		go writeFile(i, results, wg)
	}
	wg.Wait()
	for i := 0; i < options.Threads; i++ {
		r := <-results
		log.Printf("Thread %d: %s, %s/s", r.Index, r.Duration, Datasize(int64(float64(*options.Filesize)*float64(time.Second)/float64(r.Duration))))
	}
	close(results)
}

func writeFile(idx int, c chan Result, wg *sync.WaitGroup) {
	result := Result{
		Index: idx,
	}
	defer func() { c <- result }()
	defer wg.Done()
	filename := fmt.Sprintf("%s/iowhip_%d_%d", os.TempDir(), idx, time.Now().UnixNano())
	log.Printf("Thread %d: Using %s", idx, filename)
	if !options.KeepFiles {
		defer os.Remove(filename)
	}

	f, err := os.Create(filename)
	if err != nil {
		log.Printf("Thread %d: Could not open file %s: %s", idx, filename, err)
		return
	}
	defer f.Close()

	amount := *options.Filesize
	data := make([]byte, int(*options.Blocksize))
	start := time.Now()
	for amount > 0 {
		n, err := f.Write(data)
		if err != nil {
			log.Printf("Thread %d: Write to %s failed: %s", idx, filename, err)
			return
		}
		amount -= Datasize(n)
		if options.Sync {
			f.Sync()
		}
	}
	f.Sync()
	result.Duration = time.Now().Sub(start)
}
<commit_msg>Add output directory option<commit_after>package main

import (
	"fmt"
	"log"
	"os"
	"path/filepath"
	"runtime"
	"sync"
	"time"

	"github.com/voxelbrain/goptions"
)

const (
	VERSION = "1.1.1"
)

var (
	DefaultFilesize  = 10 * GigaByte
	DefaultBlocksize = 4 * KiloByte
	options          = struct {
		Cores     int           `goptions:"-c, --cores, description='Number of cores to use'"`
		Threads   int           `goptions:"-t, --threads, description='Number of threads to use'"`
		Blocksize *Datasize     `goptions:"-b, --block-size, description='Number of bytes to write with each call'"`
		Filesize  *Datasize     `goptions:"-f, --file-size, description='Number of zeroes to write to each file'"`
		OutputDir string        `goptions:"-o, --output-dir, description='Output directory'"`
		Sync      bool          `goptions:"-s, --sync, description='Sync after every written block'"`
		KeepFiles bool          `goptions:"-k, --keep-files, description='Dont delete files when done'"`
		Help      goptions.Help `goptions:"-h, --help, description='Show this help'"`
	}{
		Cores:     runtime.NumCPU(),
		Threads:   runtime.NumCPU(),
		Filesize:  &DefaultFilesize,
		OutputDir: filepath.Clean(os.TempDir() + fmt.Sprintf("/iowhip_%d/", time.Now().UnixNano())),
		Blocksize: &DefaultBlocksize,
	}
)

func init() {
	goptions.ParseAndFail(&options)
}

type Result struct {
	Index    int
	Duration time.Duration
}

func main() {
	runtime.GOMAXPROCS(options.Cores)
	log.Printf("Starting %d workers on %d cores writing %s bytes (%s per call)...", options.Threads, options.Cores, options.Filesize, options.Blocksize)

	results := make(chan Result, options.Threads)
	wg := &sync.WaitGroup{}
	wg.Add(options.Threads)
	for i := 0; i < options.Threads; i++ {
		go writeFile(i, results, wg)
	}
	wg.Wait()
	for i := 0; i < options.Threads; i++ {
		r := <-results
		log.Printf("Thread %d: %s, %s/s", r.Index, r.Duration, Datasize(int64(float64(*options.Filesize)*float64(time.Second)/float64(r.Duration))))
	}
	close(results)
}

func writeFile(idx int, c chan Result, wg *sync.WaitGroup) {
	result := Result{
		Index: idx,
	}
	defer func() { c <- result }()
	defer wg.Done()
	filename := fmt.Sprintf("%s/%d", options.OutputDir, idx)
	log.Printf("Thread %d: Using %s", idx, filename)
	if !options.KeepFiles {
		defer os.Remove(filename)
	}

	f, err := os.Create(filename)
	if err != nil {
		log.Printf("Thread %d: Could not open file %s: %s", idx, filename, err)
		return
	}
	defer f.Close()

	amount := *options.Filesize
	data := make([]byte, int(*options.Blocksize))
	start := time.Now()
	for amount > 0 {
		n, err := f.Write(data)
		if err != nil {
			log.Printf("Thread %d: Write to %s failed: %s", idx, filename, err)
			return
		}
		amount -= Datasize(n)
		if options.Sync {
			f.Sync()
		}
	}
	f.Sync()
	result.Duration = time.Now().Sub(start)
}
<|endoftext|>


<commit_before>package handler_test

import (
	"encoding/json"
	"errors"
	"net/http"
	"time"

	"gopkg.in/mgo.v2/bson"

	"github.com/Lunchr/luncher-api/db"
	"github.com/Lunchr/luncher-api/db/model"
	. "github.com/Lunchr/luncher-api/handler"
	"github.com/Lunchr/luncher-api/handler/mocks"
	"github.com/Lunchr/luncher-api/router"
	"github.com/Lunchr/luncher-api/session"
	"github.com/stretchr/testify/mock"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("RestaurantsHandlers", func() {
	Describe("GET /restaurants", func() {
		var (
			mockRestaurantsCollection db.Restaurants
			handler                   router.Handler
		)

		BeforeEach(func() {
			mockRestaurantsCollection = &mockRestaurants{}
		})

		JustBeforeEach(func() {
			handler = Restaurants(mockRestaurantsCollection)
		})

		It("should succeed", func(done Done) {
			defer close(done)
			err := handler(responseRecorder, request)
			Expect(err).To(BeNil())
		})

		It("should return json", func(done Done) {
			defer close(done)
			handler(responseRecorder, request)
			contentTypes := responseRecorder.HeaderMap["Content-Type"]
			Expect(contentTypes).To(HaveLen(1))
			Expect(contentTypes[0]).To(Equal("application/json"))
		})

		Context("with simple mocked result from DB", func() {
			var (
				mockResult []*model.Restaurant
			)
			BeforeEach(func() {
				mockResult = []*model.Restaurant{&model.Restaurant{Name: "somerestaurant"}}
				mockRestaurantsCollection = &mockRestaurants{
					func() (restaurants []*model.Restaurant, err error) {
						restaurants = mockResult
						return
					},
					nil,
				}
			})

			It("should write the returned data to responsewriter", func(done Done) {
				defer close(done)
				handler(responseRecorder, request)
				var result []*model.Restaurant
				json.Unmarshal(responseRecorder.Body.Bytes(), &result)
				Expect(result).To(HaveLen(1))
				Expect(result[0].Name).To(Equal(mockResult[0].Name))
			})
		})

		Context("with an error returned from the DB", func() {
			var dbErr = errors.New("DB stuff failed")

			BeforeEach(func() {
				mockRestaurantsCollection = &mockRestaurants{
					func() (restaurants []*model.Restaurant, err error) {
						err = dbErr
						return
					},
					nil,
				}
			})

			It("should return error 500", func(done Done) {
				defer close(done)
				err := handler(responseRecorder, request)
				Expect(err.Code).To(Equal(http.StatusInternalServerError))
			})
		})
	})

	Describe("POST /restaurants", func() {
		var (
			sessionManager        session.Manager
			restaurantsCollection db.Restaurants
			usersCollection       db.Users
			handler               router.Handler
		)

		JustBeforeEach(func() {
			handler = PostRestaurants(restaurantsCollection, sessionManager, usersCollection)
		})

		ExpectUserToBeLoggedIn(func() *router.HandlerError {
			return handler(responseRecorder, request)
		}, func(mgr session.Manager, users db.Users) {
			sessionManager = mgr
			usersCollection = users
		})

		Context("with session set and a matching user in DB", func() {
			var (
				mockSessionManager        *mocks.Manager
				mockRestaurantsCollection *mocks.Restaurants
				mockUsersCollection       *mocks.Users
				user                      *model.User
				id                        bson.ObjectId
			)

			BeforeEach(func() {
				mockSessionManager = new(mocks.Manager)
				sessionManager = mockSessionManager
				mockRestaurantsCollection = new(mocks.Restaurants)
				restaurantsCollection = mockRestaurantsCollection
				mockUsersCollection = new(mocks.Users)
				usersCollection = mockUsersCollection
				user = &model.User{}
				id = bson.NewObjectId()

				mockSessionManager.On("Get", mock.Anything).Return("session", nil)
				mockUsersCollection.On("GetSessionID", "session").Return(user, nil)

				requestMethod = "POST"
				requestData = map[string]interface{}{
					"facebook_page_id": "1337",
					"name":             "A Restaurant Name",
					"address":          "Street 10, City, Country",
					"phone":            "+372 1234567890",
					"website":          "https://some.address.com/some/path",
					"email":            "an.email@address.com",
					"location": map[string]interface{}{
						"type":        "Point",
						"coordinates": []float64{12.34, 56.78},
					},
				}
			})

			AfterEach(func() {
				mockSessionManager.AssertExpectations(GinkgoT())
				mockRestaurantsCollection.AssertExpectations(GinkgoT())
				mockUsersCollection.AssertExpectations(GinkgoT())
			})

			Context("with DB inserts succeeding", func() {
				BeforeEach(func() {
					mockRestaurantsCollection.On("Insert", mock.AnythingOfType("[]*model.Restaurant")).Return([]*model.Restaurant{
						&model.Restaurant{
							ID: id,
						},
					}, nil)
					mockUsersCollection.On("Update", mock.AnythingOfType("string"), mock.AnythingOfType("*model.User")).Return(nil)
				})

				It("should succeed", func(done Done) {
					defer close(done)
					err := handler(responseRecorder, request)
					Expect(err).To(BeNil())
				})

				It("should return json", func(done Done) {
					defer close(done)
					handler(responseRecorder, request)
					contentTypes := responseRecorder.HeaderMap["Content-Type"]
					Expect(contentTypes).To(HaveLen(1))
					Expect(contentTypes[0]).To(Equal("application/json"))
				})

				It("should include the restaurant with the new ID", func(done Done) {
					defer close(done)
					handler(responseRecorder, request)
					var restaurant *model.Restaurant
					json.Unmarshal(responseRecorder.Body.Bytes(), &restaurant)
					Expect(restaurant.ID).To(Equal(id))
				})
			})

			Context("the inserted restaurant", func() {
				var insertedRestaurant *model.Restaurant
				BeforeEach(func() {
					mockRestaurantsCollection.On("Insert", mock.AnythingOfType("[]*model.Restaurant")).Return([]*model.Restaurant{
						&model.Restaurant{
							ID: id,
						},
					}, nil).Run(func(args mock.Arguments) {
						insertedRestaurant = args.Get(0).([]*model.Restaurant)[0]
					})
					mockUsersCollection.On("Update", mock.AnythingOfType("string"), mock.AnythingOfType("*model.User")).Return(nil)
				})

				It("should correctly parse and insert the restaurant", func() {
					handler(responseRecorder, request)

					Expect(insertedRestaurant.FacebookPageID).To(Equal("1337"))
					Expect(insertedRestaurant.Name).To(Equal("A Restaurant Name"))
					Expect(insertedRestaurant.Address).To(Equal("Street 10, City, Country"))
					Expect(insertedRestaurant.Region).To(Equal("Tallinn"))
					Expect(insertedRestaurant.Phone).To(Equal("+372 1234567890"))
					Expect(insertedRestaurant.Website).To(Equal("https://some.address.com/some/path"))
					Expect(insertedRestaurant.Email).To(Equal("an.email@address.com"))
					Expect(insertedRestaurant.Location.Type).To(Equal("Point"))
					Expect(insertedRestaurant.Location.Coordinates[0]).To(Equal(12.34))
					Expect(insertedRestaurant.Location.Coordinates[1]).To(Equal(56.78))
				})
			})

			Context("the updated user", func() {
				var updatedUser *model.User
				BeforeEach(func() {
					mockRestaurantsCollection.On("Insert", mock.AnythingOfType("[]*model.Restaurant")).Return([]*model.Restaurant{
						&model.Restaurant{
							ID: id,
						},
					}, nil)
					mockUsersCollection.On("Update", mock.AnythingOfType("string"), mock.AnythingOfType("*model.User")).Return(nil).Run(func(args mock.Arguments) {
						updatedUser = args.Get(1).(*model.User)
					})
				})

				It("should update the user to include a reference to the restaurant", func() {
					handler(responseRecorder, request)
					Expect(updatedUser.RestaurantIDs[0]).To(Equal(id))
				})
			})
		})
	})

	Describe("GET /restaurant", func() {
		var (
			sessionManager        session.Manager
			restaurantsCollection db.Restaurants
			usersCollection       db.Users
			handler               router.Handler
		)

		JustBeforeEach(func() {
			handler = Restaurant(restaurantsCollection, sessionManager, usersCollection)
		})

		ExpectUserToBeLoggedIn(func() *router.HandlerError {
			return handler(responseRecorder, request)
		}, func(mgr session.Manager, users db.Users) {
			sessionManager = mgr
			usersCollection = users
		})

		Context("with user logged in", func() {
			var (
				mockSessionManager        *mocks.Manager
				mockRestaurantsCollection *mocks.Restaurants
				mockUsersCollection       *mocks.Users
				restaurantID              bson.ObjectId
			)

			BeforeEach(func() {
				mockSessionManager = new(mocks.Manager)
				sessionManager = mockSessionManager
				mockRestaurantsCollection = new(mocks.Restaurants)
				restaurantsCollection = mockRestaurantsCollection
				mockUsersCollection = new(mocks.Users)
				usersCollection = mockUsersCollection

				restaurantID = bson.NewObjectId()
				restaurant := &model.Restaurant{
					ID:   restaurantID,
					Name: "restname",
				}
				user := &model.User{
					RestaurantIDs: []bson.ObjectId{restaurant.ID},
				}

				mockSessionManager.On("Get", mock.Anything).Return("session", nil)
				mockUsersCollection.On("GetSessionID", "session").Return(user, nil)
				mockRestaurantsCollection.On("GetID", restaurantID).Return(restaurant, nil)
			})

			It("should succeed", func() {
				err := handler(responseRecorder, request)
				Expect(err).To(BeNil())
			})

			It("should return json", func() {
				handler(responseRecorder, request)
				contentTypes := responseRecorder.HeaderMap["Content-Type"]
				Expect(contentTypes).To(HaveLen(1))
				Expect(contentTypes[0]).To(Equal("application/json"))
			})

			It("should include the restaurant data in the response", func() {
				handler(responseRecorder, request)
				var restaurant *model.Restaurant
				json.Unmarshal(responseRecorder.Body.Bytes(), &restaurant)
				Expect(restaurant.ID).To(Equal(restaurantID))
				Expect(restaurant.Name).To(Equal("restname"))
			})
		})
	})

	Describe("GET /restaurant/offers", func() {
		var (
			sessionManager            session.Manager
			mockRestaurantsCollection db.Restaurants
			mockUsersCollection       db.Users
			handler                   router.Handler
			mockOffersCollection      db.Offers
			imageStorage              *mocks.Images
		)

		BeforeEach(func() {
			mockRestaurantsCollection = &mockRestaurants{}
			imageStorage = new(mocks.Images)
			imageStorage.On("PathsFor", "image checksum").Return(&model.OfferImagePaths{
				Large:     "images/a large image path",
				Thumbnail: "images/thumbnail",
			}, nil)
			imageStorage.On("PathsFor", "").Return(nil, nil)
		})

		JustBeforeEach(func() {
			handler = RestaurantOffers(mockRestaurantsCollection, sessionManager, mockUsersCollection, mockOffersCollection, imageStorage)
		})

		ExpectUserToBeLoggedIn(func() *router.HandlerError {
			return handler(responseRecorder, request)
		}, func(mgr session.Manager, users db.Users) {
			sessionManager = mgr
			mockUsersCollection = users
		})

		Context("with user logged in", func() {
			BeforeEach(func() {
				sessionManager = &mockSessionManager{isSet: true, id: "correctSession"}
				mockUsersCollection = mockUsers{}
				mockOffersCollection = mockOffers{}
			})

			It("should succeed", func(done Done) {
				defer close(done)
				err := handler(responseRecorder, request)
				Expect(err).To(BeNil())
			})

			It("should return json", func(done Done) {
				defer close(done)
				handler(responseRecorder, request)
				contentTypes := responseRecorder.HeaderMap["Content-Type"]
				Expect(contentTypes).To(HaveLen(1))
				Expect(contentTypes[0]).To(Equal("application/json"))
			})

			It("should include the offers in the response", func(done Done) {
				defer close(done)
				handler(responseRecorder, request)
				var result []*model.OfferJSON
				json.Unmarshal(responseRecorder.Body.Bytes(), &result)
				Expect(result).To(HaveLen(2))
				Expect(result[0].Title).To(Equal("a"))
				Expect(result[1].Title).To(Equal("b"))
				Expect(result[0].Image.Large).To(Equal("images/a large image path"))
				Expect(result[1].Image).To(BeNil())
			})
		})
	})
})

type mockRestaurants struct {
	getFunc func() ([]*model.Restaurant, error)
	db.Restaurants
}

func (mock mockRestaurants) Get() (restaurants []*model.Restaurant, err error) {
	if mock.getFunc != nil {
		restaurants, err = mock.getFunc()
	}
	return
}

func (c mockOffers) GetForRestaurant(restaurantID bson.ObjectId, startTime time.Time) ([]*model.Offer, error) {
	Expect(restaurantID).To(Equal(bson.ObjectId("12letrrestid")))
	Expect(startTime.Sub(time.Now())).To(BeNumerically("~", 0, time.Second))
	return []*model.Offer{
		&model.Offer{
			CommonOfferFields: model.CommonOfferFields{
				Title: "a",
			},
			ImageChecksum: "image checksum",
		},
		&model.Offer{
			CommonOfferFields: model.CommonOfferFields{
				Title: "b",
			},
		},
	}, nil
}
<commit_msg>Remove unnecessary asynchronity from tests<commit_after>package handler_test

import (
	"encoding/json"
	"errors"
	"net/http"
	"time"

	"gopkg.in/mgo.v2/bson"

	"github.com/Lunchr/luncher-api/db"
	"github.com/Lunchr/luncher-api/db/model"
	. "github.com/Lunchr/luncher-api/handler"
	"github.com/Lunchr/luncher-api/handler/mocks"
	"github.com/Lunchr/luncher-api/router"
	"github.com/Lunchr/luncher-api/session"
	"github.com/stretchr/testify/mock"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("RestaurantsHandlers", func() {
	Describe("GET /restaurants", func() {
		var (
			mockRestaurantsCollection db.Restaurants
			handler                   router.Handler
		)

		BeforeEach(func() {
			mockRestaurantsCollection = &mockRestaurants{}
		})

		JustBeforeEach(func() {
			handler = Restaurants(mockRestaurantsCollection)
		})

		It("should succeed", func() {
			err := handler(responseRecorder, request)
			Expect(err).To(BeNil())
		})

		It("should return json", func() {
			handler(responseRecorder, request)
			contentTypes := responseRecorder.HeaderMap["Content-Type"]
			Expect(contentTypes).To(HaveLen(1))
			Expect(contentTypes[0]).To(Equal("application/json"))
		})

		Context("with simple mocked result from DB", func() {
			var (
				mockResult []*model.Restaurant
			)
			BeforeEach(func() {
				mockResult = []*model.Restaurant{&model.Restaurant{Name: "somerestaurant"}}
				mockRestaurantsCollection = &mockRestaurants{
					func() (restaurants []*model.Restaurant, err error) {
						restaurants = mockResult
						return
					},
					nil,
				}
			})

			It("should write the returned data to responsewriter", func() {
				handler(responseRecorder, request)
				var result []*model.Restaurant
				json.Unmarshal(responseRecorder.Body.Bytes(), &result)
				Expect(result).To(HaveLen(1))
				Expect(result[0].Name).To(Equal(mockResult[0].Name))
			})
		})

		Context("with an error returned from the DB", func() {
			var dbErr = errors.New("DB stuff failed")

			BeforeEach(func() {
				mockRestaurantsCollection = &mockRestaurants{
					func() (restaurants []*model.Restaurant, err error) {
						err = dbErr
						return
					},
					nil,
				}
			})

			It("should return error 500", func() {
				err := handler(responseRecorder, request)
				Expect(err.Code).To(Equal(http.StatusInternalServerError))
			})
		})
	})

	Describe("POST /restaurants", func() {
		var (
			sessionManager        session.Manager
			restaurantsCollection db.Restaurants
			usersCollection       db.Users
			handler               router.Handler
		)

		JustBeforeEach(func() {
			handler = PostRestaurants(restaurantsCollection, sessionManager, usersCollection)
		})

		ExpectUserToBeLoggedIn(func() *router.HandlerError {
			return handler(responseRecorder, request)
		}, func(mgr session.Manager, users db.Users) {
			sessionManager = mgr
			usersCollection = users
		})

		Context("with session set and a matching user in DB", func() {
			var (
				mockSessionManager        *mocks.Manager
				mockRestaurantsCollection *mocks.Restaurants
				mockUsersCollection       *mocks.Users
				user                      *model.User
				id                        bson.ObjectId
			)

			BeforeEach(func() {
				mockSessionManager = new(mocks.Manager)
				sessionManager = mockSessionManager
				mockRestaurantsCollection = new(mocks.Restaurants)
				restaurantsCollection = mockRestaurantsCollection
				mockUsersCollection = new(mocks.Users)
				usersCollection = mockUsersCollection
				user = &model.User{}
				id = bson.NewObjectId()

				mockSessionManager.On("Get", mock.Anything).Return("session", nil)
				mockUsersCollection.On("GetSessionID", "session").Return(user, nil)

				requestMethod = "POST"
				requestData = map[string]interface{}{
					"facebook_page_id": "1337",
					"name":             "A Restaurant Name",
					"address":          "Street 10, City, Country",
					"phone":            "+372 1234567890",
					"website":          "https://some.address.com/some/path",
					"email":            "an.email@address.com",
					"location": map[string]interface{}{
						"type":        "Point",
						"coordinates": []float64{12.34, 56.78},
					},
				}
			})

			AfterEach(func() {
				mockSessionManager.AssertExpectations(GinkgoT())
				mockRestaurantsCollection.AssertExpectations(GinkgoT())
				mockUsersCollection.AssertExpectations(GinkgoT())
			})

			Context("with DB inserts succeeding", func() {
				BeforeEach(func() {
					mockRestaurantsCollection.On("Insert", mock.AnythingOfType("[]*model.Restaurant")).Return([]*model.Restaurant{
						&model.Restaurant{
							ID: id,
						},
					}, nil)
					mockUsersCollection.On("Update", mock.AnythingOfType("string"), mock.AnythingOfType("*model.User")).Return(nil)
				})

				It("should succeed", func() {
					err := handler(responseRecorder, request)
					Expect(err).To(BeNil())
				})

				It("should return json", func() {
					handler(responseRecorder, request)
					contentTypes := responseRecorder.HeaderMap["Content-Type"]
					Expect(contentTypes).To(HaveLen(1))
					Expect(contentTypes[0]).To(Equal("application/json"))
				})

				It("should include the restaurant with the new ID", func() {
					handler(responseRecorder, request)
					var restaurant *model.Restaurant
					json.Unmarshal(responseRecorder.Body.Bytes(), &restaurant)
					Expect(restaurant.ID).To(Equal(id))
				})
			})

			Context("the inserted restaurant", func() {
				var insertedRestaurant *model.Restaurant
				BeforeEach(func() {
					mockRestaurantsCollection.On("Insert", mock.AnythingOfType("[]*model.Restaurant")).Return([]*model.Restaurant{
						&model.Restaurant{
							ID: id,
						},
					}, nil).Run(func(args mock.Arguments) {
						insertedRestaurant = args.Get(0).([]*model.Restaurant)[0]
					})
					mockUsersCollection.On("Update", mock.AnythingOfType("string"), mock.AnythingOfType("*model.User")).Return(nil)
				})

				It("should correctly parse and insert the restaurant", func() {
					handler(responseRecorder, request)

					Expect(insertedRestaurant.FacebookPageID).To(Equal("1337"))
					Expect(insertedRestaurant.Name).To(Equal("A Restaurant Name"))
					Expect(insertedRestaurant.Address).To(Equal("Street 10, City, Country"))
					Expect(insertedRestaurant.Region).To(Equal("Tallinn"))
					Expect(insertedRestaurant.Phone).To(Equal("+372 1234567890"))
					Expect(insertedRestaurant.Website).To(Equal("https://some.address.com/some/path"))
					Expect(insertedRestaurant.Email).To(Equal("an.email@address.com"))
					Expect(insertedRestaurant.Location.Type).To(Equal("Point"))
					Expect(insertedRestaurant.Location.Coordinates[0]).To(Equal(12.34))
					Expect(insertedRestaurant.Location.Coordinates[1]).To(Equal(56.78))
				})
			})

			Context("the updated user", func() {
				var updatedUser *model.User
				BeforeEach(func() {
					mockRestaurantsCollection.On("Insert", mock.AnythingOfType("[]*model.Restaurant")).Return([]*model.Restaurant{
						&model.Restaurant{
							ID: id,
						},
					}, nil)
					mockUsersCollection.On("Update", mock.AnythingOfType("string"), mock.AnythingOfType("*model.User")).Return(nil).Run(func(args mock.Arguments) {
						updatedUser = args.Get(1).(*model.User)
					})
				})

				It("should update the user to include a reference to the restaurant", func() {
					handler(responseRecorder, request)
					Expect(updatedUser.RestaurantIDs[0]).To(Equal(id))
				})
			})
		})
	})

	Describe("GET /restaurant", func() {
		var (
			sessionManager        session.Manager
			restaurantsCollection db.Restaurants
			usersCollection       db.Users
			handler               router.Handler
		)

		JustBeforeEach(func() {
			handler = Restaurant(restaurantsCollection, sessionManager, usersCollection)
		})

		ExpectUserToBeLoggedIn(func() *router.HandlerError {
			return handler(responseRecorder, request)
		}, func(mgr session.Manager, users db.Users) {
			sessionManager = mgr
			usersCollection = users
		})

		Context("with user logged in", func() {
			var (
				mockSessionManager        *mocks.Manager
				mockRestaurantsCollection *mocks.Restaurants
				mockUsersCollection       *mocks.Users
				restaurantID              bson.ObjectId
			)

			BeforeEach(func() {
				mockSessionManager = new(mocks.Manager)
				sessionManager = mockSessionManager
				mockRestaurantsCollection = new(mocks.Restaurants)
				restaurantsCollection = mockRestaurantsCollection
				mockUsersCollection = new(mocks.Users)
				usersCollection = mockUsersCollection

				restaurantID = bson.NewObjectId()
				restaurant := &model.Restaurant{
					ID:   restaurantID,
					Name: "restname",
				}
				user := &model.User{
					RestaurantIDs: []bson.ObjectId{restaurant.ID},
				}

				mockSessionManager.On("Get", mock.Anything).Return("session", nil)
				mockUsersCollection.On("GetSessionID", "session").Return(user, nil)
				mockRestaurantsCollection.On("GetID", restaurantID).Return(restaurant, nil)
			})

			It("should succeed", func() {
				err := handler(responseRecorder, request)
				Expect(err).To(BeNil())
			})

			It("should return json", func() {
				handler(responseRecorder, request)
				contentTypes := responseRecorder.HeaderMap["Content-Type"]
				Expect(contentTypes).To(HaveLen(1))
				Expect(contentTypes[0]).To(Equal("application/json"))
			})

			It("should include the restaurant data in the response", func() {
				handler(responseRecorder, request)
				var restaurant *model.Restaurant
				json.Unmarshal(responseRecorder.Body.Bytes(), &restaurant)
				Expect(restaurant.ID).To(Equal(restaurantID))
				Expect(restaurant.Name).To(Equal("restname"))
			})
		})
	})

	Describe("GET /restaurant/offers", func() {
		var (
			sessionManager            session.Manager
			mockRestaurantsCollection db.Restaurants
			mockUsersCollection       db.Users
			handler                   router.Handler
			mockOffersCollection      db.Offers
			imageStorage              *mocks.Images
		)

		BeforeEach(func() {
			mockRestaurantsCollection = &mockRestaurants{}
			imageStorage = new(mocks.Images)
			imageStorage.On("PathsFor", "image checksum").Return(&model.OfferImagePaths{
				Large:     "images/a large image path",
				Thumbnail: "images/thumbnail",
			}, nil)
			imageStorage.On("PathsFor", "").Return(nil, nil)
		})

		JustBeforeEach(func() {
			handler = RestaurantOffers(mockRestaurantsCollection, sessionManager, mockUsersCollection, mockOffersCollection, imageStorage)
		})

		ExpectUserToBeLoggedIn(func() *router.HandlerError {
			return handler(responseRecorder, request)
		}, func(mgr session.Manager, users db.Users) {
			sessionManager = mgr
			mockUsersCollection = users
		})

		Context("with user logged in", func() {
			BeforeEach(func() {
				sessionManager = &mockSessionManager{isSet: true, id: "correctSession"}
				mockUsersCollection = mockUsers{}
				mockOffersCollection = mockOffers{}
			})

			It("should succeed", func() {
				err := handler(responseRecorder, request)
				Expect(err).To(BeNil())
			})

			It("should return json", func() {
				handler(responseRecorder, request)
				contentTypes := responseRecorder.HeaderMap["Content-Type"]
				Expect(contentTypes).To(HaveLen(1))
				Expect(contentTypes[0]).To(Equal("application/json"))
			})

			It("should include the offers in the response", func() {
				handler(responseRecorder, request)
				var result []*model.OfferJSON
				json.Unmarshal(responseRecorder.Body.Bytes(), &result)
				Expect(result).To(HaveLen(2))
				Expect(result[0].Title).To(Equal("a"))
				Expect(result[1].Title).To(Equal("b"))
				Expect(result[0].Image.Large).To(Equal("images/a large image path"))
				Expect(result[1].Image).To(BeNil())
			})
		})
	})
})

type mockRestaurants struct {
	getFunc func() ([]*model.Restaurant, error)
	db.Restaurants
}

func (mock mockRestaurants) Get() (restaurants []*model.Restaurant, err error) {
	if mock.getFunc != nil {
		restaurants, err = mock.getFunc()
	}
	return
}

func (c mockOffers) GetForRestaurant(restaurantID bson.ObjectId, startTime time.Time) ([]*model.Offer, error) {
	Expect(restaurantID).To(Equal(bson.ObjectId("12letrrestid")))
	Expect(startTime.Sub(time.Now())).To(BeNumerically("~", 0, time.Second))
	return []*model.Offer{
		&model.Offer{
			CommonOfferFields: model.CommonOfferFields{
				Title: "a",
			},
			ImageChecksum: "image checksum",
		},
		&model.Offer{
			CommonOfferFields: model.CommonOfferFields{
				Title: "b",
			},
		},
	}, nil
}
<|endoftext|>


<commit_before>package cloudcontroller

import (
	"encoding/json"
	"fmt"
	"strings"

	"github.com/pivotalservices/cf-mgmt/http"
	"github.com/xchapter7x/lo"
)

func NewManager(host, token string) Manager {
	return &DefaultManager{
		Host:  host,
		Token: token,
		HTTP:  http.NewManager(),
	}
}

func (m *DefaultManager) CreateSpace(spaceName, orgGUID string) error {
	url := fmt.Sprintf("%s/v2/spaces", m.Host)
	sendString := fmt.Sprintf(`{"name":"%s", "organization_guid":"%s"}`, spaceName, orgGUID)
	_, err := m.HTTP.Post(url, m.Token, sendString)
	return err
}

func (m *DefaultManager) ListSpaces(orgGUID string) ([]*Space, error) {
	spaceResources := &SpaceResources{}
	url := fmt.Sprintf("%s/v2/organizations/%s/spaces", m.Host, orgGUID)
	var err = m.HTTP.Get(url, m.Token, spaceResources)
	if err != nil {
		return nil, err
	}
	if spaceResources.NextURL == "" {
		return spaceResources.Spaces, nil
	}
	nextURL := spaceResources.NextURL
	spaceResourcesTemp := &SpaceResources{}
	for nextURL != "" {
		url = fmt.Sprintf("%s%s", m.Host, nextURL)
		err = m.HTTP.Get(url, m.Token, spaceResourcesTemp)
		if err != nil {
			return nil, err
		}
		spaceResources.Spaces = append(spaceResources.Spaces, spaceResourcesTemp.Spaces...)
		nextURL = spaceResourcesTemp.NextURL
	}
	lo.G.Info("Total spaces returned :", len(spaceResources.Spaces))
	return spaceResources.Spaces, nil
}

func (m *DefaultManager) AddUserToSpaceRole(userName, role, spaceGUID string) error {
	url := fmt.Sprintf("%s/v2/spaces/%s/%s", m.Host, spaceGUID, role)
	sendString := fmt.Sprintf(`{"username": "%s"}`, userName)
	err := m.HTTP.Put(url, m.Token, sendString)
	return err
}

func (m *DefaultManager) AddUserToOrg(userName, orgGUID string) error {
	url := fmt.Sprintf("%s/v2/organizations/%s/users", m.Host, orgGUID)
	sendString := fmt.Sprintf(`{"username": "%s"}`, userName)
	err := m.HTTP.Put(url, m.Token, sendString)
	return err
}

func (m *DefaultManager) UpdateSpaceSSH(sshAllowed bool, spaceGUID string) error {
	url := fmt.Sprintf("%s/v2/spaces/%s", m.Host, spaceGUID)
	sendString := fmt.Sprintf(`{"allow_ssh":%t}`, sshAllowed)
	return m.HTTP.Put(url, m.Token, sendString)
}

func (m *DefaultManager) ListSecurityGroups() (map[string]string, error) {
	var err error
	securityGroups := make(map[string]string)
	url := fmt.Sprintf("%s/v2/security_groups", m.Host)
	sgResources := &SecurityGroupResources{}
	if err = m.HTTP.Get(url, m.Token, sgResources); err == nil {
		for _, sg := range sgResources.SecurityGroups {
			securityGroups[sg.Entity.Name] = sg.MetaData.GUID
		}
		return securityGroups, nil
	}
	return nil, err
}

func (m *DefaultManager) UpdateSecurityGroup(sgGUID, sgName, contents string) error {
	url := fmt.Sprintf("%s/v2/security_groups/%s", m.Host, sgGUID)
	sendString := fmt.Sprintf(`{"name":"%s","rules":%s}`, sgName, contents)
	return m.HTTP.Put(url, m.Token, sendString)
}

func (m *DefaultManager) CreateSecurityGroup(sgName, contents string) (string, error) {
	url := fmt.Sprintf("%s/v2/security_groups", m.Host)
	sendString := fmt.Sprintf(`{"name":"%s","rules":%s}`, sgName, contents)
	if body, err := m.HTTP.Post(url, m.Token, sendString); err != nil {
		return "", err
	} else {
		sgResource := &SecurityGroup{}
		if err := json.Unmarshal([]byte(body), &sgResource); err == nil {
			return sgResource.MetaData.GUID, nil
		} else {
			return "", err
		}
	}
}

func (m *DefaultManager) AssignSecurityGroupToSpace(spaceGUID, sgGUID string) error {
	url := fmt.Sprintf("%s/v2/security_groups/%s/spaces/%s", m.Host, sgGUID, spaceGUID)
	err := m.HTTP.Put(url, m.Token, "")
	return err
}

func (m *DefaultManager) AssignQuotaToSpace(spaceGUID, quotaGUID string) error {
	url := fmt.Sprintf("%s/v2/space_quota_definitions/%s/spaces/%s", m.Host, quotaGUID, spaceGUID)
	err := m.HTTP.Put(url, m.Token, "")
	return err
}

func (m *DefaultManager) CreateSpaceQuota(orgGUID, quotaName string,
	memoryLimit, instanceMemoryLimit, totalRoutes, totalServices int,
	paidServicePlansAllowed bool) (string, error) {
	url := fmt.Sprintf("%s/v2/space_quota_definitions", m.Host)
	sendString := fmt.Sprintf(`{"name":"%s","memory_limit":%d,"instance_memory_limit":%d,"total_routes":%d,"total_services":%d,"non_basic_services_allowed":%t,"organization_guid":"%s"}`, quotaName, memoryLimit, instanceMemoryLimit, totalRoutes, totalServices, paidServicePlansAllowed, orgGUID)
	if body, err := m.HTTP.Post(url, m.Token, sendString); err == nil {
		quotaResource := &Quota{}
		if err = json.Unmarshal([]byte(body), &quotaResource); err == nil {
			return quotaResource.MetaData.GUID, nil
		} else {
			return "", err
		}
	} else {
		return "", err
	}
}

func (m *DefaultManager) UpdateSpaceQuota(orgGUID, quotaGUID, quotaName string,
	memoryLimit, instanceMemoryLimit, totalRoutes, totalServices int,
	paidServicePlansAllowed bool) error {
	url := fmt.Sprintf("%s/v2/space_quota_definitions/%s", m.Host, quotaGUID)
	sendString := fmt.Sprintf(`{"guid":"%s","name":"%s","memory_limit":%d,"instance_memory_limit":%d,"total_routes":%d,"total_services":%d,"non_basic_services_allowed":%t,"organization_guid":"%s"}`, quotaGUID, quotaName, memoryLimit, instanceMemoryLimit, totalRoutes, totalServices, paidServicePlansAllowed, orgGUID)
	return m.HTTP.Put(url, m.Token, sendString)
}

func (m *DefaultManager) ListAllSpaceQuotasForOrg(orgGUID string) (map[string]string, error) {
	quotas := make(map[string]string)
	url := fmt.Sprintf("%s/v2/organizations/%s/space_quota_definitions", m.Host, orgGUID)
	quotaResources := &Quotas{}
	if err := m.HTTP.Get(url, m.Token, quotaResources); err == nil {
		for _, quota := range quotaResources.Quotas {
			quotas[quota.Entity.Name] = quota.MetaData.GUID
		}
		return quotas, nil
	} else {
		return nil, err
	}
}

func (m *DefaultManager) CreateOrg(orgName string) error {
	url := fmt.Sprintf("%s/v2/organizations", m.Host)
	sendString := fmt.Sprintf(`{"name":"%s"}`, orgName)
	_, err := m.HTTP.Post(url, m.Token, sendString)
	return err
}

func (m *DefaultManager) DeleteOrg(orgName string) error {
	orgs, err := m.ListOrgs()
	if err != nil {
		return err
	}
	for _, org := range orgs {
		if org.Entity.Name == orgName {
			url := fmt.Sprintf("%s/v2/organizations/%s?recursive=true", m.Host, org.MetaData.GUID)
			err = m.HTTP.Delete(url, m.Token)
		}
	}

	return err
}

//ListOrgs : Returns all orgs in the given foundation
func (m *DefaultManager) ListOrgs() ([]*Org, error) {
	url := fmt.Sprintf("%s/v2/organizations?results-per-page=100", m.Host)
	orgs := &Orgs{}
	var err = m.HTTP.Get(url, m.Token, orgs)
	if err != nil {
		return nil, err
	}
	if orgs.NextURL == "" {
		return orgs.Orgs, nil
	}
	nextURL := orgs.NextURL
	orgsTemp := &Orgs{}
	for nextURL != "" {
		url = fmt.Sprintf("%s%s", m.Host, nextURL)
		lo.G.Info("getOrgs() URL :", url)
		err = m.HTTP.Get(url, m.Token, orgsTemp)
		if err != nil {
			return nil, err
		}
		orgs.Orgs = append(orgs.Orgs, orgsTemp.Orgs...)
		nextURL = orgsTemp.NextURL
	}
	lo.G.Info("Total orgs returned :", len(orgs.Orgs))
	return orgs.Orgs, nil
}

func (m *DefaultManager) AddUserToOrgRole(userName, role, orgGUID string) error {
	url := fmt.Sprintf("%s/v2/organizations/%s/%s", m.Host, orgGUID, role)
	sendString := fmt.Sprintf(`{"username": "%s"}`, userName)
	return m.HTTP.Put(url, m.Token, sendString)
}

func (m *DefaultManager) ListAllOrgQuotas() (map[string]string, error) {
	quotas := make(map[string]string)
	url := fmt.Sprintf("%s/v2/quota_definitions", m.Host)
	quotaResources := &Quotas{}
	if err := m.HTTP.Get(url, m.Token, quotaResources); err == nil {
		for _, quota := range quotaResources.Quotas {
			quotas[quota.Entity.Name] = quota.MetaData.GUID
		}
		return quotas, nil
	} else {
		return nil, err
	}
}

func (m *DefaultManager) CreateQuota(quotaName string,
	memoryLimit, instanceMemoryLimit, totalRoutes, totalServices int,
	paidServicePlansAllowed bool) (string, error) {
	url := fmt.Sprintf("%s/v2/quota_definitions", m.Host)
	sendString := fmt.Sprintf(`{"name":"%s","memory_limit":%d,"instance_memory_limit":%d,"total_routes":%d,"total_services":%d,"non_basic_services_allowed":%t}`, quotaName, memoryLimit, instanceMemoryLimit, totalRoutes, totalServices, paidServicePlansAllowed)
	if body, err := m.HTTP.Post(url, m.Token, sendString); err == nil {
		quotaResource := &Quota{}
		if err = json.Unmarshal([]byte(body), &quotaResource); err == nil {
			return quotaResource.MetaData.GUID, nil
		} else {
			return "", err
		}
	} else {
		return "", err
	}
}
func (m *DefaultManager) UpdateQuota(quotaGUID, quotaName string,
	memoryLimit, instanceMemoryLimit, totalRoutes, totalServices int,
	paidServicePlansAllowed bool) error {

	url := fmt.Sprintf("%s/v2/quota_definitions/%s", m.Host, quotaGUID)
	sendString := fmt.Sprintf(`{"guid":"%s","name":"%s","memory_limit":%d,"instance_memory_limit":%d,"total_routes":%d,"total_services":%d,"non_basic_services_allowed":%t}`, quotaGUID, quotaName, memoryLimit, instanceMemoryLimit, totalRoutes, totalServices, paidServicePlansAllowed)
	return m.HTTP.Put(url, m.Token, sendString)
}

func (m *DefaultManager) AssignQuotaToOrg(orgGUID, quotaGUID string) error {
	url := fmt.Sprintf("%s/v2/organizations/%s", m.Host, orgGUID)
	sendString := fmt.Sprintf(`{"quota_definition_guid":"%s"}`, quotaGUID)
	return m.HTTP.Put(url, m.Token, sendString)
}

//GetCFUsers Returns a list of space users who has a given role
func (m *DefaultManager) GetCFUsers(entityGUID, entityType, role string) (map[string]string, error) {
	userMap := make(map[string]string)
	url := fmt.Sprintf("%s/v2/%s/%s/%s?results-per-page=100", m.Host, entityType, entityGUID, role)
	users := &OrgSpaceUsers{}
	var err = m.HTTP.Get(url, m.Token, users)
	if err != nil {
		return nil, err
	}
	nextURL := users.NextURL
	usersTemp := &OrgSpaceUsers{}
	for nextURL != "" {
		url = fmt.Sprintf("%s%s", m.Host, nextURL)
		err = m.HTTP.Get(url, m.Token, usersTemp)
		if err != nil {
			return nil, err
		}
		users.Users = append(users.Users, usersTemp.Users...)
		nextURL = usersTemp.NextURL
	}
	for _, user := range users.Users {
		userMap[strings.ToLower(user.Entity.UserName)] = user.MetaData.GUID
	}
	return userMap, nil
}

//RemoveCFUser - Un assigns a given from the given user for a given org and space
func (m *DefaultManager) RemoveCFUser(entityGUID, entityType, userGUID, role string) error {
	url := fmt.Sprintf("%s/v2/%s/%s/%s/%s", m.Host, entityType, entityGUID, role, userGUID)
	return m.HTTP.Delete(url, m.Token)
}

//QuotaDef Returns quota definition for a given Quota
func (m *DefaultManager) QuotaDef(quotaDefGUID string, entityType string) (*Quota, error) {
	var apiPath string
	if "organizations" == entityType {
		apiPath = "quota_definitions"
	} else {
		apiPath = "space_quota_definitions"
	}
	url := fmt.Sprintf("%s/v2/%s/%s", m.Host, apiPath, quotaDefGUID)
	var err error
	quotaResource := &Quota{}
	if err = m.HTTP.Get(url, m.Token, quotaResource); err == nil {
		lo.G.Debugf("Quota returned : %v", quotaResource.Entity)
		return quotaResource, nil
	}
	lo.G.Errorf("Error from quota API call : %v", err)
	return nil, err
}
<commit_msg>update logging for paging<commit_after>package cloudcontroller

import (
	"encoding/json"
	"fmt"
	"strings"

	"github.com/pivotalservices/cf-mgmt/http"
	"github.com/xchapter7x/lo"
)

func NewManager(host, token string) Manager {
	return &DefaultManager{
		Host:  host,
		Token: token,
		HTTP:  http.NewManager(),
	}
}

func (m *DefaultManager) CreateSpace(spaceName, orgGUID string) error {
	url := fmt.Sprintf("%s/v2/spaces", m.Host)
	sendString := fmt.Sprintf(`{"name":"%s", "organization_guid":"%s"}`, spaceName, orgGUID)
	_, err := m.HTTP.Post(url, m.Token, sendString)
	return err
}

func (m *DefaultManager) ListSpaces(orgGUID string) ([]*Space, error) {
	spaceResources := &SpaceResources{}
	url := fmt.Sprintf("%s/v2/organizations/%s/spaces", m.Host, orgGUID)
	var err = m.HTTP.Get(url, m.Token, spaceResources)
	if err != nil {
		return nil, err
	}
	if spaceResources.NextURL == "" {
		return spaceResources.Spaces, nil
	}
	nextURL := spaceResources.NextURL
	for nextURL != "" {
		lo.G.Debugf("NextURL: %s", nextURL)
		spaceResourcesTemp := &SpaceResources{}
		url = fmt.Sprintf("%s%s", m.Host, nextURL)
		err = m.HTTP.Get(url, m.Token, spaceResourcesTemp)
		if err != nil {
			return nil, err
		}
		spaceResources.Spaces = append(spaceResources.Spaces, spaceResourcesTemp.Spaces...)
		nextURL = spaceResourcesTemp.NextURL
	}
	lo.G.Info("Total spaces returned :", len(spaceResources.Spaces))
	return spaceResources.Spaces, nil
}

func (m *DefaultManager) AddUserToSpaceRole(userName, role, spaceGUID string) error {
	url := fmt.Sprintf("%s/v2/spaces/%s/%s", m.Host, spaceGUID, role)
	sendString := fmt.Sprintf(`{"username": "%s"}`, userName)
	err := m.HTTP.Put(url, m.Token, sendString)
	return err
}

func (m *DefaultManager) AddUserToOrg(userName, orgGUID string) error {
	url := fmt.Sprintf("%s/v2/organizations/%s/users", m.Host, orgGUID)
	sendString := fmt.Sprintf(`{"username": "%s"}`, userName)
	err := m.HTTP.Put(url, m.Token, sendString)
	return err
}

func (m *DefaultManager) UpdateSpaceSSH(sshAllowed bool, spaceGUID string) error {
	url := fmt.Sprintf("%s/v2/spaces/%s", m.Host, spaceGUID)
	sendString := fmt.Sprintf(`{"allow_ssh":%t}`, sshAllowed)
	return m.HTTP.Put(url, m.Token, sendString)
}

func (m *DefaultManager) ListSecurityGroups() (map[string]string, error) {
	var err error
	securityGroups := make(map[string]string)
	url := fmt.Sprintf("%s/v2/security_groups", m.Host)
	sgResources := &SecurityGroupResources{}
	if err = m.HTTP.Get(url, m.Token, sgResources); err == nil {
		for _, sg := range sgResources.SecurityGroups {
			securityGroups[sg.Entity.Name] = sg.MetaData.GUID
		}
		return securityGroups, nil
	}
	return nil, err
}

func (m *DefaultManager) UpdateSecurityGroup(sgGUID, sgName, contents string) error {
	url := fmt.Sprintf("%s/v2/security_groups/%s", m.Host, sgGUID)
	sendString := fmt.Sprintf(`{"name":"%s","rules":%s}`, sgName, contents)
	return m.HTTP.Put(url, m.Token, sendString)
}

func (m *DefaultManager) CreateSecurityGroup(sgName, contents string) (string, error) {
	url := fmt.Sprintf("%s/v2/security_groups", m.Host)
	sendString := fmt.Sprintf(`{"name":"%s","rules":%s}`, sgName, contents)
	if body, err := m.HTTP.Post(url, m.Token, sendString); err != nil {
		return "", err
	} else {
		sgResource := &SecurityGroup{}
		if err := json.Unmarshal([]byte(body), &sgResource); err == nil {
			return sgResource.MetaData.GUID, nil
		} else {
			return "", err
		}
	}
}

func (m *DefaultManager) AssignSecurityGroupToSpace(spaceGUID, sgGUID string) error {
	url := fmt.Sprintf("%s/v2/security_groups/%s/spaces/%s", m.Host, sgGUID, spaceGUID)
	err := m.HTTP.Put(url, m.Token, "")
	return err
}

func (m *DefaultManager) AssignQuotaToSpace(spaceGUID, quotaGUID string) error {
	url := fmt.Sprintf("%s/v2/space_quota_definitions/%s/spaces/%s", m.Host, quotaGUID, spaceGUID)
	err := m.HTTP.Put(url, m.Token, "")
	return err
}

func (m *DefaultManager) CreateSpaceQuota(orgGUID, quotaName string,
	memoryLimit, instanceMemoryLimit, totalRoutes, totalServices int,
	paidServicePlansAllowed bool) (string, error) {
	url := fmt.Sprintf("%s/v2/space_quota_definitions", m.Host)
	sendString := fmt.Sprintf(`{"name":"%s","memory_limit":%d,"instance_memory_limit":%d,"total_routes":%d,"total_services":%d,"non_basic_services_allowed":%t,"organization_guid":"%s"}`, quotaName, memoryLimit, instanceMemoryLimit, totalRoutes, totalServices, paidServicePlansAllowed, orgGUID)
	if body, err := m.HTTP.Post(url, m.Token, sendString); err == nil {
		quotaResource := &Quota{}
		if err = json.Unmarshal([]byte(body), &quotaResource); err == nil {
			return quotaResource.MetaData.GUID, nil
		} else {
			return "", err
		}
	} else {
		return "", err
	}
}

func (m *DefaultManager) UpdateSpaceQuota(orgGUID, quotaGUID, quotaName string,
	memoryLimit, instanceMemoryLimit, totalRoutes, totalServices int,
	paidServicePlansAllowed bool) error {
	url := fmt.Sprintf("%s/v2/space_quota_definitions/%s", m.Host, quotaGUID)
	sendString := fmt.Sprintf(`{"guid":"%s","name":"%s","memory_limit":%d,"instance_memory_limit":%d,"total_routes":%d,"total_services":%d,"non_basic_services_allowed":%t,"organization_guid":"%s"}`, quotaGUID, quotaName, memoryLimit, instanceMemoryLimit, totalRoutes, totalServices, paidServicePlansAllowed, orgGUID)
	return m.HTTP.Put(url, m.Token, sendString)
}

func (m *DefaultManager) ListAllSpaceQuotasForOrg(orgGUID string) (map[string]string, error) {
	quotas := make(map[string]string)
	url := fmt.Sprintf("%s/v2/organizations/%s/space_quota_definitions", m.Host, orgGUID)
	quotaResources := &Quotas{}
	if err := m.HTTP.Get(url, m.Token, quotaResources); err == nil {
		for _, quota := range quotaResources.Quotas {
			quotas[quota.Entity.Name] = quota.MetaData.GUID
		}
		return quotas, nil
	} else {
		return nil, err
	}
}

func (m *DefaultManager) CreateOrg(orgName string) error {
	url := fmt.Sprintf("%s/v2/organizations", m.Host)
	sendString := fmt.Sprintf(`{"name":"%s"}`, orgName)
	_, err := m.HTTP.Post(url, m.Token, sendString)
	return err
}

func (m *DefaultManager) DeleteOrg(orgName string) error {
	orgs, err := m.ListOrgs()
	if err != nil {
		return err
	}
	for _, org := range orgs {
		if org.Entity.Name == orgName {
			url := fmt.Sprintf("%s/v2/organizations/%s?recursive=true", m.Host, org.MetaData.GUID)
			err = m.HTTP.Delete(url, m.Token)
		}
	}

	return err
}

//ListOrgs : Returns all orgs in the given foundation
func (m *DefaultManager) ListOrgs() ([]*Org, error) {
	url := fmt.Sprintf("%s/v2/organizations?results-per-page=100", m.Host)
	orgs := &Orgs{}
	var err = m.HTTP.Get(url, m.Token, orgs)
	if err != nil {
		return nil, err
	}
	if orgs.NextURL == "" {
		return orgs.Orgs, nil
	}
	nextURL := orgs.NextURL
	for nextURL != "" {
		lo.G.Debugf("NextURL: %s", nextURL)
		orgsTemp := &Orgs{}
		url = fmt.Sprintf("%s%s", m.Host, nextURL)
		lo.G.Info("getOrgs() URL :", url)
		err = m.HTTP.Get(url, m.Token, orgsTemp)
		if err != nil {
			return nil, err
		}
		orgs.Orgs = append(orgs.Orgs, orgsTemp.Orgs...)
		nextURL = orgsTemp.NextURL
	}
	lo.G.Info("Total orgs returned :", len(orgs.Orgs))
	return orgs.Orgs, nil
}

func (m *DefaultManager) AddUserToOrgRole(userName, role, orgGUID string) error {
	url := fmt.Sprintf("%s/v2/organizations/%s/%s", m.Host, orgGUID, role)
	sendString := fmt.Sprintf(`{"username": "%s"}`, userName)
	return m.HTTP.Put(url, m.Token, sendString)
}

func (m *DefaultManager) ListAllOrgQuotas() (map[string]string, error) {
	quotas := make(map[string]string)
	url := fmt.Sprintf("%s/v2/quota_definitions", m.Host)
	quotaResources := &Quotas{}
	if err := m.HTTP.Get(url, m.Token, quotaResources); err == nil {
		for _, quota := range quotaResources.Quotas {
			quotas[quota.Entity.Name] = quota.MetaData.GUID
		}
		return quotas, nil
	} else {
		return nil, err
	}
}

func (m *DefaultManager) CreateQuota(quotaName string,
	memoryLimit, instanceMemoryLimit, totalRoutes, totalServices int,
	paidServicePlansAllowed bool) (string, error) {
	url := fmt.Sprintf("%s/v2/quota_definitions", m.Host)
	sendString := fmt.Sprintf(`{"name":"%s","memory_limit":%d,"instance_memory_limit":%d,"total_routes":%d,"total_services":%d,"non_basic_services_allowed":%t}`, quotaName, memoryLimit, instanceMemoryLimit, totalRoutes, totalServices, paidServicePlansAllowed)
	if body, err := m.HTTP.Post(url, m.Token, sendString); err == nil {
		quotaResource := &Quota{}
		if err = json.Unmarshal([]byte(body), &quotaResource); err == nil {
			return quotaResource.MetaData.GUID, nil
		} else {
			return "", err
		}
	} else {
		return "", err
	}
}
func (m *DefaultManager) UpdateQuota(quotaGUID, quotaName string,
	memoryLimit, instanceMemoryLimit, totalRoutes, totalServices int,
	paidServicePlansAllowed bool) error {

	url := fmt.Sprintf("%s/v2/quota_definitions/%s", m.Host, quotaGUID)
	sendString := fmt.Sprintf(`{"guid":"%s","name":"%s","memory_limit":%d,"instance_memory_limit":%d,"total_routes":%d,"total_services":%d,"non_basic_services_allowed":%t}`, quotaGUID, quotaName, memoryLimit, instanceMemoryLimit, totalRoutes, totalServices, paidServicePlansAllowed)
	return m.HTTP.Put(url, m.Token, sendString)
}

func (m *DefaultManager) AssignQuotaToOrg(orgGUID, quotaGUID string) error {
	url := fmt.Sprintf("%s/v2/organizations/%s", m.Host, orgGUID)
	sendString := fmt.Sprintf(`{"quota_definition_guid":"%s"}`, quotaGUID)
	return m.HTTP.Put(url, m.Token, sendString)
}

//GetCFUsers Returns a list of space users who has a given role
func (m *DefaultManager) GetCFUsers(entityGUID, entityType, role string) (map[string]string, error) {
	userMap := make(map[string]string)
	url := fmt.Sprintf("%s/v2/%s/%s/%s?results-per-page=100", m.Host, entityType, entityGUID, role)
	users := &OrgSpaceUsers{}
	var err = m.HTTP.Get(url, m.Token, users)
	if err != nil {
		return nil, err
	}
	nextURL := users.NextURL
	for nextURL != "" {
		lo.G.Debugf("NextURL %s", nextURL)
		usersTemp := &OrgSpaceUsers{}
		url = fmt.Sprintf("%s%s", m.Host, nextURL)
		err = m.HTTP.Get(url, m.Token, usersTemp)
		if err != nil {
			return nil, err
		}
		users.Users = append(users.Users, usersTemp.Users...)
		nextURL = usersTemp.NextURL
	}
	for _, user := range users.Users {
		userMap[strings.ToLower(user.Entity.UserName)] = user.MetaData.GUID
	}
	return userMap, nil
}

//RemoveCFUser - Un assigns a given from the given user for a given org and space
func (m *DefaultManager) RemoveCFUser(entityGUID, entityType, userGUID, role string) error {
	url := fmt.Sprintf("%s/v2/%s/%s/%s/%s", m.Host, entityType, entityGUID, role, userGUID)
	return m.HTTP.Delete(url, m.Token)
}

//QuotaDef Returns quota definition for a given Quota
func (m *DefaultManager) QuotaDef(quotaDefGUID string, entityType string) (*Quota, error) {
	var apiPath string
	if "organizations" == entityType {
		apiPath = "quota_definitions"
	} else {
		apiPath = "space_quota_definitions"
	}
	url := fmt.Sprintf("%s/v2/%s/%s", m.Host, apiPath, quotaDefGUID)
	var err error
	quotaResource := &Quota{}
	if err = m.HTTP.Get(url, m.Token, quotaResource); err == nil {
		lo.G.Debugf("Quota returned : %v", quotaResource.Entity)
		return quotaResource, nil
	}
	lo.G.Errorf("Error from quota API call : %v", err)
	return nil, err
}
<|endoftext|>