예제 #1
0
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
}
예제 #2
0
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
}
예제 #3
0
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)
	}
}
예제 #4
0
// 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
		}
	}
}
예제 #5
0
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 = &timestamp
				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
}