<commit_before>// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This file implements the knownFormats map which records the valid
// formats for a given type. The valid formats must correspond to
// supported compiler formats implemented in fmt.go, or whatever
// other format verbs are implemented for the given type. The map may
// also be used to change the use of a format verb across all compiler
// sources automatically (for instance, if the implementation of fmt.go
// changes), by using the -r option together with the new formats in the
// map. To generate this file automatically from the existing source,
// run: go test -run Formats -u.
//
// See the package comment in fmt_test.go for additional information.

package main_test

// knownFormats entries are of the form "typename format" -> "newformat".
// An absent entry means that the format is not recognized as valid.
// An empty new format means that the format should remain unchanged.
var knownFormats = map[string]string{
	"*bytes.Buffer %s":                                "",
	"*cmd/compile/internal/gc.Mpflt %v":               "",
	"*cmd/compile/internal/gc.Mpint %v":               "",
	"*cmd/compile/internal/gc.Node %#v":               "",
	"*cmd/compile/internal/gc.Node %+S":               "",
	"*cmd/compile/internal/gc.Node %+v":               "",
	"*cmd/compile/internal/gc.Node %L":                "",
	"*cmd/compile/internal/gc.Node %S":                "",
	"*cmd/compile/internal/gc.Node %j":                "",
	"*cmd/compile/internal/gc.Node %p":                "",
	"*cmd/compile/internal/gc.Node %v":                "",
	"*cmd/compile/internal/ssa.Block %s":              "",
	"*cmd/compile/internal/ssa.Block %v":              "",
	"*cmd/compile/internal/ssa.Func %s":               "",
	"*cmd/compile/internal/ssa.Func %v":               "",
	"*cmd/compile/internal/ssa.Register %s":           "",
	"*cmd/compile/internal/ssa.Register %v":           "",
	"*cmd/compile/internal/ssa.SparseTreeNode %v":     "",
	"*cmd/compile/internal/ssa.Value %s":              "",
	"*cmd/compile/internal/ssa.Value %v":              "",
	"*cmd/compile/internal/ssa.sparseTreeMapEntry %v": "",
	"*cmd/compile/internal/types.Field %p":            "",
	"*cmd/compile/internal/types.Field %v":            "",
	"*cmd/compile/internal/types.Sym %0S":             "",
	"*cmd/compile/internal/types.Sym %S":              "",
	"*cmd/compile/internal/types.Sym %p":              "",
	"*cmd/compile/internal/types.Sym %v":              "",
	"*cmd/compile/internal/types.Type %#L":            "",
	"*cmd/compile/internal/types.Type %#v":            "",
	"*cmd/compile/internal/types.Type %+v":            "",
	"*cmd/compile/internal/types.Type %-S":            "",
	"*cmd/compile/internal/types.Type %0S":            "",
	"*cmd/compile/internal/types.Type %L":             "",
	"*cmd/compile/internal/types.Type %S":             "",
	"*cmd/compile/internal/types.Type %p":             "",
	"*cmd/compile/internal/types.Type %s":             "",
	"*cmd/compile/internal/types.Type %v":             "",
	"*cmd/internal/obj.Addr %v":                       "",
	"*cmd/internal/obj.LSym %v":                       "",
	"*math/big.Float %f":                              "",
	"*math/big.Int %#x":                               "",
	"*math/big.Int %s":                                "",
	"*math/big.Int %v":                                "",
	"[16]byte %x":                                     "",
	"[]*cmd/compile/internal/ssa.Block %v":            "",
	"[]*cmd/compile/internal/ssa.Value %v":            "",
	"[][]string %q":                                   "",
	"[]byte %s":                                       "",
	"[]byte %x":                                       "",
	"[]cmd/compile/internal/ssa.Edge %v":              "",
	"[]cmd/compile/internal/ssa.ID %v":                "",
	"[]cmd/compile/internal/ssa.posetNode %v":         "",
	"[]cmd/compile/internal/ssa.posetUndo %v":         "",
	"[]cmd/compile/internal/syntax.token %s":          "",
	"[]string %v":                                     "",
	"[]uint32 %v":                                     "",
	"bool %v":                                         "",
	"byte %08b":                                       "",
	"byte %c":                                         "",
	"byte %q":                                         "",
	"byte %v":                                         "",
	"cmd/compile/internal/arm.shift %d":               "",
	"cmd/compile/internal/gc.Class %d":                "",
	"cmd/compile/internal/gc.Class %s":                "",
	"cmd/compile/internal/gc.Class %v":                "",
	"cmd/compile/internal/gc.Ctype %d":                "",
	"cmd/compile/internal/gc.Ctype %v":                "",
	"cmd/compile/internal/gc.Nodes %#v":               "",
	"cmd/compile/internal/gc.Nodes %+v":               "",
	"cmd/compile/internal/gc.Nodes %.v":               "",
	"cmd/compile/internal/gc.Nodes %v":                "",
	"cmd/compile/internal/gc.Op %#v":                  "",
	"cmd/compile/internal/gc.Op %v":                   "",
	"cmd/compile/internal/gc.Val %#v":                 "",
	"cmd/compile/internal/gc.Val %T":                  "",
	"cmd/compile/internal/gc.Val %v":                  "",
	"cmd/compile/internal/gc.fmtMode %d":              "",
	"cmd/compile/internal/gc.initKind %d":             "",
	"cmd/compile/internal/gc.itag %v":                 "",
	"cmd/compile/internal/ssa.BranchPrediction %d":    "",
	"cmd/compile/internal/ssa.Edge %v":                "",
	"cmd/compile/internal/ssa.GCNode %v":              "",
	"cmd/compile/internal/ssa.ID %d":                  "",
	"cmd/compile/internal/ssa.ID %v":                  "",
	"cmd/compile/internal/ssa.LocPair %s":             "",
	"cmd/compile/internal/ssa.LocalSlot %s":           "",
	"cmd/compile/internal/ssa.LocalSlot %v":           "",
	"cmd/compile/internal/ssa.Location %T":            "",
	"cmd/compile/internal/ssa.Location %s":            "",
	"cmd/compile/internal/ssa.Op %s":                  "",
	"cmd/compile/internal/ssa.Op %v":                  "",
	"cmd/compile/internal/ssa.ValAndOff %s":           "",
	"cmd/compile/internal/ssa.domain %v":              "",
	"cmd/compile/internal/ssa.posetNode %v":           "",
	"cmd/compile/internal/ssa.posetTestOp %v":         "",
	"cmd/compile/internal/ssa.rbrank %d":              "",
	"cmd/compile/internal/ssa.regMask %d":             "",
	"cmd/compile/internal/ssa.register %d":            "",
	"cmd/compile/internal/ssa.relation %s":            "",
	"cmd/compile/internal/syntax.Error %q":            "",
	"cmd/compile/internal/syntax.Expr %#v":            "",
	"cmd/compile/internal/syntax.LitKind %d":          "",
	"cmd/compile/internal/syntax.Node %T":             "",
	"cmd/compile/internal/syntax.Operator %s":         "",
	"cmd/compile/internal/syntax.Pos %s":              "",
	"cmd/compile/internal/syntax.Pos %v":              "",
	"cmd/compile/internal/syntax.position %s":         "",
	"cmd/compile/internal/syntax.token %q":            "",
	"cmd/compile/internal/syntax.token %s":            "",
	"cmd/compile/internal/types.EType %d":             "",
	"cmd/compile/internal/types.EType %s":             "",
	"cmd/compile/internal/types.EType %v":             "",
	"cmd/internal/obj.ABI %v":                         "",
	"error %v":                                        "",
	"float64 %.2f":                                    "",
	"float64 %.3f":                                    "",
	"float64 %.6g":                                    "",
	"float64 %g":                                      "",
	"int %-12d":                                       "",
	"int %-6d":                                        "",
	"int %-8o":                                        "",
	"int %02d":                                        "",
	"int %6d":                                         "",
	"int %c":                                          "",
	"int %d":                                          "",
	"int %v":                                          "",
	"int %x":                                          "",
	"int16 %d":                                        "",
	"int16 %x":                                        "",
	"int32 %d":                                        "",
	"int32 %v":                                        "",
	"int32 %x":                                        "",
	"int64 %+d":                                       "",
	"int64 %-10d":                                     "",
	"int64 %.5d":                                      "",
	"int64 %X":                                        "",
	"int64 %d":                                        "",
	"int64 %v":                                        "",
	"int64 %x":                                        "",
	"int8 %d":                                         "",
	"int8 %v":                                         "",
	"int8 %x":                                         "",
	"interface{} %#v":                                 "",
	"interface{} %T":                                  "",
	"interface{} %p":                                  "",
	"interface{} %q":                                  "",
	"interface{} %s":                                  "",
	"interface{} %v":                                  "",
	"map[*cmd/compile/internal/gc.Node]*cmd/compile/internal/ssa.Value %v": "",
	"map[*cmd/compile/internal/gc.Node][]*cmd/compile/internal/gc.Node %v": "",
	"map[cmd/compile/internal/ssa.ID]uint32 %v":                            "",
	"map[int64]uint32 %v":  "",
	"math/big.Accuracy %s": "",
	"reflect.Type %s":      "",
	"rune %#U":             "",
	"rune %c":              "",
	"rune %q":              "",
	"string %-*s":          "",
	"string %-16s":         "",
	"string %-6s":          "",
	"string %q":            "",
	"string %s":            "",
	"string %v":            "",
	"time.Duration %d":     "",
	"time.Duration %v":     "",
	"uint %04x":            "",
	"uint %5d":             "",
	"uint %d":              "",
	"uint %x":              "",
	"uint16 %d":            "",
	"uint16 %x":            "",
	"uint32 %#U":           "",
	"uint32 %#x":           "",
	"uint32 %d":            "",
	"uint32 %v":            "",
	"uint32 %x":            "",
	"uint64 %08x":          "",
	"uint64 %b":            "",
	"uint64 %d":            "",
	"uint64 %x":            "",
	"uint8 %d":             "",
	"uint8 %v":             "",
	"uint8 %x":             "",
	"uintptr %d":           "",
}
<commit_msg>cmd/compile: update TestFormats for CL 196959<commit_after>// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This file implements the knownFormats map which records the valid
// formats for a given type. The valid formats must correspond to
// supported compiler formats implemented in fmt.go, or whatever
// other format verbs are implemented for the given type. The map may
// also be used to change the use of a format verb across all compiler
// sources automatically (for instance, if the implementation of fmt.go
// changes), by using the -r option together with the new formats in the
// map. To generate this file automatically from the existing source,
// run: go test -run Formats -u.
//
// See the package comment in fmt_test.go for additional information.

package main_test

