Ejemplo n.º 1
0
func HTTPUnitHiera(filename string, freq time.Duration) error {
	plans, err := httpunit.ExtractHiera(filename)
	if err != nil {
		return err
	}
	HTTPUnitPlans(filename, &httpunit.Plans{Plans: plans}, freq)
	return nil
}
Ejemplo n.º 2
0
func main() {
	flag.Parse()
	if *verbose2 {
		*verbose1 = true
	}
	plans := &httpunit.Plans{
		IPs: make(httpunit.IPMap),
	}
	var err error
	if *timeout > 0 {
		httpunit.Timeout = *timeout
	}
	if *tomlLoc != "" {
		if _, err := toml.DecodeFile(*tomlLoc, &plans); err != nil {
			log.Fatal(err)
		}
	}
	if *hiera != "" {
		p, err := httpunit.ExtractHiera(*hiera)
		plans.Plans = append(plans.Plans, p...)
		if err != nil {
			log.Fatal(err)
		}
	}
	if args := flag.Args(); len(args) > 0 {
		if plans.Plans != nil {
			log.Fatal("cannot manually specify URLs with other modes")
		}
		u := args[0]
		args = args[1:]
		tp := httpunit.TestPlan{
			Label: u,
		}
		if !strings.Contains(u, "://") {
			u = "http://" + u
		}
		tp.URL = u
		if len(args) > 0 {
			if args[0] != "" {
				tp.IPs = []string{args[0]}
			}
			args = args[1:]
		}
		if len(args) > 0 {
			code, err := strconv.Atoi(args[0])
			if err != nil {
				log.Fatalf("bad status code: %v: %v", args[0], err)
			}
			args = args[1:]
			tp.Code = code
		}
		if len(args) > 0 {
			_, err := regexp.Compile(args[0])
			if err != nil {
				log.Fatalf("bad regex: %v: %v", args[0], err)
			}
			tp.Regex = args[0]
			args = args[1:]
		}
		if len(args) > 0 {
			log.Fatalf("too many arguments")
		}
		plans.Plans = []*httpunit.TestPlan{&tp}
	}
	if *ipMap != "" {
		sp := strings.SplitN(*ipMap, "=", 2)
		if len(sp) != 2 {
			log.Fatalf("expected key=value in -ipmap")
		}
		var vals []string
		if err := json.Unmarshal([]byte(sp[1]), &vals); err != nil {
			log.Fatalf("ipmap: %v", err)
		}
		plans.IPs[sp[0]] = vals
	}
	if len(plans.Plans) == 0 {
		log.Fatalf("no tests specified")
	}
	rch, count, err := plans.Test(*filter, *no10)
	if err != nil {
		log.Fatal(err)
	}
	var res httpunit.Results
	delay := time.Second / 2
	next := time.After(delay)
	got := 0
	start := time.Now()

Loop:
	for {
		select {
		case <-next:
			fmt.Fprintf(os.Stderr, "%v of %v done in %v\n", got, count, time.Since(start))
			next = time.After(delay)
		case r, ok := <-rch:
			if !ok {
				fmt.Fprintf(os.Stderr, "%v of %v done in %v\n", got, count, time.Since(start))
				break Loop
			}
			res = append(res, r)
			got++
		}
	}

	pidx := make(map[*httpunit.TestPlan]int)
	for i, p := range plans.Plans {
		pidx[p] = i
	}
	slice.Sort(res, func(i, j int) bool {
		a := res[i].Plan
		b := res[j].Plan
		pa := pidx[a]
		pb := pidx[b]
		if pa != pb {
			return pa < pb
		}
		ai := res[i].Case.IP
		bi := res[j].Case.IP
		if len(ai) != len(bi) {
			return len(ai) < len(bi)
		}
		for k, v := range ai {
			if bi[k] != v {
				return ai[k] < bi[k]
			}
		}
		return false
	})
	for _, r := range res {
		fromDNS := "IP"
		if r.Case.FromDNS {
			fromDNS = "DNS"
		}
		ip := fmt.Sprintf("%v=%v", fromDNS, r.Case.IP)
		var status, verbose string
		if r.Case.ExpectCode > 0 {
			status += fmt.Sprint(r.Case.ExpectCode)
		}
		if r.Case.ExpectText != "" {
			status += " T"
		}
		if r.Case.ExpectRegex != nil {
			status += " R"
		}
		if status != "" {
			status = " (" + status + ")"
		}
		if !*verbose1 && r.Result.Result == nil {
			continue
		}
		if *verbose2 {
			if resp := r.Result.Resp; resp != nil {
				if *header != "" {
					if h := resp.Header.Get(*header); h != "" {
						verbose += fmt.Sprintf("\n\theader %s: %s", *header, h)
					}
				}
				if t := resp.TLS; t != nil {
					for i, c := range t.PeerCertificates {
						verbose += fmt.Sprintf("\n\tcert %v:\n\t\texpires: %v\n\t\tfingerprint: %x\n\t\tdomains: %q", i, c.NotAfter, sha1.Sum(c.Raw), c.DNSNames)
					}
				}
			}

		}
		fmt.Printf("==== %v: %v %s%s%s\n", r.Plan.Label, r.Plan.URL, ip, status, verbose)
		if r.Result.Result != nil {
			fmt.Println("ERROR:", r.Result.Result)
		}
	}
}