func (a *Percentiles) Set(s string) error { f, err := strconv.ParseFloat(s, 64) if err != nil { return spew.Errorf("%d %v: '%#v'", getCaller(), err, s) } *a = append(*a, &Percentile{f, strings.Replace(s, ".", "_", -1)}) return nil }
func testMigrate(tt migrateTest) error { dir, err := ioutil.TempDir("", tstprefix) if err != nil { return fmt.Errorf("error creating tempdir: %v", err) } defer os.RemoveAll(dir) storeDir := filepath.Join(dir, "store") db, err := db.NewDB(filepath.Join(storeDir, "db")) if err != nil { return err } if err = tt.predb.populate(db); err != nil { return err } fn := func(tx *sql.Tx) error { err := migrate(tx, tt.postdb.version()) if err != nil { return err } return nil } if err = db.Do(fn); err != nil { return err } var curDBVersion int fn = func(tx *sql.Tx) error { var err error curDBVersion, err = getDBVersion(tx) if err != nil { return err } return nil } if err = db.Do(fn); err != nil { return err } if curDBVersion != tt.postdb.version() { return fmt.Errorf("wrong db version: got %#v, want %#v", curDBVersion, tt.postdb.version()) } if err := tt.curdb.load(db); err != nil { return err } if !tt.curdb.compare(tt.postdb) { return spew.Errorf("while comparing DBs:\n\tgot %#v\n\twant %#v\n", tt.curdb, tt.postdb) } return nil }
func main() { protoDir, outFile := os.Args[1], os.Args[2] fset := &token.FileSet{} pkgs, err := parser.ParseDir(fset, protoDir, nil, 0) if err != nil { panic(err) } enums := []*EnumMap{ &EnumMap{Hook: "DEM", Struct: "CDemo", Enum: "EDemoCommands", Fill: "_DEM_"}, &EnumMap{Hook: "NET", Struct: "CNETMsg_", Enum: "NET_Messages", Fill: "_net_"}, &EnumMap{Hook: "SVC", Struct: "CSVCMsg_", Enum: "SVC_Messages", Fill: "_svc_"}, &EnumMap{Hook: "BUM", Struct: "CUserMessage", Enum: "EBaseUserMessages", Fill: "_UM_"}, &EnumMap{Hook: "BEM", Struct: "CEntityMessage", Enum: "EBaseEntityMessages", Fill: "_EM_"}, &EnumMap{Hook: "BGE", Struct: "CMsg", Enum: "EBaseGameEvents", Fill: "_GE_"}, &EnumMap{Hook: "DUM", Struct: "CDOTAUserMsg_", Enum: "EDotaUserMessages", Fill: "_DOTA_UM_"}, } for _, enum := range enums { enum.EnumNames = []string{} enum.StructNames = []string{} enum.Values = map[string]int{} } for _, pkg := range pkgs { for _, file := range pkg.Files { for _, iDecl := range file.Decls { switch decl := iDecl.(type) { case *ast.GenDecl: for _, iSpec := range decl.Specs { switch spec := iSpec.(type) { case *ast.ValueSpec: switch valueSpecType := spec.Type.(type) { case *ast.Ident: for _, enum := range enums { if enum.Enum == valueSpecType.String() { var eValue int for _, iValue := range spec.Values { switch value := iValue.(type) { case *ast.BasicLit: if value.Kind == token.INT { eValue, _ = strconv.Atoi(value.Value) } else { panic(spew.Errorf("%v", value)) } case *ast.UnaryExpr: switch value.Op { case token.SUB: switch x := value.X.(type) { case *ast.BasicLit: if x.Kind == token.INT { i, _ := strconv.Atoi(x.Value) eValue = -i } else { panic(spew.Errorf("-%v", x)) } } default: pp(spec) panic("not SUB") } default: pp(spec) panic("not basic lit") } } for _, name := range spec.Names { enum.EnumNames = append(enum.EnumNames, name.String()) enum.Values[name.String()] = eValue } } } } case *ast.TypeSpec: name := spec.Name.String() for _, enum := range enums { if strings.HasPrefix(name, enum.Struct) { enum.StructNames = append(enum.StructNames, name) } } } } } } } } file := bytes.NewBufferString(spew.Sprintf( `//go:generate go run gen/message_lookup.go %s %s package manta import ( "fmt" "github.com/dotabuff/manta/dota" "github.com/golang/protobuf/proto" ) `, protoDir, outFile)) values := map[int]string{} rawMsg := []string{} switches := []string{} demSwitches := []string{} onFns := []string{} onFnNames := make(map[string]bool) packetTypeIds := make([]int, 0) packetTypeNames := make(map[int]string) for _, enum := range enums { slice.SortTyped(&enum.EnumNames, func(a, b string) bool { return enum.Values[a] < enum.Values[b] }) for _, e := range enum.EnumNames { matching := "" for _, name := range enum.StructNames { if name[len(enum.Struct):] == e[len(enum.Enum)+len(enum.Fill):] { matching = name break } } if matching == "" { switch e { case "EDotaUserMessages_DOTA_UM_AddUnitToSelection", "EDotaUserMessages_DOTA_UM_CombatLogData", "EDotaUserMessages_DOTA_UM_CharacterSpeakConcept", "EDotaUserMessages_DOTA_UM_TournamentDrop", "EBaseUserMessages_UM_MAX_BASE": continue case "EDemoCommands_DEM_Error", "EDemoCommands_DEM_Max", "EDemoCommands_DEM_IsCompressed": continue case "EDemoCommands_DEM_SignonPacket": matching = "CDemoPacket" default: //pp(e) } } if enum.Hook != "DEM" { if prev, found := values[enum.Values[e]]; found { pp(matching, e, prev, enum.Values[e]) panic("dupe") } else { values[enum.Values[e]] = e } if _, ok := packetTypeNames[enum.Values[e]]; !ok { packetTypeIds = append(packetTypeIds, enum.Values[e]) packetTypeNames[enum.Values[e]] = e } else { spew.Printf("duplicate enum %d: have %s, new %s\n", enum.Values[e], packetTypeNames[enum.Values[e]], e) } } if matching == "" { spew.Printf("WARN: no matching enum found for %s (%d)\n", e, enum.Values[e]) continue } cbType := "dota." + matching cbEnt := "on" + matching cbName := "On" + matching switch e { case "EDemoCommands_DEM_SignonPacket": cbEnt = "onCDemoSignonPacket" cbName = "OnCDemoSignonPacket" } fnsig := spew.Sprintf("func (*%s) error", cbType) swtch := spew.Sprintf( `case %d: // dota.%s if cbs := callbacks.%s; cbs != nil { msg := &%s{} if err := proto.Unmarshal(raw, msg); err != nil { return err } for _, fn := range cbs { if err := fn(msg); err != nil { return err } } } return nil`, enum.Values[e], e, cbEnt, cbType) onfn := spew.Sprintf( `func (c *Callbacks) %s(fn %s) { if c.%s == nil { c.%s = make([]%s, 0) } c.%s = append(c.%s, fn) }`, cbName, fnsig, cbEnt, cbEnt, fnsig, cbEnt, cbEnt) if enum.Hook == "DEM" { demSwitches = append(demSwitches, swtch) } else { switches = append(switches, swtch) } rawMsg = append(rawMsg, spew.Sprintf(`%s []%s`, cbEnt, fnsig)) if _, ok := onFnNames[matching]; !ok { onFnNames[cbName] = true onFns = append(onFns, onfn) } } } file.WriteString(spew.Sprintf("var packetNames = map[int32]string{\n")) sort.Ints(packetTypeIds) for _, id := range packetTypeIds { name := packetTypeNames[id] file.WriteString(spew.Sprintf("\t%d: \"%s\",\n", id, name)) } file.WriteString(spew.Sprintf("}\n")) file.WriteString(spew.Sprintf(` type Callbacks struct { %s } `, strings.Join(rawMsg, "\n"))) callTemplate := ` func (p *Parser) %s(t int32, raw []byte) (error) { callbacks := p.Callbacks switch t { %s } return fmt.Errorf("no type found: %%d", t) } ` file.WriteString(strings.Join(onFns, "\n")) file.WriteString(spew.Sprintf(callTemplate, "CallByDemoType", strings.Join(demSwitches, "\n"))) file.WriteString(spew.Sprintf(callTemplate, "CallByPacketType", strings.Join(switches, "\n"))) source, err := format.Source(file.Bytes()) if err != nil { spew.Println(file.String()) panic(err) } err = ioutil.WriteFile(outFile, source, 0644) if err != nil { panic(err) } }
// TestSpew executes all of the tests described by spewTests. func TestSpew(t *testing.T) { initSpewTests() t.Logf("Running %d tests", len(spewTests)) for i, test := range spewTests { buf := new(bytes.Buffer) switch test.f { case fCSFdump: test.cs.Fdump(buf, test.in) case fCSFprint: test.cs.Fprint(buf, test.in) case fCSFprintf: test.cs.Fprintf(buf, test.format, test.in) case fCSFprintln: test.cs.Fprintln(buf, test.in) case fCSPrint: b, err := redirStdout(func() { test.cs.Print(test.in) }) if err != nil { t.Errorf("%v #%d %v", test.f, i, err) continue } buf.Write(b) case fCSPrintln: b, err := redirStdout(func() { test.cs.Println(test.in) }) if err != nil { t.Errorf("%v #%d %v", test.f, i, err) continue } buf.Write(b) case fCSSdump: str := test.cs.Sdump(test.in) buf.WriteString(str) case fCSSprint: str := test.cs.Sprint(test.in) buf.WriteString(str) case fCSSprintf: str := test.cs.Sprintf(test.format, test.in) buf.WriteString(str) case fCSSprintln: str := test.cs.Sprintln(test.in) buf.WriteString(str) case fCSErrorf: err := test.cs.Errorf(test.format, test.in) buf.WriteString(err.Error()) case fCSNewFormatter: fmt.Fprintf(buf, test.format, test.cs.NewFormatter(test.in)) case fErrorf: err := spew.Errorf(test.format, test.in) buf.WriteString(err.Error()) case fFprint: spew.Fprint(buf, test.in) case fFprintln: spew.Fprintln(buf, test.in) case fPrint: b, err := redirStdout(func() { spew.Print(test.in) }) if err != nil { t.Errorf("%v #%d %v", test.f, i, err) continue } buf.Write(b) case fPrintln: b, err := redirStdout(func() { spew.Println(test.in) }) if err != nil { t.Errorf("%v #%d %v", test.f, i, err) continue } buf.Write(b) case fSdump: str := spew.Sdump(test.in) buf.WriteString(str) case fSprint: str := spew.Sprint(test.in) buf.WriteString(str) case fSprintf: str := spew.Sprintf(test.format, test.in) buf.WriteString(str) case fSprintln: str := spew.Sprintln(test.in) buf.WriteString(str) default: t.Errorf("%v #%d unrecognized function", test.f, i) continue } s := buf.String() if test.want != s { t.Errorf("ConfigState #%d\n got: %s want: %s", i, s, test.want) continue } } }
func submit(deadline time.Time) error { var buffer bytes.Buffer var num int64 now := time.Now().Unix() num += processCounters(&buffer, now) num += processGauges(&buffer, now) num += processTimers(&buffer, now, percentThreshold) if *graphiteAddress != "-" { client, err := net.Dial("tcp", *graphiteAddress) if err != nil { if *debug { log.Printf("WARNING: resetting counters when in debug mode") processCounters(&buffer, now) processGauges(&buffer, now) processTimers(&buffer, now, percentThreshold) } return spew.Errorf("dialing %s failed - %s", *graphiteAddress, err) } defer client.Close() err = client.SetDeadline(deadline) if err != nil { return spew.Errorf("could not set deadline: %v", err) } if num == 0 { return nil } if *debug { for _, line := range bytes.Split(buffer.Bytes(), []byte("\n")) { if len(line) == 0 { continue } log.Printf("DEBUG: %s", line) } } _, err = client.Write(buffer.Bytes()) if err != nil { return spew.Errorf("failed to write stats - %s", err) } log.Printf("sent %d stats to %s", num, *graphiteAddress) } if *openTSDBAddress != "-" { datapoints := []tsdb.DataPoint{} TSDB := tsdb.TSDB{} server := tsdb.Server{} serverAdress := strings.Split(*openTSDBAddress, ":") if len(serverAdress) != 2 { return spew.Errorf("Error: Incorrect openTSDB server address") } port, err := strconv.ParseUint(serverAdress[1], 10, 32) if err != nil { return spew.Errorf("%d %v: '%#v'", getCaller(), err, serverAdress[1]) } server.Host = serverAdress[0] server.Port = uint(port) TSDB.Servers = append(TSDB.Servers, server) metrics := strings.Split(buffer.String(), "\n") for _, mtr := range metrics { data := strings.Split(mtr, " ") if len(data) == 3 { metric := tsdb.Metric{} value := tsdb.Value{} tags := tsdb.Tags{} timestamp := tsdb.Time{} datapoint := tsdb.DataPoint{} val, err := strconv.ParseFloat(data[1], 64) if err != nil { return spew.Errorf("%d %v: '%#v'", getCaller(), err, data[1]) } value.Set(val) err = timestamp.Parse(data[2]) if err != nil { return spew.Errorf("%d %v: '%#v'", getCaller(), err, data[2]) } metricAndTags := strings.Split(data[0], "?") if metricAndTags[0] != data[0] { err = metric.Set(metricAndTags[0]) if err != nil { return spew.Errorf("%d %v: '%#v'", getCaller(), err, metricAndTags[0]) } for _, tagVal := range strings.Split(metricAndTags[1], "&") { arrTagVal := strings.Split(tagVal, "=") if len(arrTagVal) != 2 { return spew.Errorf("Error: Incorrect metric format %s: '%s'", "tagVal", tagVal) } tags.Set(arrTagVal[0], arrTagVal[1]) } } else { metricAndTags := strings.Split(data[0], "._t_") if len(metricAndTags) != 2 { return spew.Errorf("Error: Incorrect metric format %s: '%s'", "data[0]", data[0]) } err = metric.Set(metricAndTags[0]) if err != nil { return spew.Errorf("%v : '%#v'", err, metricAndTags[0]) } arrTagVal := strings.Split(metricAndTags[1], ".") if len(arrTagVal) != 2 { return spew.Errorf("Error: Incorrect metric format %s: '%s'", "metricAndTags[1]", metricAndTags[1]) } tags.Set(arrTagVal[0], arrTagVal[1]) } datapoint.Value = &value datapoint.Metric = &metric datapoint.Tags = &tags datapoint.Timestamp = ×tamp datapoints = append(datapoints, datapoint) if len(datapoints) > 10 { _, err = TSDB.Put(datapoints) if err != nil { return spew.Errorf("%d %v: '%#v'", getCaller(), err, datapoints) } datapoints = []tsdb.DataPoint{} } } } if len(datapoints) > 0 { _, err = TSDB.Put(datapoints) if err != nil { return spew.Errorf("%d %v: '%#v'", getCaller(), err, datapoints) } } log.Printf("sent %d stats to %s", num, *openTSDBAddress) } return nil }