// knownFormats entries are of the form "typename format" -> "newformat".
// An absent entry means that the format is not recognized as valid.
// An empty new format means that the format should remain unchanged.
var knownFormats = map[string]string{
	"*bytes.Buffer %s":                                "",
	"*cmd/compile/internal/gc.EscLocation %v":         "",
	"*cmd/compile/internal/gc.Mpflt %v":               "",
	"*cmd/compile/internal/gc.Mpint %v":               "",
	"*cmd/compile/internal/gc.Node %#v":               "",
	"*cmd/compile/internal/gc.Node %+S":               "",
	"*cmd/compile/internal/gc.Node %+v":               "",
	"*cmd/compile/internal/gc.Node %L":                "",
	"*cmd/compile/internal/gc.Node %S":                "",
	"*cmd/compile/internal/gc.Node %j":                "",
	"*cmd/compile/internal/gc.Node %p":                "",
	"*cmd/compile/internal/gc.Node %v":                "",
	"*cmd/compile/internal/ssa.Block %s":              "",
	"*cmd/compile/internal/ssa.Block %v":              "",
	"*cmd/compile/internal/ssa.Func %s":               "",
	"*cmd/compile/internal/ssa.Func %v":               "",
	"*cmd/compile/internal/ssa.Register %s":           "",
	"*cmd/compile/internal/ssa.Register %v":           "",
	"*cmd/compile/internal/ssa.SparseTreeNode %v":     "",
	"*cmd/compile/internal/ssa.Value %s":              "",
	"*cmd/compile/internal/ssa.Value %v":              "",
	"*cmd/compile/internal/ssa.sparseTreeMapEntry %v": "",
	"*cmd/compile/internal/types.Field %p":            "",
	"*cmd/compile/internal/types.Field %v":            "",
	"*cmd/compile/internal/types.Sym %0S":             "",
	"*cmd/compile/internal/types.Sym %S":              "",
	"*cmd/compile/internal/types.Sym %p":              "",
	"*cmd/compile/internal/types.Sym %v":              "",
	"*cmd/compile/internal/types.Type %#L":            "",
	"*cmd/compile/internal/types.Type %#v":            "",
	"*cmd/compile/internal/types.Type %+v":            "",
	"*cmd/compile/internal/types.Type %-S":            "",
	"*cmd/compile/internal/types.Type %0S":            "",
	"*cmd/compile/internal/types.Type %L":             "",
	"*cmd/compile/internal/types.Type %S":             "",
	"*cmd/compile/internal/types.Type %p":             "",
	"*cmd/compile/internal/types.Type %s":             "",
	"*cmd/compile/internal/types.Type %v":             "",
	"*cmd/internal/obj.Addr %v":                       "",
	"*cmd/internal/obj.LSym %v":                       "",
	"*math/big.Float %f":                              "",
	"*math/big.Int %#x":                               "",
	"*math/big.Int %s":                                "",
	"*math/big.Int %v":                                "",
	"[16]byte %x":                                     "",
	"[]*cmd/compile/internal/ssa.Block %v":            "",
	"[]*cmd/compile/internal/ssa.Value %v":            "",
	"[][]string %q":                                   "",
	"[]byte %s":                                       "",
	"[]byte %x":                                       "",
	"[]cmd/compile/internal/ssa.Edge %v":              "",
	"[]cmd/compile/internal/ssa.ID %v":                "",
	"[]cmd/compile/internal/ssa.posetNode %v":         "",
	"[]cmd/compile/internal/ssa.posetUndo %v":         "",
	"[]cmd/compile/internal/syntax.token %s":          "",
	"[]string %v":                                     "",
	"[]uint32 %v":                                     "",
	"bool %v":                                         "",
	"byte %08b":                                       "",
	"byte %c":                                         "",
	"byte %q":                                         "",
	"byte %v":                                         "",
	"cmd/compile/internal/arm.shift %d":               "",
	"cmd/compile/internal/gc.Class %d":                "",
	"cmd/compile/internal/gc.Class %s":                "",
	"cmd/compile/internal/gc.Class %v":                "",
	"cmd/compile/internal/gc.Ctype %d":                "",
	"cmd/compile/internal/gc.Ctype %v":                "",
	"cmd/compile/internal/gc.Nodes %#v":               "",
	"cmd/compile/internal/gc.Nodes %+v":               "",
	"cmd/compile/internal/gc.Nodes %.v":               "",
	"cmd/compile/internal/gc.Nodes %v":                "",
	"cmd/compile/internal/gc.Op %#v":                  "",
	"cmd/compile/internal/gc.Op %v":                   "",
	"cmd/compile/internal/gc.Val %#v":                 "",
	"cmd/compile/internal/gc.Val %T":                  "",
	"cmd/compile/internal/gc.Val %v":                  "",
	"cmd/compile/internal/gc.fmtMode %d":              "",
	"cmd/compile/internal/gc.initKind %d":             "",
	"cmd/compile/internal/gc.itag %v":                 "",
	"cmd/compile/internal/ssa.BranchPrediction %d":    "",
	"cmd/compile/internal/ssa.Edge %v":                "",
	"cmd/compile/internal/ssa.GCNode %v":              "",
	"cmd/compile/internal/ssa.ID %d":                  "",
	"cmd/compile/internal/ssa.ID %v":                  "",
	"cmd/compile/internal/ssa.LocPair %s":             "",
	"cmd/compile/internal/ssa.LocalSlot %s":           "",
	"cmd/compile/internal/ssa.LocalSlot %v":           "",
	"cmd/compile/internal/ssa.Location %T":            "",
	"cmd/compile/internal/ssa.Location %s":            "",
	"cmd/compile/internal/ssa.Op %s":                  "",
	"cmd/compile/internal/ssa.Op %v":                  "",
	"cmd/compile/internal/ssa.ValAndOff %s":           "",
	"cmd/compile/internal/ssa.domain %v":              "",
	"cmd/compile/internal/ssa.posetNode %v":           "",
	"cmd/compile/internal/ssa.posetTestOp %v":         "",
	"cmd/compile/internal/ssa.rbrank %d":              "",
	"cmd/compile/internal/ssa.regMask %d":             "",
	"cmd/compile/internal/ssa.register %d":            "",
	"cmd/compile/internal/ssa.relation %s":            "",
	"cmd/compile/internal/syntax.Error %q":            "",
	"cmd/compile/internal/syntax.Expr %#v":            "",
	"cmd/compile/internal/syntax.LitKind %d":          "",
	"cmd/compile/internal/syntax.Node %T":             "",
	"cmd/compile/internal/syntax.Operator %s":         "",
	"cmd/compile/internal/syntax.Pos %s":              "",
	"cmd/compile/internal/syntax.Pos %v":              "",
	"cmd/compile/internal/syntax.position %s":         "",
	"cmd/compile/internal/syntax.token %q":            "",
	"cmd/compile/internal/syntax.token %s":            "",
	"cmd/compile/internal/types.EType %d":             "",
	"cmd/compile/internal/types.EType %s":             "",
	"cmd/compile/internal/types.EType %v":             "",
	"cmd/internal/obj.ABI %v":                         "",
	"error %v":                                        "",
	"float64 %.2f":                                    "",
	"float64 %.3f":                                    "",
	"float64 %.6g":                                    "",
	"float64 %g":                                      "",
	"int %-12d":                                       "",
	"int %-6d":                                        "",
	"int %-8o":                                        "",
	"int %02d":                                        "",
	"int %6d":                                         "",
	"int %c":                                          "",
	"int %d":                                          "",
	"int %v":                                          "",
	"int %x":                                          "",
	"int16 %d":                                        "",
	"int16 %x":                                        "",
	"int32 %d":                                        "",
	"int32 %v":                                        "",
	"int32 %x":                                        "",
	"int64 %+d":                                       "",
	"int64 %-10d":                                     "",
	"int64 %.5d":                                      "",
	"int64 %X":                                        "",
	"int64 %d":                                        "",
	"int64 %v":                                        "",
	"int64 %x":                                        "",
	"int8 %d":                                         "",
	"int8 %v":                                         "",
	"int8 %x":                                         "",
	"interface{} %#v":                                 "",
	"interface{} %T":                                  "",
	"interface{} %p":                                  "",
	"interface{} %q":                                  "",
	"interface{} %s":                                  "",
	"interface{} %v":                                  "",
	"map[*cmd/compile/internal/gc.Node]*cmd/compile/internal/ssa.Value %v": "",
	"map[*cmd/compile/internal/gc.Node][]*cmd/compile/internal/gc.Node %v": "",
	"map[cmd/compile/internal/ssa.ID]uint32 %v":                            "",
	"map[int64]uint32 %v":  "",
	"math/big.Accuracy %s": "",
	"reflect.Type %s":      "",
	"rune %#U":             "",
	"rune %c":              "",
	"rune %q":              "",
	"string %-*s":          "",
	"string %-16s":         "",
	"string %-6s":          "",
	"string %q":            "",
	"string %s":            "",
	"string %v":            "",
	"time.Duration %d":     "",
	"time.Duration %v":     "",
	"uint %04x":            "",
	"uint %5d":             "",
	"uint %d":              "",
	"uint %x":              "",
	"uint16 %d":            "",
	"uint16 %x":            "",
	"uint32 %#U":           "",
	"uint32 %#x":           "",
	"uint32 %d":            "",
	"uint32 %v":            "",
	"uint32 %x":            "",
	"uint64 %08x":          "",
	"uint64 %b":            "",
	"uint64 %d":            "",
	"uint64 %x":            "",
	"uint8 %d":             "",
	"uint8 %v":             "",
	"uint8 %x":             "",
	"uintptr %d":           "",
}
<|endoftext|>


<commit_before>// Code generated by go generate. DO NOT EDIT.
// Source: vendor/istio.io/api/mixer/v1/global_dictionary.yaml

package attribute

func GlobalList() []string {
	tmp := make([]string, len(globalList))
	copy(tmp, globalList)
	return tmp
}

var (
	globalList = []string{
		"source.ip",
		"source.port",
		"source.name",
		"source.uid",
		"source.namespace",
		"source.labels",
		"source.user",
		"target.ip",
		"target.port",
		"target.service",
		"target.name",
		"target.uid",
		"target.namespace",
		"target.labels",
		"target.user",
		"request.headers",
		"request.id",
		"request.path",
		"request.host",
		"request.method",
		"request.reason",
		"request.referer",
		"request.scheme",
		"request.size",
		"request.time",
		"request.useragent",
		"response.headers",
		"response.size",
		"response.time",
		"response.duration",
		"response.code",
		":authority",
		":method",
		":path",
		":scheme",
		":status",
		"access-control-allow-origin",
		"access-control-allow-methods",
		"access-control-allow-headers",
		"access-control-max-age",
		"access-control-request-method",
		"access-control-request-headers",
		"accept-charset",
		"accept-encoding",
		"accept-language",
		"accept-ranges",
		"accept",
		"access-control-allow",
		"age",
		"allow",
		"authorization",
		"cache-control",
		"content-disposition",
		"content-encoding",
		"content-language",
		"content-length",
		"content-location",
		"content-range",
		"content-type",
		"cookie",
		"date",
		"etag",
		"expect",
		"expires",
		"from",
		"host",
		"if-match",
		"if-modified-since",
		"if-none-match",
		"if-range",
		"if-unmodified-since",
		"keep-alive",
		"last-modified",
		"link",
		"location",
		"max-forwards",
		"proxy-authenticate",
		"proxy-authorization",
		"range",
		"referer",
		"refresh",
		"retry-after",
		"server",
		"set-cookie",
		"strict-transport-sec",
		"transfer-encoding",
		"user-agent",
		"vary",
		"via",
		"www-authenticate",
		"GET",
		"POST",
		"http",
		"envoy",
		"'200'",
		"Keep-Alive",
		"chunked",
		"x-envoy-service-time",
		"x-forwarded-for",
		"x-forwarded-host",
		"x-forwarded-proto",
		"x-http-method-override",
		"x-request-id",
		"x-requested-with",
		"application/json",
		"application/xml",
		"gzip",
		"text/html",
		"text/html; charset=utf-8",
		"text/plain",
		"text/plain; charset=utf-8",
		"'0'",
		"'1'",
		"true",
		"false",
		"gzip, deflate",
		"max-age=0",
		"x-envoy-upstream-service-time",
		"x-envoy-internal",
		"x-envoy-expected-rq-timeout-ms",
		"x-ot-span-context",
		"x-b3-traceid",
		"x-b3-sampled",
		"x-b3-spanid",
		"tcp",
		"connection.id",
		"connection.received.bytes",
		"connection.received.bytes_total",
		"connection.sent.bytes",
		"connection.sent.bytes_total",
		"connection.duration",
		"context.protocol",
		"context.timestamp",
		"context.time",
		"0",
		"1",
		"200",
		"302",
		"400",
		"401",
		"403",
		"404",
		"409",
		"429",
		"499",
		"500",
		"501",
		"502",
		"503",
		"504",
		"destination.ip",
		"destination.port",
		"destination.service",
		"destination.name",
		"destination.uid",
		"destination.namespace",
		"destination.labels",
		"destination.user",
		"source.service",
		"api.service",
		"api.version",
		"api.operation",
		"api.protocol",
		"request.auth.principal",
		"request.auth.audiences",
		"request.auth.presenter",
		"request.api_key",
		"check.error_code",
		"check.error_message",
		"request.total_size",
		"response.total_size",
		"connection.event",
		"check.cache_hit",
		"quota.cache_hit",
		"source.principal",
		"request.auth.claims",
		"request.auth.raw_claims",
		"connection.mtls",
		"source.metadata",
		"source.owner",
		"source.services",
		"source.workload.uid",
		"source.workload.name",
		"source.workload.namespace",
		"destination.metadata",
		"destination.owner",
		"destination.principal",
		"destination.workload.uid",
		"destination.workload.name",
		"destination.workload.namespace",
		"destination.service.uid",
		"destination.service.name",
		"destination.service.namespace",
		"destination.service.host",
		"destination.container.name",
		"destination.container.image",
		"context.reporter.local",
		"context.reporter.uid",
	}
)
<commit_msg>Generate descriptor for the generate service proto. (#6058)<commit_after>// Code generated by go generate. DO NOT EDIT.
// Source: vendor/istio.io/api/mixer/v1/global_dictionary.yaml

package attribute

func GlobalList() ([]string) {
    tmp := make([]string, len(globalList))
    copy(tmp, globalList)
    return tmp
}

var (
    globalList = []string{
		"source.ip",
		"source.port",
		"source.name",
		"source.uid",
		"source.namespace",
		"source.labels",
		"source.user",
		"target.ip",
		"target.port",
		"target.service",
		"target.name",
		"target.uid",
		"target.namespace",
		"target.labels",
		"target.user",
		"request.headers",
		"request.id",
		"request.path",
		"request.host",
		"request.method",
		"request.reason",
		"request.referer",
		"request.scheme",
		"request.size",
		"request.time",
		"request.useragent",
		"response.headers",
		"response.size",
		"response.time",
		"response.duration",
		"response.code",
		":authority",
		":method",
		":path",
		":scheme",
		":status",
		"access-control-allow-origin",
		"access-control-allow-methods",
		"access-control-allow-headers",
		"access-control-max-age",
		"access-control-request-method",
		"access-control-request-headers",
		"accept-charset",
		"accept-encoding",
		"accept-language",
		"accept-ranges",
		"accept",
		"access-control-allow",
		"age",
		"allow",
		"authorization",
		"cache-control",
		"content-disposition",
		"content-encoding",
		"content-language",
		"content-length",
		"content-location",
		"content-range",
		"content-type",
		"cookie",
		"date",
		"etag",
		"expect",
		"expires",
		"from",
		"host",
		"if-match",
		"if-modified-since",
		"if-none-match",
		"if-range",
		"if-unmodified-since",
		"keep-alive",
		"last-modified",
		"link",
		"location",
		"max-forwards",
		"proxy-authenticate",
		"proxy-authorization",
		"range",
		"referer",
		"refresh",
		"retry-after",
		"server",
		"set-cookie",
		"strict-transport-sec",
		"transfer-encoding",
		"user-agent",
		"vary",
		"via",
		"www-authenticate",
		"GET",
		"POST",
		"http",
		"envoy",
		"'200'",
		"Keep-Alive",
		"chunked",
		"x-envoy-service-time",
		"x-forwarded-for",
		"x-forwarded-host",
		"x-forwarded-proto",
		"x-http-method-override",
		"x-request-id",
		"x-requested-with",
		"application/json",
		"application/xml",
		"gzip",
		"text/html",
		"text/html; charset=utf-8",
		"text/plain",
		"text/plain; charset=utf-8",
		"'0'",
		"'1'",
		"true",
		"false",
		"gzip, deflate",
		"max-age=0",
		"x-envoy-upstream-service-time",
		"x-envoy-internal",
		"x-envoy-expected-rq-timeout-ms",
		"x-ot-span-context",
		"x-b3-traceid",
		"x-b3-sampled",
		"x-b3-spanid",
		"tcp",
		"connection.id",
		"connection.received.bytes",
		"connection.received.bytes_total",
		"connection.sent.bytes",
		"connection.sent.bytes_total",
		"connection.duration",
		"context.protocol",
		"context.timestamp",
		"context.time",
		"0",
		"1",
		"200",
		"302",
		"400",
		"401",
		"403",
		"404",
		"409",
		"429",
		"499",
		"500",
		"501",
		"502",
		"503",
		"504",
		"destination.ip",
		"destination.port",
		"destination.service",
		"destination.name",
		"destination.uid",
		"destination.namespace",
		"destination.labels",
		"destination.user",
		"source.service",
		"api.service",
		"api.version",
		"api.operation",
		"api.protocol",
		"request.auth.principal",
		"request.auth.audiences",
		"request.auth.presenter",
		"request.api_key",
		"check.error_code",
		"check.error_message",
		"request.total_size",
		"response.total_size",
		"connection.event",
		"check.cache_hit",
		"quota.cache_hit",
		"source.principal",
		"request.auth.claims",
		"request.auth.raw_claims",
		"connection.mtls",
		"source.metadata",
		"source.owner",
		"source.services",
		"source.workload.uid",
		"source.workload.name",
		"source.workload.namespace",
		"destination.metadata",
		"destination.owner",
		"destination.principal",
		"destination.workload.uid",
		"destination.workload.name",
		"destination.workload.namespace",
		"destination.service.uid",
		"destination.service.name",
		"destination.service.namespace",
		"destination.service.host",
		"destination.container.name",
		"destination.container.image",
		"context.reporter.local",
		"context.reporter.uid",
    }
)
<|endoftext|>


<commit_before>// Code generated by go generate. DO NOT EDIT.
// Source: vendor/istio.io/api/mixer/v1/global_dictionary.yaml

package attribute

func GlobalList() ([]string) {
    tmp := make([]string, len(globalList))
    copy(tmp, globalList)
    return tmp
}

var (
    globalList = []string{
		"source.ip",
		"source.port",
		"source.name",
		"source.uid",
		"source.namespace",
		"source.labels",
		"source.user",
		"target.ip",
		"target.port",
		"target.service",
		"target.name",
		"target.uid",
		"target.namespace",
		"target.labels",
		"target.user",
		"request.headers",
		"request.id",
		"request.path",
		"request.host",
		"request.method",
		"request.reason",
		"request.referer",
		"request.scheme",
		"request.size",
		"request.time",
		"request.useragent",
		"response.headers",
		"response.size",
		"response.time",
		"response.duration",
		"response.code",
		":authority",
		":method",
		":path",
		":scheme",
		":status",
		"access-control-allow-origin",
		"access-control-allow-methods",
		"access-control-allow-headers",
		"access-control-max-age",
		"access-control-request-method",
		"access-control-request-headers",
		"accept-charset",
		"accept-encoding",
		"accept-language",
		"accept-ranges",
		"accept",
		"access-control-allow",
		"age",
		"allow",
		"authorization",
		"cache-control",
		"content-disposition",
		"content-encoding",
		"content-language",
		"content-length",
		"content-location",
		"content-range",
		"content-type",
		"cookie",
		"date",
		"etag",
		"expect",
		"expires",
		"from",
		"host",
		"if-match",
		"if-modified-since",
		"if-none-match",
		"if-range",
		"if-unmodified-since",
		"keep-alive",
		"last-modified",
		"link",
		"location",
		"max-forwards",
		"proxy-authenticate",
		"proxy-authorization",
		"range",
		"referer",
		"refresh",
		"retry-after",
		"server",
		"set-cookie",
		"strict-transport-sec",
		"transfer-encoding",
		"user-agent",
		"vary",
		"via",
		"www-authenticate",
		"GET",
		"POST",
		"http",
		"envoy",
		"'200'",
		"Keep-Alive",
		"chunked",
		"x-envoy-service-time",
		"x-forwarded-for",
		"x-forwarded-host",
		"x-forwarded-proto",
		"x-http-method-override",
		"x-request-id",
		"x-requested-with",
		"application/json",
		"application/xml",
		"gzip",
		"text/html",
		"text/html; charset=utf-8",
		"text/plain",
		"text/plain; charset=utf-8",
		"'0'",
		"'1'",
		"true",
		"false",
		"gzip, deflate",
		"max-age=0",
		"x-envoy-upstream-service-time",
		"x-envoy-internal",
		"x-envoy-expected-rq-timeout-ms",
		"x-ot-span-context",
		"x-b3-traceid",
		"x-b3-sampled",
		"x-b3-spanid",
		"tcp",
		"connection.id",
		"connection.received.bytes",
		"connection.received.bytes_total",
		"connection.sent.bytes",
		"connection.sent.bytes_total",
		"connection.duration",
		"context.protocol",
		"context.timestamp",
		"context.time",
		"0",
		"1",
		"200",
		"302",
		"400",
		"401",
		"403",
		"404",
		"409",
		"429",
		"499",
		"500",
		"501",
		"502",
		"503",
		"504",
		"destination.ip",
		"destination.port",
		"destination.service",
		"destination.name",
		"destination.uid",
		"destination.namespace",
		"destination.labels",
		"destination.user",
		"source.service",
		"api.service",
		"api.version",
		"api.operation",
		"api.protocol",
		"request.auth.principal",
		"request.auth.audiences",
		"request.auth.presenter",
		"request.api_key",
		"check.error_code",
		"check.error_message",
		"request.total_size",
		"response.total_size",
		"connection.event",
		"check.cache_hit",
		"quota.cache_hit",
    }
)
<commit_msg>Define request.auth.claims (#5550)<commit_after>// Code generated by go generate. DO NOT EDIT.
// Source: vendor/istio.io/api/mixer/v1/global_dictionary.yaml

package attribute

func GlobalList() ([]string) {
    tmp := make([]string, len(globalList))
    copy(tmp, globalList)
    return tmp
}

var (
    globalList = []string{
		"source.ip",
		"source.port",
		"source.name",
		"source.uid",
		"source.namespace",
		"source.labels",
		"source.user",
		"target.ip",
		"target.port",
		"target.service",
		"target.name",
		"target.uid",
		"target.namespace",
		"target.labels",
		"target.user",
		"request.headers",
		"request.id",
		"request.path",
		"request.host",
		"request.method",
		"request.reason",
		"request.referer",
		"request.scheme",
		"request.size",
		"request.time",
		"request.useragent",
		"response.headers",
		"response.size",
		"response.time",
		"response.duration",
		"response.code",
		":authority",
		":method",
		":path",
		":scheme",
		":status",
		"access-control-allow-origin",
		"access-control-allow-methods",
		"access-control-allow-headers",
		"access-control-max-age",
		"access-control-request-method",
		"access-control-request-headers",
		"accept-charset",
		"accept-encoding",
		"accept-language",
		"accept-ranges",
		"accept",
		"access-control-allow",
		"age",
		"allow",
		"authorization",
		"cache-control",
		"content-disposition",
		"content-encoding",
		"content-language",
		"content-length",
		"content-location",
		"content-range",
		"content-type",
		"cookie",
		"date",
		"etag",
		"expect",
		"expires",
		"from",
		"host",
		"if-match",
		"if-modified-since",
		"if-none-match",
		"if-range",
		"if-unmodified-since",
		"keep-alive",
		"last-modified",
		"link",
		"location",
		"max-forwards",
		"proxy-authenticate",
		"proxy-authorization",
		"range",
		"referer",
		"refresh",
		"retry-after",
		"server",
		"set-cookie",
		"strict-transport-sec",
		"transfer-encoding",
		"user-agent",
		"vary",
		"via",
		"www-authenticate",
		"GET",
		"POST",
		"http",
		"envoy",
		"'200'",
		"Keep-Alive",
		"chunked",
		"x-envoy-service-time",
		"x-forwarded-for",
		"x-forwarded-host",
		"x-forwarded-proto",
		"x-http-method-override",
		"x-request-id",
		"x-requested-with",
		"application/json",
		"application/xml",
		"gzip",
		"text/html",
		"text/html; charset=utf-8",
		"text/plain",
		"text/plain; charset=utf-8",
		"'0'",
		"'1'",
		"true",
		"false",
		"gzip, deflate",
		"max-age=0",
		"x-envoy-upstream-service-time",
		"x-envoy-internal",
		"x-envoy-expected-rq-timeout-ms",
		"x-ot-span-context",
		"x-b3-traceid",
		"x-b3-sampled",
		"x-b3-spanid",
		"tcp",
		"connection.id",
		"connection.received.bytes",
		"connection.received.bytes_total",
		"connection.sent.bytes",
		"connection.sent.bytes_total",
		"connection.duration",
		"context.protocol",
		"context.timestamp",
		"context.time",
		"0",
		"1",
		"200",
		"302",
		"400",
		"401",
		"403",
		"404",
		"409",
		"429",
		"499",
		"500",
		"501",
		"502",
		"503",
		"504",
		"destination.ip",
		"destination.port",
		"destination.service",
		"destination.name",
		"destination.uid",
		"destination.namespace",
		"destination.labels",
		"destination.user",
		"source.service",
		"api.service",
		"api.version",
		"api.operation",
		"api.protocol",
		"request.auth.principal",
		"request.auth.audiences",
		"request.auth.presenter",
		"request.api_key",
		"check.error_code",
		"check.error_message",
		"request.total_size",
		"response.total_size",
		"connection.event",
		"check.cache_hit",
		"quota.cache_hit",
		"source.principal",
		"request.auth.claims",
    }
)
<|endoftext|>


<commit_before>package main

import (
	"github.com/zvin/gocairo"
	"strings"
	"sync"
	"time"
)

const (
	WIDTH  = 2000
	HEIGHT = 3000
)

var (
	locations          = make(map[string]*Location)
	locationsMutex     sync.RWMutex
	CurrentlyUsedSites LockableWebsiteSlice
)

type UserAndEvent struct {
	User  *User
	Event []interface{}
}

type Location struct {
	Join         chan *JoinRequest
	Quit         chan *User
	Message      chan UserAndEvent
	Close        chan bool
	Url          string
	UserCount    int
	Chat         *MessagesLog
	users        []*User
	fileName     string
	chatFileName string
	surface      *cairo.Surface
	delta        []interface{}
}

func init() {
	go func() {
		tick := time.Tick(10 * time.Second)
		for _ = range tick {
			update_currently_used_sites()
		}
	}()
}

func GetLocation(url string) *Location {
	locationsMutex.Lock()
	defer locationsMutex.Unlock()
	location, present := locations[url]
	if present {
		return location
	} else {
		location = NewLocation(url)
		locations[url] = location
	}
	return location
}

func CloseAllLocations() {
	locationsMutex.Lock()
	for _, loc := range locations {
		loc.Close <- true
		<-loc.Close
		delete(locations, loc.Url)
	}
	locationsMutex.Unlock()
}

func CloseLocation(location *Location) {
	locationsMutex.Lock()
	delete(locations, location.Url)
	locationsMutex.Unlock()
}

func update_currently_used_sites() {
	var sites []Website
	locationsMutex.RLock()
	for _, location := range locations {
		count := location.UserCount
		if count > 0 {
			sites = append(sites, Website{Url: location.Url, UserCount: count})
		}
	}
	locationsMutex.RUnlock()
	SortWebsites(sites)
	CurrentlyUsedSites.Mutex.Lock()
	CurrentlyUsedSites.Sites = sites[:MinInt(len(sites), 10)]
	CurrentlyUsedSites.Mutex.Unlock()
}

func NewLocation(url string) *Location {
	loc := new(Location)
	loc.Join = make(chan *JoinRequest)
	loc.Quit = make(chan *User)
	loc.Message = make(chan UserAndEvent)
	loc.Close = make(chan bool)
	loc.Url = url
	b64fname := Base64Encode(url)
	b64fname = b64fname[:MinInt(len(b64fname), 251)]
	b64fname = strings.Replace(b64fname, "/", "_", -1)
	loc.chatFileName = CHAT_DIR + "/" + b64fname + ".gob"
	loc.Chat = OpenMessagesLog(loc.chatFileName)
	loc.fileName = IMAGES_DIR + "/" + b64fname + ".png" // filename
	Log.Printf("filename: %v", loc.fileName)
	loc.surface = cairo.NewSurfaceFromPNG(loc.fileName)
	if loc.surface.SurfaceStatus() != 0 {
		loc.surface.Finish()
		loc.surface.Destroy()
		loc.surface = cairo.NewSurface(cairo.FormatArgB32, WIDTH, HEIGHT)
	}
	loc.surface.SetSourceRGB(0, 0, 0)
	go loc.main()
	return loc
}

func (location *Location) main() {
	save_tick := time.Tick(1 * time.Minute)
	for {
		select {
		case request := <-location.Join:
			if len(location.users) >= MAX_USERS_PER_LOCATION {
				request.resultChan <- false
			} else {
				Log.Println("New user", request.user.UserId, "joins", location.Url)
				location.AddUser(request.user)
				request.resultChan <- true
			}
		case user := <-location.Quit:
			location.RemoveUser(user)
			if len(location.users) == 0 {
				location.Save()
				location.Destroy()
				CloseLocation(location)
				return
			}
		case message := <-location.Message:
			event := message.User.GotMessage(message.Event)
			if event != nil {
				location.broadcast(message.User, event)
			}
		case <-save_tick:
			location.Save()
		case <-location.Close:
			for _, user := range location.users {
				user.Socket.Close()
			}
			location.Save()
			location.Destroy()
			location.Close <- true
			return
		}
	}
}

func (location *Location) Destroy() {
	location.surface.Finish()
	location.surface.Destroy()
}

func (location *Location) broadcast(user *User, event []interface{}) {
	// event.insert(1, user.UserId) ...
	event = append(event[:1], append([]interface{}{user.UserId}, event[1:]...)...)
	for _, other := range location.users {
		other.SendEvent(event)
	}
}

func (location *Location) AddUser(user *User) {
	user.Location = location
	// Send the list of present users to this user:
	timestamp := Timestamp()
	for _, other := range location.users {
		user.SendEvent([]interface{}{
			EventTypeJoin,
			other.UserId,
			[]interface{}{other.PositionX, other.PositionY},
			[]interface{}{other.ColorRed, other.ColorGreen, other.ColorBlue},
			other.MouseIsDown,
			false, // not you
			other.Nickname,
			other.UsePen,
			0, // no timestamp
		})
	}
	// Send the delta between the image and now to the new user:
	user.SendEvent([]interface{}{
		EventTypeWelcome,
		location.fileName,
		location.GetDelta(),
		location.Chat.GetMessages(),
	})
	// Send this new user to other users:
	event := []interface{}{
		EventTypeJoin,
		[]interface{}{user.PositionX, user.PositionY},
		[]interface{}{user.ColorRed, user.ColorGreen, user.ColorBlue},
		user.MouseIsDown,
		false, // not you
		user.Nickname,
		user.UsePen,
		timestamp,
	}
	location.broadcast(user, event) // user is not yet in location.users, so it will not receive this event.
	// Send this user to himself
	event = []interface{}{
		EventTypeJoin,
		user.UserId,
		[]interface{}{user.PositionX, user.PositionY},
		[]interface{}{user.ColorRed, user.ColorGreen, user.ColorBlue},
		user.MouseIsDown,
		true, // you
		user.Nickname,
		user.UsePen,
		timestamp,
	}
	user.SendEvent(event)
	location.users = append(location.users, user)
	location.Chat.AddMessage(timestamp, "", "user "+user.Nickname+" joined")
	location.UserCount += 1
}

func (location *Location) RemoveUser(user *User) {
	location.users = Remove(location.users, user)
	timestamp := Timestamp()
	location.broadcast(user, []interface{}{EventTypeLeave, timestamp})
	location.Chat.AddMessage(timestamp, "", "user "+user.Nickname+" left")
	location.UserCount -= 1
}

func (location *Location) DrawLine(x1, y1, x2, y2, duration, red, green, blue int, use_pen bool) {
	//    fmt.Printf("draw line duration %d\n", duration)
	if duration <= 0 {
		return
	}
	d := Distance(x1, y1, x2, y2)
	if d <= 0 {
		return
	}
	location.delta = append(location.delta, []interface{}{x1, y1, x2, y2, duration, red, green, blue, use_pen})
	speed := d / float64(duration)
	if !use_pen { // not use_pen: use eraser
		location.surface.SetOperator(cairo.OperatorDestOut)
	} else {
		location.surface.SetOperator(cairo.OperatorOver)
		location.surface.SetSourceRGB(float64(red)/255., float64(green)/255., float64(blue)/255.)
	}
	location.surface.SetLineWidth(1. / (1.3 + (3. * speed)))
	location.surface.MoveTo(float64(x1), float64(y1))
	location.surface.LineTo(float64(x2), float64(y2))
	location.surface.Stroke()
}

func (location *Location) GetDelta() []interface{} {
	return location.delta
}

func (location *Location) Save() {
	if len(location.delta) > 0 {
		Log.Printf("save %s (delta %d)\n", location.Url, len(location.delta))
		location.surface.WriteToPNG(location.fileName) // Output to PNG
		location.delta = nil
	}
	location.Chat.Save()
}

func Remove(list []*User, value *User) []*User {
	var i int
	var elem *User
	for i, elem = range list {
		if elem == value {
			break
		}
	}
	return append(list[:i], list[i+1:]...)
}
<commit_msg>Location.save and Location.destroy are private<commit_after>package main

import (
	"github.com/zvin/gocairo"
	"strings"
	"sync"
	"time"
)

const (
	WIDTH  = 2000
	HEIGHT = 3000
)

var (
	locations          = make(map[string]*Location)
	locationsMutex     sync.RWMutex
	CurrentlyUsedSites LockableWebsiteSlice
)

type UserAndEvent struct {
	User  *User
	Event []interface{}
}

type Location struct {
	Join         chan *JoinRequest
	Quit         chan *User
	Message      chan UserAndEvent
	Close        chan bool
	Url          string
	UserCount    int
	Chat         *MessagesLog
	users        []*User
	fileName     string
	chatFileName string
	surface      *cairo.Surface
	delta        []interface{}
}

func init() {
	go func() {
		tick := time.Tick(10 * time.Second)
		for _ = range tick {
			update_currently_used_sites()
		}
	}()
}

func GetLocation(url string) *Location {
	locationsMutex.Lock()
	defer locationsMutex.Unlock()
	location, present := locations[url]
	if present {
		return location
	} else {
		location = NewLocation(url)
		locations[url] = location
	}
	return location
}

func CloseAllLocations() {
	locationsMutex.Lock()
	for _, loc := range locations {
		loc.Close <- true
		<-loc.Close
		delete(locations, loc.Url)
	}
	locationsMutex.Unlock()
}

func CloseLocation(location *Location) {
	locationsMutex.Lock()
	delete(locations, location.Url)
	locationsMutex.Unlock()
}

func update_currently_used_sites() {
	var sites []Website
	locationsMutex.RLock()
	for _, location := range locations {
		count := location.UserCount
		if count > 0 {
			sites = append(sites, Website{Url: location.Url, UserCount: count})
		}
	}
	locationsMutex.RUnlock()
	SortWebsites(sites)
	CurrentlyUsedSites.Mutex.Lock()
	CurrentlyUsedSites.Sites = sites[:MinInt(len(sites), 10)]
	CurrentlyUsedSites.Mutex.Unlock()
}

func NewLocation(url string) *Location {
	loc := new(Location)
	loc.Join = make(chan *JoinRequest)
	loc.Quit = make(chan *User)
	loc.Message = make(chan UserAndEvent)
	loc.Close = make(chan bool)
	loc.Url = url
	b64fname := Base64Encode(url)
	b64fname = b64fname[:MinInt(len(b64fname), 251)]
	b64fname = strings.Replace(b64fname, "/", "_", -1)
	loc.chatFileName = CHAT_DIR + "/" + b64fname + ".gob"
	loc.Chat = OpenMessagesLog(loc.chatFileName)
	loc.fileName = IMAGES_DIR + "/" + b64fname + ".png" // filename
	Log.Printf("filename: %v", loc.fileName)
	loc.surface = cairo.NewSurfaceFromPNG(loc.fileName)
	if loc.surface.SurfaceStatus() != 0 {
		loc.surface.Finish()
		loc.surface.Destroy()
		loc.surface = cairo.NewSurface(cairo.FormatArgB32, WIDTH, HEIGHT)
	}
	loc.surface.SetSourceRGB(0, 0, 0)
	go loc.main()
	return loc
}

func (location *Location) main() {
	save_tick := time.Tick(1 * time.Minute)
	for {
		select {
		case request := <-location.Join:
			if len(location.users) >= MAX_USERS_PER_LOCATION {
				request.resultChan <- false
			} else {
				Log.Println("New user", request.user.UserId, "joins", location.Url)
				location.AddUser(request.user)
				request.resultChan <- true
			}
		case user := <-location.Quit:
			location.RemoveUser(user)
			if len(location.users) == 0 {
				location.save()
				location.destroy()
				CloseLocation(location)
				return
			}
		case message := <-location.Message:
			event := message.User.GotMessage(message.Event)
			if event != nil {
				location.broadcast(message.User, event)
			}
		case <-save_tick:
			location.save()
		case <-location.Close:
			for _, user := range location.users {
				user.Socket.Close()
			}
			location.save()
			location.destroy()
			location.Close <- true
			return  // stop processing events for this location
		}
	}
}

func (location *Location) destroy() {
	location.surface.Finish()
	location.surface.Destroy()
}

func (location *Location) broadcast(user *User, event []interface{}) {
	// event.insert(1, user.UserId) ...
	event = append(event[:1], append([]interface{}{user.UserId}, event[1:]...)...)
	for _, other := range location.users {
		other.SendEvent(event)
	}
}

func (location *Location) AddUser(user *User) {
	user.Location = location
	// Send the list of present users to this user:
	timestamp := Timestamp()
	for _, other := range location.users {
		user.SendEvent([]interface{}{
			EventTypeJoin,
			other.UserId,
			[]interface{}{other.PositionX, other.PositionY},
			[]interface{}{other.ColorRed, other.ColorGreen, other.ColorBlue},
			other.MouseIsDown,
			false, // not you
			other.Nickname,
			other.UsePen,
			0, // no timestamp
		})
	}
	// Send the delta between the image and now to the new user:
	user.SendEvent([]interface{}{
		EventTypeWelcome,
		location.fileName,
		location.GetDelta(),
		location.Chat.GetMessages(),
	})
	// Send this new user to other users:
	event := []interface{}{
		EventTypeJoin,
		[]interface{}{user.PositionX, user.PositionY},
		[]interface{}{user.ColorRed, user.ColorGreen, user.ColorBlue},
		user.MouseIsDown,
		false, // not you
		user.Nickname,
		user.UsePen,
		timestamp,
	}
	location.broadcast(user, event) // user is not yet in location.users, so it will not receive this event.
	// Send this user to himself
	event = []interface{}{
		EventTypeJoin,
		user.UserId,
		[]interface{}{user.PositionX, user.PositionY},
		[]interface{}{user.ColorRed, user.ColorGreen, user.ColorBlue},
		user.MouseIsDown,
		true, // you
		user.Nickname,
		user.UsePen,
		timestamp,
	}
	user.SendEvent(event)
	location.users = append(location.users, user)
	location.Chat.AddMessage(timestamp, "", "user "+user.Nickname+" joined")
	location.UserCount += 1
}

func (location *Location) RemoveUser(user *User) {
	location.users = Remove(location.users, user)
	timestamp := Timestamp()
	location.broadcast(user, []interface{}{EventTypeLeave, timestamp})
	location.Chat.AddMessage(timestamp, "", "user "+user.Nickname+" left")
	location.UserCount -= 1
}

func (location *Location) DrawLine(x1, y1, x2, y2, duration, red, green, blue int, use_pen bool) {
	//    fmt.Printf("draw line duration %d\n", duration)
	if duration <= 0 {
		return
	}
	d := Distance(x1, y1, x2, y2)
	if d <= 0 {
		return
	}
	location.delta = append(location.delta, []interface{}{x1, y1, x2, y2, duration, red, green, blue, use_pen})
	speed := d / float64(duration)
	if !use_pen { // not use_pen: use eraser
		location.surface.SetOperator(cairo.OperatorDestOut)
	} else {
		location.surface.SetOperator(cairo.OperatorOver)
		location.surface.SetSourceRGB(float64(red)/255., float64(green)/255., float64(blue)/255.)
	}
	location.surface.SetLineWidth(1. / (1.3 + (3. * speed)))
	location.surface.MoveTo(float64(x1), float64(y1))
	location.surface.LineTo(float64(x2), float64(y2))
	location.surface.Stroke()
}

func (location *Location) GetDelta() []interface{} {
	return location.delta
}

func (location *Location) save() {
	if len(location.delta) > 0 {
		Log.Printf("save %s (delta %d)\n", location.Url, len(location.delta))
		location.surface.WriteToPNG(location.fileName) // Output to PNG
		location.delta = nil
	}
	location.Chat.Save()
}

func Remove(list []*User, value *User) []*User {
	var i int
	var elem *User
	for i, elem = range list {
		if elem == value {
			break
		}
	}
	return append(list[:i], list[i+1:]...)
}
<|endoftext|>


<commit_before>package gostagram

import (
	"fmt"
	"errors"

	"github.com/mitchellh/mapstructure"
	"strconv"
)

var (
	maxLocationDistanceError = errors.New("Maximun distance is 5km.")
)

const (
	maxLocationDistance = 750
)

type Location struct {
	Id        string
	Name      string
	Latitude  float64
	Longitude float64
}

// Get an especific location by a respective id,
// for more information about it, go to
// https://www.instagram.com/developer/endpoints/locations/#get_locations
func (c Client) GetLocationById(location_id string) (*Location, error) {
	tmp, _, err := c.get(fmt.Sprintf("%slocations/%s?access_token=%s", apiUrl, location_id, c.access_token))
	if err != nil {
		return nil, err
	}

	tmpLocation := (*tmp).(map[string]interface{})
	var location Location
	if err = mapstructure.Decode(tmpLocation, &location); err != nil {
		return nil, err
	}

	return &location, nil
}

// Search locations by its latitude, longitude, distance and facebook places,
// for more information about it, go to
// https://www.instagram.com/developer/endpoints/locations/#get_locations_search
func (c Client) SearchLocations(latitude, longitude string, params Parameters) ([]*Location, error) {
	tmp1 := "%slocations/search?lat=%s&lng=%s&access_token=%s"
	if params != nil {
		if params["distance"] != "" {
			distance, err := strconv.Atoi(params["distance"])
			if err != nil {
				return nil, err
			}

			if distance > maxLocationDistance {
				return nil, maxLocationDistanceError
			}

			tmp1 += fmt.Sprintf("&distance=%d", distance)
		}
	}

	tmp, _, err := c.get(fmt.Sprintf(tmp1,
		apiUrl, latitude, longitude, c.access_token))

	if err != nil {
		return nil, err
	}

	tmpLocations := (*tmp).([]interface{})
	var locations []*Location
	for _, tmplocation := range tmpLocations {
		var location Location

		if err := mapstructure.Decode(tmplocation, &location); err != nil {
			return nil, err
		}

		locations = append(locations, &location)
	}

	return locations, nil
}
<commit_msg>Fixed error message.<commit_after>package gostagram

import (
	"fmt"
	"errors"

	"github.com/mitchellh/mapstructure"
	"strconv"
)

var (
	maxLocationDistanceError = errors.New("Maximun distance is 750m.")
)

const (
	maxLocationDistance = 750
)

type Location struct {
	Id        string
	Name      string
	Latitude  float64
	Longitude float64
}

// Get an especific location by a respective id,
// for more information about it, go to
// https://www.instagram.com/developer/endpoints/locations/#get_locations
func (c Client) GetLocationById(location_id string) (*Location, error) {
	tmp, _, err := c.get(fmt.Sprintf("%slocations/%s?access_token=%s", apiUrl, location_id, c.access_token))
	if err != nil {
		return nil, err
	}

	tmpLocation := (*tmp).(map[string]interface{})
	var location Location
	if err = mapstructure.Decode(tmpLocation, &location); err != nil {
		return nil, err
	}

	return &location, nil
}

// Search locations by its latitude, longitude, distance and facebook places,
// for more information about it, go to
// https://www.instagram.com/developer/endpoints/locations/#get_locations_search
func (c Client) SearchLocations(latitude, longitude string, params Parameters) ([]*Location, error) {
	tmp1 := "%slocations/search?lat=%s&lng=%s&access_token=%s"
	if params != nil {
		if params["distance"] != "" {
			distance, err := strconv.Atoi(params["distance"])
			if err != nil {
				return nil, err
			}

			if distance > maxLocationDistance {
				return nil, maxLocationDistanceError
			}

			tmp1 += fmt.Sprintf("&distance=%d", distance)
		}
	}

	tmp, _, err := c.get(fmt.Sprintf(tmp1,
		apiUrl, latitude, longitude, c.access_token))

	if err != nil {
		return nil, err
	}

	tmpLocations := (*tmp).([]interface{})
	var locations []*Location
	for _, tmplocation := range tmpLocations {
		var location Location

		if err := mapstructure.Decode(tmplocation, &location); err != nil {
			return nil, err
		}

		locations = append(locations, &location)
	}

	return locations, nil
}
<|endoftext|>


<commit_before>package cloudflare

import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"time"
)

// ZoneLockdown represents a Zone Lockdown rule. A rule only permits access to
// the provided URL pattern(s) from the given IP address(es) or subnet(s).
type ZoneLockdown struct {
	ID             string               `json:"id"`
	Description    string               `json:"description"`
	URLs           []string             `json:"urls"`
	Configurations []ZoneLockdownConfig `json:"configurations"`
	Paused         bool                 `json:"paused"`
	Priority       int                  `json:"priority,omitempty"`
	CreatedOn      *time.Time           `json:"created_on,omitempty"`
	ModifiedOn     *time.Time           `json:"modified_on,omitempty"`
}

// ZoneLockdownConfig represents a Zone Lockdown config, which comprises
// a Target ("ip" or "ip_range") and a Value (an IP address or IP+mask,
// respectively.)
type ZoneLockdownConfig struct {
	Target string `json:"target"`
	Value  string `json:"value"`
}

// ZoneLockdownResponse represents a response from the Zone Lockdown endpoint.
type ZoneLockdownResponse struct {
	Result ZoneLockdown `json:"result"`
	Response
	ResultInfo `json:"result_info"`
}

// ZoneLockdownListResponse represents a response from the List Zone Lockdown
// endpoint.
type ZoneLockdownListResponse struct {
	Result []ZoneLockdown `json:"result"`
	Response
	ResultInfo `json:"result_info"`
}

// ZoneLockdownCreateParams contains required and optional params
// for creating a zone lockdown.
type ZoneLockdownCreateParams struct {
	Description    string               `json:"description"`
	URLs           []string             `json:"urls"`
	Configurations []ZoneLockdownConfig `json:"configurations"`
	Paused         bool                 `json:"paused"`
}

// ZoneLockdownUpdateParams contains required and optional params
// for updating a zone lockdown.
type ZoneLockdownUpdateParams struct {
	ID             string               `json:"id"`
	Description    string               `json:"description"`
	URLs           []string             `json:"urls"`
	Configurations []ZoneLockdownConfig `json:"configurations"`
	Paused         bool                 `json:"paused"`
}

type LockdownListParams struct {
	ResultInfo
}

// CreateZoneLockdown creates a Zone ZoneLockdown rule for the given zone ID.
//
// API reference: https://api.cloudflare.com/#zone-ZoneLockdown-create-a-ZoneLockdown-rule
func (api *API) CreateZoneLockdown(ctx context.Context, rc *ResourceContainer, params ZoneLockdownCreateParams) (ZoneLockdown, error) {
	uri := fmt.Sprintf("/zones/%s/firewall/lockdowns", rc.Identifier)
	res, err := api.makeRequestContext(ctx, http.MethodPost, uri, params)
	if err != nil {
		return ZoneLockdown{}, err
	}

	response := &ZoneLockdownResponse{}
	err = json.Unmarshal(res, &response)
	if err != nil {
		return ZoneLockdown{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
	}

	return response.Result, nil
}

// UpdateZoneLockdown updates a Zone ZoneLockdown rule (based on the ID) for the given zone ID.
//
// API reference: https://api.cloudflare.com/#zone-ZoneLockdown-update-ZoneLockdown-rule
func (api *API) UpdateZoneLockdown(ctx context.Context, rc *ResourceContainer, params ZoneLockdownUpdateParams) (ZoneLockdown, error) {
	uri := fmt.Sprintf("/zones/%s/firewall/lockdowns/%s", rc.Identifier, params.ID)
	res, err := api.makeRequestContext(ctx, http.MethodPut, uri, params)
	if err != nil {
		return ZoneLockdown{}, err
	}

	response := &ZoneLockdownResponse{}
	err = json.Unmarshal(res, &response)
	if err != nil {
		return ZoneLockdown{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
	}

	return response.Result, nil
}

// DeleteZoneLockdown deletes a Zone ZoneLockdown rule (based on the ID) for the given zone ID.
//
// API reference: https://api.cloudflare.com/#zone-ZoneLockdown-delete-ZoneLockdown-rule
func (api *API) DeleteZoneLockdown(ctx context.Context, rc *ResourceContainer, id string) (ZoneLockdown, error) {
	uri := fmt.Sprintf("/zones/%s/firewall/lockdowns/%s", rc.Identifier, id)
	res, err := api.makeRequestContext(ctx, http.MethodDelete, uri, nil)
	if err != nil {
		return ZoneLockdown{}, err
	}

	response := &ZoneLockdownResponse{}
	err = json.Unmarshal(res, &response)
	if err != nil {
		return ZoneLockdown{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
	}

	return response.Result, nil
}

// ZoneLockdown retrieves a Zone ZoneLockdown rule (based on the ID) for the given zone ID.
//
// API reference: https://api.cloudflare.com/#zone-ZoneLockdown-ZoneLockdown-rule-details
func (api *API) ZoneLockdown(ctx context.Context, rc *ResourceContainer, id string) (ZoneLockdown, error) {
	uri := fmt.Sprintf("/zones/%s/firewall/lockdowns/%s", rc.Identifier, id)
	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
	if err != nil {
		return ZoneLockdown{}, err
	}

	response := &ZoneLockdownResponse{}
	err = json.Unmarshal(res, &response)
	if err != nil {
		return ZoneLockdown{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
	}

	return response.Result, nil
}

// ListZoneLockdowns retrieves every Zone ZoneLockdown rules for a given zone ID.
//
// Automatically paginates all results unless `params.PerPage` and `params.Page`
// is set.
//
// API reference: https://api.cloudflare.com/#zone-ZoneLockdown-list-ZoneLockdown-rules
func (api *API) ListZoneLockdowns(ctx context.Context, rc *ResourceContainer, params LockdownListParams) ([]ZoneLockdown, *ResultInfo, error) {
	autoPaginate := true
	if params.PerPage >= 1 || params.Page >= 1 {
		autoPaginate = false
	}
	if params.PerPage < 1 {
		params.PerPage = 50
	}
	if params.Page < 1 {
		params.Page = 1
	}

	var zoneLockdowns []ZoneLockdown
	var zResponse ZoneLockdownListResponse
	for {
		uri := buildURI(fmt.Sprintf("/zones/%s/firewall/lockdowns", rc.Identifier), params)

		res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
		if err != nil {
			return []ZoneLockdown{}, &ResultInfo{}, err
		}

		err = json.Unmarshal(res, &zResponse)
		if err != nil {
			return []ZoneLockdown{}, &ResultInfo{}, fmt.Errorf("failed to unmarshal filters JSON data: %w", err)
		}

		zoneLockdowns = append(zoneLockdowns, zResponse.Result...)
		params.ResultInfo = zResponse.ResultInfo.Next()

		if params.ResultInfo.Done() || !autoPaginate {
			break
		}
	}

	return zoneLockdowns, &zResponse.ResultInfo, nil
}
<commit_msg>zone_lockdown: add Priority to ZoneLockdownCreateParams and ZoneLockdownUpdateParams<commit_after>package cloudflare

import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"time"
)

// ZoneLockdown represents a Zone Lockdown rule. A rule only permits access to
// the provided URL pattern(s) from the given IP address(es) or subnet(s).
type ZoneLockdown struct {
	ID             string               `json:"id"`
	Description    string               `json:"description"`
	URLs           []string             `json:"urls"`
	Configurations []ZoneLockdownConfig `json:"configurations"`
	Paused         bool                 `json:"paused"`
	Priority       int                  `json:"priority,omitempty"`
	CreatedOn      *time.Time           `json:"created_on,omitempty"`
	ModifiedOn     *time.Time           `json:"modified_on,omitempty"`
}

// ZoneLockdownConfig represents a Zone Lockdown config, which comprises
// a Target ("ip" or "ip_range") and a Value (an IP address or IP+mask,
// respectively.)
type ZoneLockdownConfig struct {
	Target string `json:"target"`
	Value  string `json:"value"`
}

// ZoneLockdownResponse represents a response from the Zone Lockdown endpoint.
type ZoneLockdownResponse struct {
	Result ZoneLockdown `json:"result"`
	Response
	ResultInfo `json:"result_info"`
}

// ZoneLockdownListResponse represents a response from the List Zone Lockdown
// endpoint.
type ZoneLockdownListResponse struct {
	Result []ZoneLockdown `json:"result"`
	Response
	ResultInfo `json:"result_info"`
}

// ZoneLockdownCreateParams contains required and optional params
// for creating a zone lockdown.
type ZoneLockdownCreateParams struct {
	Description    string               `json:"description"`
	URLs           []string             `json:"urls"`
	Configurations []ZoneLockdownConfig `json:"configurations"`
	Paused         bool                 `json:"paused"`
	Priority       int                  `json:"priority,omitempty"`
}

// ZoneLockdownUpdateParams contains required and optional params
// for updating a zone lockdown.
type ZoneLockdownUpdateParams struct {
	ID             string               `json:"id"`
	Description    string               `json:"description"`
	URLs           []string             `json:"urls"`
	Configurations []ZoneLockdownConfig `json:"configurations"`
	Paused         bool                 `json:"paused"`
	Priority       int                  `json:"priority,omitempty"`
}

type LockdownListParams struct {
	ResultInfo
}

// CreateZoneLockdown creates a Zone ZoneLockdown rule for the given zone ID.
//
// API reference: https://api.cloudflare.com/#zone-ZoneLockdown-create-a-ZoneLockdown-rule
func (api *API) CreateZoneLockdown(ctx context.Context, rc *ResourceContainer, params ZoneLockdownCreateParams) (ZoneLockdown, error) {
	uri := fmt.Sprintf("/zones/%s/firewall/lockdowns", rc.Identifier)
	res, err := api.makeRequestContext(ctx, http.MethodPost, uri, params)
	if err != nil {
		return ZoneLockdown{}, err
	}

	response := &ZoneLockdownResponse{}
	err = json.Unmarshal(res, &response)
	if err != nil {
		return ZoneLockdown{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
	}

	return response.Result, nil
}

// UpdateZoneLockdown updates a Zone ZoneLockdown rule (based on the ID) for the given zone ID.
//
// API reference: https://api.cloudflare.com/#zone-ZoneLockdown-update-ZoneLockdown-rule
func (api *API) UpdateZoneLockdown(ctx context.Context, rc *ResourceContainer, params ZoneLockdownUpdateParams) (ZoneLockdown, error) {
	uri := fmt.Sprintf("/zones/%s/firewall/lockdowns/%s", rc.Identifier, params.ID)
	res, err := api.makeRequestContext(ctx, http.MethodPut, uri, params)
	if err != nil {
		return ZoneLockdown{}, err
	}

	response := &ZoneLockdownResponse{}
	err = json.Unmarshal(res, &response)
	if err != nil {
		return ZoneLockdown{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
	}

	return response.Result, nil
}

// DeleteZoneLockdown deletes a Zone ZoneLockdown rule (based on the ID) for the given zone ID.
//
// API reference: https://api.cloudflare.com/#zone-ZoneLockdown-delete-ZoneLockdown-rule
func (api *API) DeleteZoneLockdown(ctx context.Context, rc *ResourceContainer, id string) (ZoneLockdown, error) {
	uri := fmt.Sprintf("/zones/%s/firewall/lockdowns/%s", rc.Identifier, id)
	res, err := api.makeRequestContext(ctx, http.MethodDelete, uri, nil)
	if err != nil {
		return ZoneLockdown{}, err
	}

	response := &ZoneLockdownResponse{}
	err = json.Unmarshal(res, &response)
	if err != nil {
		return ZoneLockdown{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
	}

	return response.Result, nil
}

// ZoneLockdown retrieves a Zone ZoneLockdown rule (based on the ID) for the given zone ID.
//
// API reference: https://api.cloudflare.com/#zone-ZoneLockdown-ZoneLockdown-rule-details
func (api *API) ZoneLockdown(ctx context.Context, rc *ResourceContainer, id string) (ZoneLockdown, error) {
	uri := fmt.Sprintf("/zones/%s/firewall/lockdowns/%s", rc.Identifier, id)
	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
	if err != nil {
		return ZoneLockdown{}, err
	}

	response := &ZoneLockdownResponse{}
	err = json.Unmarshal(res, &response)
	if err != nil {
		return ZoneLockdown{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
	}

	return response.Result, nil
}

// ListZoneLockdowns retrieves every Zone ZoneLockdown rules for a given zone ID.
//
// Automatically paginates all results unless `params.PerPage` and `params.Page`
// is set.
//
// API reference: https://api.cloudflare.com/#zone-ZoneLockdown-list-ZoneLockdown-rules
func (api *API) ListZoneLockdowns(ctx context.Context, rc *ResourceContainer, params LockdownListParams) ([]ZoneLockdown, *ResultInfo, error) {
	autoPaginate := true
	if params.PerPage >= 1 || params.Page >= 1 {
		autoPaginate = false
	}
	if params.PerPage < 1 {
		params.PerPage = 50
	}
	if params.Page < 1 {
		params.Page = 1
	}

	var zoneLockdowns []ZoneLockdown
	var zResponse ZoneLockdownListResponse
	for {
		uri := buildURI(fmt.Sprintf("/zones/%s/firewall/lockdowns", rc.Identifier), params)

		res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
		if err != nil {
			return []ZoneLockdown{}, &ResultInfo{}, err
		}

		err = json.Unmarshal(res, &zResponse)
		if err != nil {
			return []ZoneLockdown{}, &ResultInfo{}, fmt.Errorf("failed to unmarshal filters JSON data: %w", err)
		}

		zoneLockdowns = append(zoneLockdowns, zResponse.Result...)
		params.ResultInfo = zResponse.ResultInfo.Next()

		if params.ResultInfo.Done() || !autoPaginate {
			break
		}
	}

	return zoneLockdowns, &zResponse.ResultInfo, nil
}
<|endoftext|>


<commit_before>package main

import ("fmt"
	"LogProsjekt/funksjoner"
)

func main() {
	fmt.Println(funksjoner.Log2())

}
<commit_msg>Update main.go<commit_after>package main

import ("fmt"
	"log/funksjoner"
)

func main() {
	fmt.Println(funksjoner.Log2())

}
<|endoftext|>


<commit_before>package colog

import (
	"fmt"
	db "github.com/keks/go-ipfs-colog/immutabledb/ipfs-api"
	"strings"
	"testing"
)

var ipfsdb = db.New()

var id = "abc"
var value1 = "Hello1"
var value2 = "Hello2"
var value3 = "Hello3"
var hash1 = "QmbiruS6UMT6gT3JBHtZNWKitEssyUQzYu8k4gGd6rhzNc"

/* Create */

func TestNew(t *testing.T) {
	var log1 = New(id, ipfsdb)

	if log1 == nil {
		t.Fatalf("Couldn't create a log")
	}

	if log1.Id != id {
		t.Fatalf("Id not set")
	}

	if log1.db == nil {
		t.Fatalf("DB not set")
	}

	if len(log1.Items()) != 0 {
		t.Fatalf("Items not empty")
	}
}

/* Add */

func TestAdd(t *testing.T) {
	var log1 = New(id, ipfsdb)

	one, err := log1.Add(value1)
	if err != nil {
		t.Fatal(err)
	}

	if one == nil {
		t.Fatal("Entry was not added")
	}

	if strings.Compare(string(one.Hash), hash1) != 0 {
		t.Fatalf("Wrong key: %s", one.Hash)
	}

	if strings.Compare(one.GetString(), value1) != 0 {
		t.Fatalf("Wrong key: %s", one.Hash)
	}

	if len(one.Prev) != 1 && one.Prev.Sorted()[0] == "" {
		t.Fatalf("Wrong next reference: %s", one.Prev)
	}

	t.Logf("%#v\n", one)

	if len(log1.Items()) != 1 {
		t.Fatalf("Wrong items count: %d", len(log1.Items()))
	}
}

func ExampleAdd_one() {
	var log1 = New(id, ipfsdb)

	one, err := log1.Add(value1)
	if err != nil {
		panic(err)
	}

	fmt.Println(one.Hash)
	fmt.Println(one.GetString())
	fmt.Println(one.Prev)
	// Output:
	// QmbiruS6UMT6gT3JBHtZNWKitEssyUQzYu8k4gGd6rhzNc
	// Hello1
	// map[:{}]
}

func ExampleAdd_two() {
	var log1 = New(id, ipfsdb)

	log1.Add(value1)
	log1.Add(value2)

	items := log1.Items()
	fmt.Println(len(items))
	fmt.Println(items[1].Hash)
	fmt.Println(string(items[1].GetString()))
	e, err := log1.Get(items[1].Prev.Sorted()[0])
	if err != nil {
		panic(err)
	}

	fmt.Println(e.Hash)
	// Output:
	// 2
	// QmdezppSoeGZmyYQZEuiUTU4cxTqyVfiwBct7D5iosY6zN
	// Hello2
	// QmbiruS6UMT6gT3JBHtZNWKitEssyUQzYu8k4gGd6rhzNc
}

func ExampleAdd_three() {
	var log1 = New(id, ipfsdb)

	log1.Add(value1)
	log1.Add(value2)
	log1.Add(value3)

	items := log1.Items()
	fmt.Println(len(items))
	fmt.Println(string(items[0].GetString()))
	fmt.Println(string(items[1].GetString()))
	fmt.Println(string(items[2].GetString()))
	fmt.Println(items[0].Prev)
	e1, err := log1.Get(items[1].Prev.Sorted()[0])
	if err != nil {
		panic(err)
	}
	fmt.Println(e1.Hash)
	e2, err := log1.Get(items[2].Prev.Sorted()[0])
	if err != nil {
		panic(err)
	}
	fmt.Println(e2.Hash)
	// Output:
	// 3
	// Hello1
	// Hello2
	// Hello3
	// map[:{}]
	// QmbiruS6UMT6gT3JBHtZNWKitEssyUQzYu8k4gGd6rhzNc
	// QmdezppSoeGZmyYQZEuiUTU4cxTqyVfiwBct7D5iosY6zN
}

func BenchmarkAdd(b *testing.B) {
	var log1 = New(id, ipfsdb)

	for i := 0; i < b.N; i++ {
		log1.Add(value1)
	}
}

/* Join */

func TestJoin(t *testing.T) {
	var log1 = New(id, ipfsdb)
	var log2 = New(id, ipfsdb)

	log1.Add(value1)
	log2.Add(value2)

	log1.Join(log2)
	items := log1.Items()

	if len(items) != 2 {
		t.Fatalf("Wrong number of entries: %i", len(items))
	}

	// Make sure the joined log doesn't have pointers to the joined logs
	log1.Add(value1)
	log2.Add(value2)

}

func ExampleJoin_one() {
	var log1 = New(id, ipfsdb)
	var log2 = New(id, ipfsdb)

	log1.Add(value1)
	log2.Add(value2)

	log1.Join(log2)

	items := log1.Items()
	first := items[0]
	second := items[1]

	fmt.Println(len(items))
	fmt.Println(first.Hash)
	fmt.Println(second.Hash)
	fmt.Println(string(first.GetString()))
	fmt.Println(string(second.GetString()))
	// Output:
	// 2
	// QmbiruS6UMT6gT3JBHtZNWKitEssyUQzYu8k4gGd6rhzNc
	// QmXgHKWQEG6NwpqJMvvvBdMrzWqPNo6cLtZr4BpZHFvrXV
	// Hello1
	// Hello2
}

func BenchmarkJoin(b *testing.B) {
	var log1 = New(id, ipfsdb)
	var log2 = New(id, ipfsdb)

	log1.Add(value1)
	log2.Add(value2)

	for i := 0; i < b.N; i++ {
		log1.Join(log2)
	}
}
<commit_msg>update tests to use new string representation<commit_after>package colog

import (
	"fmt"
	db "github.com/keks/go-ipfs-colog/immutabledb/ipfs-api"
	"strings"
	"testing"
)

var ipfsdb = db.New()

var id = "abc"
var value1 = "Hello1"
var value2 = "Hello2"
var value3 = "Hello3"
var hash1 = "QmbiruS6UMT6gT3JBHtZNWKitEssyUQzYu8k4gGd6rhzNc"

/* Create */

func TestNew(t *testing.T) {
	var log1 = New(id, ipfsdb)

	if log1 == nil {
		t.Fatalf("Couldn't create a log")
	}

	if log1.Id != id {
		t.Fatalf("Id not set")
	}

	if log1.db == nil {
		t.Fatalf("DB not set")
	}

	if len(log1.Items()) != 0 {
		t.Fatalf("Items not empty")
	}
}

/* Add */

func TestAdd(t *testing.T) {
	var log1 = New(id, ipfsdb)

	one, err := log1.Add(value1)
	if err != nil {
		t.Fatal(err)
	}

	if one == nil {
		t.Fatal("Entry was not added")
	}

	if strings.Compare(string(one.Hash), hash1) != 0 {
		t.Fatalf("Wrong key: %s", one.Hash)
	}

	if strings.Compare(one.GetString(), value1) != 0 {
		t.Fatalf("Wrong key: %s", one.Hash)
	}

	if len(one.Prev) != 1 && one.Prev.Sorted()[0] == "" {
		t.Fatalf("Wrong next reference: %s", one.Prev)
	}

	t.Logf("%#v\n", one)

	if len(log1.Items()) != 1 {
		t.Fatalf("Wrong items count: %d", len(log1.Items()))
	}
}

func ExampleAdd_one() {
	var log1 = New(id, ipfsdb)

	one, err := log1.Add(value1)
	if err != nil {
		panic(err)
	}

	fmt.Println(one.Hash)
	fmt.Println(one.GetString())
	fmt.Println(one.Prev)
	// Output:
	// QmbiruS6UMT6gT3JBHtZNWKitEssyUQzYu8k4gGd6rhzNc
	// Hello1
	// { null }
}

func ExampleAdd_two() {
	var log1 = New(id, ipfsdb)

	log1.Add(value1)
	log1.Add(value2)

	items := log1.Items()
	fmt.Println(len(items))
	fmt.Println(items[1].Hash)
	fmt.Println(string(items[1].GetString()))
	e, err := log1.Get(items[1].Prev.Sorted()[0])
	if err != nil {
		panic(err)
	}

	fmt.Println(e.Hash)
	// Output:
	// 2
	// QmdezppSoeGZmyYQZEuiUTU4cxTqyVfiwBct7D5iosY6zN
	// Hello2
	// QmbiruS6UMT6gT3JBHtZNWKitEssyUQzYu8k4gGd6rhzNc
}

func ExampleAdd_three() {
	var log1 = New(id, ipfsdb)

	log1.Add(value1)
	log1.Add(value2)
	log1.Add(value3)

	items := log1.Items()
	fmt.Println(len(items))
	fmt.Println(string(items[0].GetString()))
	fmt.Println(string(items[1].GetString()))
	fmt.Println(string(items[2].GetString()))
	fmt.Println(items[0].Prev)
	e1, err := log1.Get(items[1].Prev.Sorted()[0])
	if err != nil {
		panic(err)
	}
	fmt.Println(e1.Hash)
	e2, err := log1.Get(items[2].Prev.Sorted()[0])
	if err != nil {
		panic(err)
	}
	fmt.Println(e2.Hash)
	// Output:
	// 3
	// Hello1
	// Hello2
	// Hello3
	// { null }
	// QmbiruS6UMT6gT3JBHtZNWKitEssyUQzYu8k4gGd6rhzNc
	// QmdezppSoeGZmyYQZEuiUTU4cxTqyVfiwBct7D5iosY6zN
}

func BenchmarkAdd(b *testing.B) {
	var log1 = New(id, ipfsdb)

	for i := 0; i < b.N; i++ {
		log1.Add(value1)
	}
}

/* Join */

func TestJoin(t *testing.T) {
	var log1 = New(id, ipfsdb)
	var log2 = New(id, ipfsdb)

	log1.Add(value1)
	log2.Add(value2)

	log1.Join(log2)
	items := log1.Items()

	if len(items) != 2 {
		t.Fatalf("Wrong number of entries: %i", len(items))
	}

	// Make sure the joined log doesn't have pointers to the joined logs
	log1.Add(value1)
	log2.Add(value2)

}

func ExampleJoin_one() {
	var log1 = New(id, ipfsdb)
	var log2 = New(id, ipfsdb)

	log1.Add(value1)
	log2.Add(value2)

	log1.Join(log2)

	items := log1.Items()
	first := items[0]
	second := items[1]

	fmt.Println(len(items))
	fmt.Println(first.Hash)
	fmt.Println(second.Hash)
	fmt.Println(string(first.GetString()))
	fmt.Println(string(second.GetString()))
	// Output:
	// 2
	// QmbiruS6UMT6gT3JBHtZNWKitEssyUQzYu8k4gGd6rhzNc
	// QmXgHKWQEG6NwpqJMvvvBdMrzWqPNo6cLtZr4BpZHFvrXV
	// Hello1
	// Hello2
}

func BenchmarkJoin(b *testing.B) {
	var log1 = New(id, ipfsdb)
	var log2 = New(id, ipfsdb)

	log1.Add(value1)
	log2.Add(value2)

	for i := 0; i < b.N; i++ {
		log1.Join(log2)
	}
}
<|endoftext|>


<commit_before>package dht

import (
	"bytes"
	"testing"

	context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"

	ds "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/datastore.go"
	ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"

	ci "github.com/jbenet/go-ipfs/crypto"
	spipe "github.com/jbenet/go-ipfs/crypto/spipe"
	inet "github.com/jbenet/go-ipfs/net"
	mux "github.com/jbenet/go-ipfs/net/mux"
	netservice "github.com/jbenet/go-ipfs/net/service"
	peer "github.com/jbenet/go-ipfs/peer"
	u "github.com/jbenet/go-ipfs/util"

	"fmt"
	"time"
)

func setupDHT(t *testing.T, p *peer.Peer) *IpfsDHT {
	ctx := context.Background()

	peerstore := peer.NewPeerstore()

	dhts := netservice.NewService(nil) // nil handler for now, need to patch it
	if err := dhts.Start(ctx); err != nil {
		t.Fatal(err)
	}

	net, err := inet.NewIpfsNetwork(ctx, p, &mux.ProtocolMap{
		mux.ProtocolID_Routing: dhts,
	})
	if err != nil {
		t.Fatal(err)
	}

	d := NewDHT(p, peerstore, net, dhts, ds.NewMapDatastore())
	dhts.Handler = d
	return d
}

func setupDHTS(n int, t *testing.T) ([]*ma.Multiaddr, []*peer.Peer, []*IpfsDHT) {
	var addrs []*ma.Multiaddr
	for i := 0; i < n; i++ {
		a, err := ma.NewMultiaddr(fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", 5000+i))
		if err != nil {
			t.Fatal(err)
		}
		addrs = append(addrs, a)
	}

	var peers []*peer.Peer
	for i := 0; i < n; i++ {
		p := makePeer(addrs[i])
		peers = append(peers, p)
	}

	dhts := make([]*IpfsDHT, n)
	for i := 0; i < n; i++ {
		dhts[i] = setupDHT(t, peers[i])
	}

	return addrs, peers, dhts
}

func makePeer(addr *ma.Multiaddr) *peer.Peer {
	p := new(peer.Peer)
	p.AddAddress(addr)
	sk, pk, err := ci.GenerateKeyPair(ci.RSA, 512)
	if err != nil {
		panic(err)
	}
	p.PrivKey = sk
	p.PubKey = pk
	id, err := spipe.IDFromPubKey(pk)
	if err != nil {
		panic(err)
	}

	p.ID = id
	return p
}

func TestPing(t *testing.T) {
	// t.Skip("skipping test to debug another")

	u.Debug = false
	addrA, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/2222")
	if err != nil {
		t.Fatal(err)
	}
	addrB, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/5678")
	if err != nil {
		t.Fatal(err)
	}

	peerA := makePeer(addrA)
	peerB := makePeer(addrB)

	dhtA := setupDHT(t, peerA)
	dhtB := setupDHT(t, peerB)

	defer dhtA.Halt()
	defer dhtB.Halt()
	defer dhtA.network.Close()
	defer dhtB.network.Close()

	_, err = dhtA.Connect(context.Background(), peerB)
	if err != nil {
		t.Fatal(err)
	}

	//Test that we can ping the node
	ctx, _ := context.WithTimeout(context.Background(), 2*time.Millisecond)
	err = dhtA.Ping(ctx, peerB)
	if err != nil {
		t.Fatal(err)
	}
}

func TestValueGetSet(t *testing.T) {
	// t.Skip("skipping test to debug another")

	u.Debug = false
	addrA, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/1235")
	if err != nil {
		t.Fatal(err)
	}
	addrB, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/5679")
	if err != nil {
		t.Fatal(err)
	}

	peerA := makePeer(addrA)
	peerB := makePeer(addrB)

	dhtA := setupDHT(t, peerA)
	dhtB := setupDHT(t, peerB)

	defer dhtA.Halt()
	defer dhtB.Halt()
	defer dhtA.network.Close()
	defer dhtB.network.Close()

	_, err = dhtA.Connect(context.Background(), peerB)
	if err != nil {
		t.Fatal(err)
	}

	ctxT, _ := context.WithTimeout(context.Background(), time.Second)
	dhtA.PutValue(ctxT, "hello", []byte("world"))

	ctxT, _ = context.WithTimeout(context.Background(), time.Second*2)
	val, err := dhtA.GetValue(ctxT, "hello")
	if err != nil {
		t.Fatal(err)
	}

	if string(val) != "world" {
		t.Fatalf("Expected 'world' got '%s'", string(val))
	}

}

func TestProvides(t *testing.T) {
	// t.Skip("skipping test to debug another")

	u.Debug = false

	_, peers, dhts := setupDHTS(4, t)
	defer func() {
		for i := 0; i < 4; i++ {
			dhts[i].Halt()
			defer dhts[i].network.Close()
		}
	}()

	_, err := dhts[0].Connect(context.Background(), peers[1])
	if err != nil {
		t.Fatal(err)
	}

	_, err = dhts[1].Connect(context.Background(), peers[2])
	if err != nil {
		t.Fatal(err)
	}

	_, err = dhts[1].Connect(context.Background(), peers[3])
	if err != nil {
		t.Fatal(err)
	}

	err = dhts[3].putLocal(u.Key("hello"), []byte("world"))
	if err != nil {
		t.Fatal(err)
	}

	bits, err := dhts[3].getLocal(u.Key("hello"))
	if err != nil && bytes.Equal(bits, []byte("world")) {
		t.Fatal(err)
	}

	err = dhts[3].Provide(context.Background(), u.Key("hello"))
	if err != nil {
		t.Fatal(err)
	}

	time.Sleep(time.Millisecond * 60)

	ctxT, _ := context.WithTimeout(context.Background(), time.Second)
	provs, err := dhts[0].FindProviders(ctxT, u.Key("hello"))
	if err != nil {
		t.Fatal(err)
	}

	if len(provs) != 1 {
		t.Fatal("Didnt get back providers")
	}
}

func TestProvidesAsync(t *testing.T) {
	// t.Skip("skipping test to debug another")

	u.Debug = false

	_, peers, dhts := setupDHTS(4, t)
	defer func() {
		for i := 0; i < 4; i++ {
			dhts[i].Halt()
			defer dhts[i].network.Close()
		}
	}()

	_, err := dhts[0].Connect(context.Background(), peers[1])
	if err != nil {
		t.Fatal(err)
	}

	_, err = dhts[1].Connect(context.Background(), peers[2])
	if err != nil {
		t.Fatal(err)
	}

	_, err = dhts[1].Connect(context.Background(), peers[3])
	if err != nil {
		t.Fatal(err)
	}

	err = dhts[3].putLocal(u.Key("hello"), []byte("world"))
	if err != nil {
		t.Fatal(err)
	}

	bits, err := dhts[3].getLocal(u.Key("hello"))
	if err != nil && bytes.Equal(bits, []byte("world")) {
		t.Fatal(err)
	}

	err = dhts[3].Provide(context.Background(), u.Key("hello"))
	if err != nil {
		t.Fatal(err)
	}

	time.Sleep(time.Millisecond * 60)

	ctx, _ := context.WithTimeout(context.TODO(), time.Millisecond*300)
	provs := dhts[0].FindProvidersAsync(ctx, u.Key("hello"), 5)
	select {
	case p := <-provs:
		if !p.ID.Equal(dhts[3].self.ID) {
			t.Fatalf("got a provider, but not the right one. %v", p.ID.Pretty())
		}
	case <-ctx.Done():
		t.Fatal("Didnt get back providers")
	}
}

func TestLayeredGet(t *testing.T) {
	// t.Skip("skipping test to debug another")

	u.Debug = false
	_, peers, dhts := setupDHTS(4, t)
	defer func() {
		for i := 0; i < 4; i++ {
			dhts[i].Halt()
			defer dhts[i].network.Close()
		}
	}()

	_, err := dhts[0].Connect(context.Background(), peers[1])
	if err != nil {
		t.Fatalf("Failed to connect: %s", err)
	}

	_, err = dhts[1].Connect(context.Background(), peers[2])
	if err != nil {
		t.Fatal(err)
	}

	_, err = dhts[1].Connect(context.Background(), peers[3])
	if err != nil {
		t.Fatal(err)
	}

	err = dhts[3].putLocal(u.Key("hello"), []byte("world"))
	if err != nil {
		t.Fatal(err)
	}

	err = dhts[3].Provide(context.Background(), u.Key("hello"))
	if err != nil {
		t.Fatal(err)
	}

	time.Sleep(time.Millisecond * 60)

	ctxT, _ := context.WithTimeout(context.Background(), time.Second)
	val, err := dhts[0].GetValue(ctxT, u.Key("hello"))
	if err != nil {
		t.Fatal(err)
	}

	if string(val) != "world" {
		t.Fatal("Got incorrect value.")
	}

}

func TestFindPeer(t *testing.T) {
	// t.Skip("skipping test to debug another")

	u.Debug = false

	_, peers, dhts := setupDHTS(4, t)
	defer func() {
		for i := 0; i < 4; i++ {
			dhts[i].Halt()
			dhts[i].network.Close()
		}
	}()

	_, err := dhts[0].Connect(context.Background(), peers[1])
	if err != nil {
		t.Fatal(err)
	}

	_, err = dhts[1].Connect(context.Background(), peers[2])
	if err != nil {
		t.Fatal(err)
	}

	_, err = dhts[1].Connect(context.Background(), peers[3])
	if err != nil {
		t.Fatal(err)
	}

	ctxT, _ := context.WithTimeout(context.Background(), time.Second)
	p, err := dhts[0].FindPeer(ctxT, peers[2].ID)
	if err != nil {
		t.Fatal(err)
	}

	if p == nil {
		t.Fatal("Failed to find peer.")
	}

	if !p.ID.Equal(peers[2].ID) {
		t.Fatal("Didnt find expected peer.")
	}
}
<commit_msg>make a few tests perform operations in two directions instead of one<commit_after>package dht

import (
	"bytes"
	"testing"

	context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"

	ds "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/datastore.go"
	ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"

	ci "github.com/jbenet/go-ipfs/crypto"
	spipe "github.com/jbenet/go-ipfs/crypto/spipe"
	inet "github.com/jbenet/go-ipfs/net"
	mux "github.com/jbenet/go-ipfs/net/mux"
	netservice "github.com/jbenet/go-ipfs/net/service"
	peer "github.com/jbenet/go-ipfs/peer"
	u "github.com/jbenet/go-ipfs/util"

	"fmt"
	"time"
)

func setupDHT(t *testing.T, p *peer.Peer) *IpfsDHT {
	ctx := context.Background()

	peerstore := peer.NewPeerstore()

	dhts := netservice.NewService(nil) // nil handler for now, need to patch it
	if err := dhts.Start(ctx); err != nil {
		t.Fatal(err)
	}

	net, err := inet.NewIpfsNetwork(ctx, p, &mux.ProtocolMap{
		mux.ProtocolID_Routing: dhts,
	})
	if err != nil {
		t.Fatal(err)
	}

	d := NewDHT(p, peerstore, net, dhts, ds.NewMapDatastore())
	dhts.Handler = d
	return d
}

func setupDHTS(n int, t *testing.T) ([]*ma.Multiaddr, []*peer.Peer, []*IpfsDHT) {
	var addrs []*ma.Multiaddr
	for i := 0; i < n; i++ {
		a, err := ma.NewMultiaddr(fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", 5000+i))
		if err != nil {
			t.Fatal(err)
		}
		addrs = append(addrs, a)
	}

	var peers []*peer.Peer
	for i := 0; i < n; i++ {
		p := makePeer(addrs[i])
		peers = append(peers, p)
	}

	dhts := make([]*IpfsDHT, n)
	for i := 0; i < n; i++ {
		dhts[i] = setupDHT(t, peers[i])
	}

	return addrs, peers, dhts
}

func makePeer(addr *ma.Multiaddr) *peer.Peer {
	p := new(peer.Peer)
	p.AddAddress(addr)
	sk, pk, err := ci.GenerateKeyPair(ci.RSA, 512)
	if err != nil {
		panic(err)
	}
	p.PrivKey = sk
	p.PubKey = pk
	id, err := spipe.IDFromPubKey(pk)
	if err != nil {
		panic(err)
	}

	p.ID = id
	return p
}

func TestPing(t *testing.T) {
	// t.Skip("skipping test to debug another")

	u.Debug = false
	addrA, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/2222")
	if err != nil {
		t.Fatal(err)
	}
	addrB, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/5678")
	if err != nil {
		t.Fatal(err)
	}

	peerA := makePeer(addrA)
	peerB := makePeer(addrB)

	dhtA := setupDHT(t, peerA)
	dhtB := setupDHT(t, peerB)

	defer dhtA.Halt()
	defer dhtB.Halt()
	defer dhtA.network.Close()
	defer dhtB.network.Close()

	_, err = dhtA.Connect(context.Background(), peerB)
	if err != nil {
		t.Fatal(err)
	}

	//Test that we can ping the node
	ctx, _ := context.WithTimeout(context.Background(), 5*time.Millisecond)
	err = dhtA.Ping(ctx, peerB)
	if err != nil {
		t.Fatal(err)
	}

	ctx, _ = context.WithTimeout(context.Background(), 5*time.Millisecond)
	err = dhtB.Ping(ctx, peerA)
	if err != nil {
		t.Fatal(err)
	}
}

func TestValueGetSet(t *testing.T) {
	// t.Skip("skipping test to debug another")

	u.Debug = false
	addrA, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/1235")
	if err != nil {
		t.Fatal(err)
	}
	addrB, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/5679")
	if err != nil {
		t.Fatal(err)
	}

	peerA := makePeer(addrA)
	peerB := makePeer(addrB)

	dhtA := setupDHT(t, peerA)
	dhtB := setupDHT(t, peerB)

	defer dhtA.Halt()
	defer dhtB.Halt()
	defer dhtA.network.Close()
	defer dhtB.network.Close()

	_, err = dhtA.Connect(context.Background(), peerB)
	if err != nil {
		t.Fatal(err)
	}

	ctxT, _ := context.WithTimeout(context.Background(), time.Second)
	dhtA.PutValue(ctxT, "hello", []byte("world"))

	ctxT, _ = context.WithTimeout(context.Background(), time.Second*2)
	val, err := dhtA.GetValue(ctxT, "hello")
	if err != nil {
		t.Fatal(err)
	}

	if string(val) != "world" {
		t.Fatalf("Expected 'world' got '%s'", string(val))
	}

	ctxT, _ = context.WithTimeout(context.Background(), time.Second*2)
	val, err = dhtB.GetValue(ctxT, "hello")
	if err != nil {
		t.Fatal(err)
	}

	if string(val) != "world" {
		t.Fatalf("Expected 'world' got '%s'", string(val))
	}
}

func TestProvides(t *testing.T) {
	// t.Skip("skipping test to debug another")

	u.Debug = false

	_, peers, dhts := setupDHTS(4, t)
	defer func() {
		for i := 0; i < 4; i++ {
			dhts[i].Halt()
			defer dhts[i].network.Close()
		}
	}()

	_, err := dhts[0].Connect(context.Background(), peers[1])
	if err != nil {
		t.Fatal(err)
	}

	_, err = dhts[1].Connect(context.Background(), peers[2])
	if err != nil {
		t.Fatal(err)
	}

	_, err = dhts[1].Connect(context.Background(), peers[3])
	if err != nil {
		t.Fatal(err)
	}

	err = dhts[3].putLocal(u.Key("hello"), []byte("world"))
	if err != nil {
		t.Fatal(err)
	}

	bits, err := dhts[3].getLocal(u.Key("hello"))
	if err != nil && bytes.Equal(bits, []byte("world")) {
		t.Fatal(err)
	}

	err = dhts[3].Provide(context.Background(), u.Key("hello"))
	if err != nil {
		t.Fatal(err)
	}

	time.Sleep(time.Millisecond * 60)

	ctxT, _ := context.WithTimeout(context.Background(), time.Second)
	provs, err := dhts[0].FindProviders(ctxT, u.Key("hello"))
	if err != nil {
		t.Fatal(err)
	}

	if len(provs) != 1 {
		t.Fatal("Didnt get back providers")
	}
}

func TestProvidesAsync(t *testing.T) {
	// t.Skip("skipping test to debug another")

	u.Debug = false

	_, peers, dhts := setupDHTS(4, t)
	defer func() {
		for i := 0; i < 4; i++ {
			dhts[i].Halt()
			defer dhts[i].network.Close()
		}
	}()

	_, err := dhts[0].Connect(context.Background(), peers[1])
	if err != nil {
		t.Fatal(err)
	}

	_, err = dhts[1].Connect(context.Background(), peers[2])
	if err != nil {
		t.Fatal(err)
	}

	_, err = dhts[1].Connect(context.Background(), peers[3])
	if err != nil {
		t.Fatal(err)
	}

	err = dhts[3].putLocal(u.Key("hello"), []byte("world"))
	if err != nil {
		t.Fatal(err)
	}

	bits, err := dhts[3].getLocal(u.Key("hello"))
	if err != nil && bytes.Equal(bits, []byte("world")) {
		t.Fatal(err)
	}

	err = dhts[3].Provide(context.Background(), u.Key("hello"))
	if err != nil {
		t.Fatal(err)
	}

	time.Sleep(time.Millisecond * 60)

	ctx, _ := context.WithTimeout(context.TODO(), time.Millisecond*300)
	provs := dhts[0].FindProvidersAsync(ctx, u.Key("hello"), 5)
	select {
	case p := <-provs:
		if !p.ID.Equal(dhts[3].self.ID) {
			t.Fatalf("got a provider, but not the right one. %v", p.ID.Pretty())
		}
	case <-ctx.Done():
		t.Fatal("Didnt get back providers")
	}
}

func TestLayeredGet(t *testing.T) {
	// t.Skip("skipping test to debug another")

	u.Debug = false
	_, peers, dhts := setupDHTS(4, t)
	defer func() {
		for i := 0; i < 4; i++ {
			dhts[i].Halt()
			defer dhts[i].network.Close()
		}
	}()

	_, err := dhts[0].Connect(context.Background(), peers[1])
	if err != nil {
		t.Fatalf("Failed to connect: %s", err)
	}

	_, err = dhts[1].Connect(context.Background(), peers[2])
	if err != nil {
		t.Fatal(err)
	}

	_, err = dhts[1].Connect(context.Background(), peers[3])
	if err != nil {
		t.Fatal(err)
	}

	err = dhts[3].putLocal(u.Key("hello"), []byte("world"))
	if err != nil {
		t.Fatal(err)
	}

	err = dhts[3].Provide(context.Background(), u.Key("hello"))
	if err != nil {
		t.Fatal(err)
	}

	time.Sleep(time.Millisecond * 60)

	ctxT, _ := context.WithTimeout(context.Background(), time.Second)
	val, err := dhts[0].GetValue(ctxT, u.Key("hello"))
	if err != nil {
		t.Fatal(err)
	}

	if string(val) != "world" {
		t.Fatal("Got incorrect value.")
	}

}

func TestFindPeer(t *testing.T) {
	// t.Skip("skipping test to debug another")

	u.Debug = false

	_, peers, dhts := setupDHTS(4, t)
	defer func() {
		for i := 0; i < 4; i++ {
			dhts[i].Halt()
			dhts[i].network.Close()
		}
	}()

	_, err := dhts[0].Connect(context.Background(), peers[1])
	if err != nil {
		t.Fatal(err)
	}

	_, err = dhts[1].Connect(context.Background(), peers[2])
	if err != nil {
		t.Fatal(err)
	}

	_, err = dhts[1].Connect(context.Background(), peers[3])
	if err != nil {
		t.Fatal(err)
	}

	ctxT, _ := context.WithTimeout(context.Background(), time.Second)
	p, err := dhts[0].FindPeer(ctxT, peers[2].ID)
	if err != nil {
		t.Fatal(err)
	}

	if p == nil {
		t.Fatal("Failed to find peer.")
	}

	if !p.ID.Equal(peers[2].ID) {
		t.Fatal("Didnt find expected peer.")
	}
}
<|endoftext|>