Exemple #1
1
// Generates a report with the amount of time for each operation in the domain DAO. For
// more realistic values it does the same operation for the same amount of data X number
// of times to get the average time of the operation. After some results, with indexes we
// get 80% better performance, another good improvements was to create and remove many
// objects at once using go routines
func domainDAOPerformanceReport(reportFile string, domainDAO dao.DomainDAO) {
	// Report header
	report := " #       | Total            | Insert           | Find             | Remove\n" +
		"------------------------------------------------------------------------------------\n"

	// Report variables
	averageTurns := 5
	scale := []int{10, 50, 100, 500, 1000, 5000,
		10000, 50000, 100000, 500000, 1000000, 5000000}

	for _, numberOfItems := range scale {
		var totalDuration, insertDuration, queryDuration, removeDuration time.Duration

		for i := 0; i < averageTurns; i++ {
			utils.Println(fmt.Sprintf("Generating report - scale %d - turn %d", numberOfItems, i+1))
			totalDurationTmp, insertDurationTmp, queryDurationTmp, removeDurationTmp :=
				calculateDomainDAODurations(domainDAO, numberOfItems)

			totalDuration += totalDurationTmp
			insertDuration += insertDurationTmp
			queryDuration += queryDurationTmp
			removeDuration += removeDurationTmp
		}

		report += fmt.Sprintf("% -8d | % 16s | % 16s | % 16s | % 16s\n",
			numberOfItems,
			time.Duration(int64(totalDuration)/int64(averageTurns)).String(),
			time.Duration(int64(insertDuration)/int64(averageTurns)).String(),
			time.Duration(int64(queryDuration)/int64(averageTurns)).String(),
			time.Duration(int64(removeDuration)/int64(averageTurns)).String(),
		)
	}

	utils.WriteReport(reportFile, report)
}
Exemple #2
0
// Generates a report with the amount of time of a scan
func scanReport(domainDAO dao.DomainDAO, scanDAO dao.ScanDAO, scanConfig ScanTestConfigFile) {
	report := " #       | Total            | DPS  | Memory (MB)\n" +
		"-----------------------------------------------------\n"

	// Report variables
	scale := []int{10, 50, 100, 500, 1000, 5000,
		10000, 50000, 100000, 500000, 1000000, 5000000}

	dnskey, privateKey, err := utils.GenerateKey()
	if err != nil {
		utils.Fatalln("Error generating DNSKEY", err)
	}

	reportHandler := ReportHandler{
		DNSKEY:     dnskey,
		PrivateKey: privateKey,
	}

	server.Handler = reportHandler
	dns.DefaultServeMux = nil

	for _, numberOfItems := range scale {
		utils.Println(fmt.Sprintf("Generating report - scale %d", numberOfItems))

		for i := 0; i < numberOfItems; i++ {
			if i%1000 == 0 {
				utils.PrintProgress("building scenario", (i*100)/numberOfItems)
			}

			fqdn := fmt.Sprintf("domain%d.br.", i)
			generateAndSaveDomain(fqdn, domainDAO, dnskey)
		}

		utils.PrintProgress("building scenario", 100)
		totalDuration, domainsPerSecond := calculateScanDurations(numberOfItems, scanDAO)

		var memStats runtime.MemStats
		runtime.ReadMemStats(&memStats)

		report += fmt.Sprintf("% -8d | %16s | %4d | %14.2f\n",
			numberOfItems,
			time.Duration(int64(totalDuration)).String(),
			domainsPerSecond,
			float64(memStats.Alloc)/float64(MB),
		)

		if err := domainDAO.RemoveAll(); err != nil {
			// When the result set is too big to remove, we got a timeout error from the
			// connection, but it's ok
			//utils.Fatalln("Error removing domains generated for report", err)
		}
	}

	utils.WriteReport(scanConfig.Report.File, report)
}
Exemple #3
0
func restReport(restConfig RESTTestConfigFile) {
	report := " #       | Operation | Total            | DPS  | Memory (MB)\n" +
		"---------------------------------------------------------------\n"

	// Report variables
	scale := []int{10, 50, 100, 500, 1000, 5000,
		10000, 50000, 100000, 500000, 1000000, 5000000}

	content := []byte(`{
      "Nameservers": [
        { "host": "ns1.example.com.br.", "ipv4": "127.0.0.1" },
        { "host": "ns2.example.com.br.", "ipv6": "::1" }
      ],
      "Owners": [
        { "email": "*****@*****.**", "language": "pt-br" }
      ]
    }`)

	url := ""
	if len(config.ShelterConfig.RESTServer.Listeners) > 0 {
		url = fmt.Sprintf("http://%s:%d", config.ShelterConfig.RESTServer.Listeners[0].IP,
			config.ShelterConfig.RESTServer.Listeners[0].Port)
	}

	if len(url) == 0 {
		utils.Fatalln("There's no interface to connect to", nil)
	}

	for _, numberOfItems := range scale {
		utils.Println(fmt.Sprintf("Generating report - scale %d", numberOfItems))

		// Generate domains
		report += restActionReport(numberOfItems, content, func(i int) (*http.Request, error) {
			return http.NewRequest("PUT", fmt.Sprintf("%s/domain/example%d.com.br.", url, i),
				bytes.NewReader(content))
		}, http.StatusCreated, "CREATE")

		// Retrieve domains
		report += restActionReport(numberOfItems, content, func(i int) (*http.Request, error) {
			return http.NewRequest("GET", fmt.Sprintf("%s/domain/example%d.com.br.", url, i), nil)
		}, http.StatusOK, "RETRIEVE")

		// Delete domains
		report += restActionReport(numberOfItems, content, func(i int) (*http.Request, error) {
			return http.NewRequest("DELETE", fmt.Sprintf("%s/domain/example%d.com.br.", url, i), nil)
		}, http.StatusNoContent, "DELETE")
	}

	utils.WriteReport(restConfig.Report.File, report)
}
Exemple #4
0
// Generates a report with the result of a scan in the root zone file, it should be last
// last thing from the test, because it changes the DNS test port to the original one for
// real tests
func inputScanReport(config ScanQuerierTestConfigFile) {
	// Move back to default port, because we are going to query the world for real to check
	// querier performance
	scan.DNSPort = 53

	// As we are using the same domains repeatedly we should be careful about how many
	// requests we send to only one host to avoid abuses. This value should be beteween 5
	// and 10
	scan.MaxQPSPerHost = 5

	report := " #       | Total            | QPS  | Memory (MB)\n" +
		"---------------------------------------------------\n"

	domains, err := readInputFile(config.Report.InputFile)
	if err != nil {
		utils.Fatalln("Error while loading input data for report", err)
	}

	nameserverStatusCounter := 0
	nameserversStatus := make(map[model.NameserverStatus]int)

	dsStatusCounter := 0
	dsSetStatus := make(map[model.DSStatus]int)

	totalDuration, queriesPerSecond, nameserversStatus, dsSetStatus :=
		calculateScanQuerierDurations(config, domains)

	var memStats runtime.MemStats
	runtime.ReadMemStats(&memStats)

	report += fmt.Sprintf("% -8d | %16s | %4d | %14.2f\n",
		len(domains),
		time.Duration(int64(totalDuration)).String(),
		queriesPerSecond,
		float64(memStats.Alloc)/float64(MB),
	)

	report += "\nNameserver Status\n" +
		"-----------------\n"
	for _, counter := range nameserversStatus {
		nameserverStatusCounter += counter
	}
	for status, counter := range nameserversStatus {
		report += fmt.Sprintf("%16s: % 3.2f%%\n",
			model.NameserverStatusToString(status),
			(float64(counter*100) / float64(nameserverStatusCounter)),
		)
	}

	report += "\nDS Status\n" +
		"---------\n"
	for _, counter := range dsSetStatus {
		dsStatusCounter += counter
	}
	for status, counter := range dsSetStatus {
		report += fmt.Sprintf("%16s: % 3.2f%%\n",
			model.DSStatusToString(status),
			(float64(counter*100) / float64(dsStatusCounter)),
		)
	}

	utils.WriteReport(config.Report.OutputFile, report)
}
Exemple #5
0
// Generates a report with the amount of time of a scan
func scanQuerierReport(config ScanQuerierTestConfigFile) {
	report := " #       | Total            | QPS  | Memory (MB)\n" +
		"-----------------------------------------------------\n"

	// Report variables
	scale := []int{10, 50, 100, 500, 1000, 5000,
		10000, 50000, 100000, 500000, 1000000, 5000000}

	fqdn := "domain.com.br."

	dnskey, rrsig, err := utils.GenerateKSKAndSignZone(fqdn)
	if err != nil {
		utils.Fatalln("Error creating DNSSEC keys and signatures", err)
	}
	ds := dnskey.ToDS(uint8(model.DSDigestTypeSHA1))

	dns.HandleFunc(fqdn, func(w dns.ResponseWriter, dnsRequestMessage *dns.Msg) {
		defer w.Close()

		if dnsRequestMessage.Question[0].Qtype == dns.TypeSOA {
			dnsResponseMessage := &dns.Msg{
				MsgHdr: dns.MsgHdr{
					Authoritative: true,
				},
				Question: dnsRequestMessage.Question,
				Answer: []dns.RR{
					&dns.SOA{
						Hdr: dns.RR_Header{
							Name:   fqdn,
							Rrtype: dns.TypeSOA,
							Class:  dns.ClassINET,
							Ttl:    86400,
						},
						Ns:      "ns1." + fqdn,
						Mbox:    "rafael.justo.net.br.",
						Serial:  2013112600,
						Refresh: 86400,
						Retry:   86400,
						Expire:  86400,
						Minttl:  900,
					},
				},
			}

			dnsResponseMessage.SetReply(dnsRequestMessage)
			w.WriteMsg(dnsResponseMessage)

		} else if dnsRequestMessage.Question[0].Qtype == dns.TypeDNSKEY {
			dnsResponseMessage := &dns.Msg{
				MsgHdr: dns.MsgHdr{
					Authoritative: true,
				},
				Question: dnsRequestMessage.Question,
				Answer: []dns.RR{
					dnskey,
					rrsig,
				},
			}

			dnsResponseMessage.SetReply(dnsRequestMessage)
			w.WriteMsg(dnsResponseMessage)
		}
	})

	for _, numberOfItems := range scale {
		var domains []*model.Domain
		for i := 0; i < numberOfItems; i++ {
			// We create an object with different nameservers because we don't want to put the
			// nameserver in the query rate limit check
			domains = append(domains, &model.Domain{
				FQDN: fqdn,
				Nameservers: []model.Nameserver{
					{
						Host: fmt.Sprintf("ns%d.%s", i, fqdn),
						IPv4: net.ParseIP("127.0.0.1"),
					},
				},
				DSSet: []model.DS{
					{
						Keytag:     dnskey.KeyTag(),
						Algorithm:  utils.ConvertKeyAlgorithm(dnskey.Algorithm),
						DigestType: model.DSDigestTypeSHA1,
						Digest:     ds.Digest,
					},
				},
			})
		}

		utils.Println(fmt.Sprintf("Generating report - scale %d", numberOfItems))
		totalDuration, queriesPerSecond, _, _ :=
			calculateScanQuerierDurations(config, domains)

		var memStats runtime.MemStats
		runtime.ReadMemStats(&memStats)

		report += fmt.Sprintf("% -8d | %16s | %4d | %14.2f\n",
			numberOfItems,
			time.Duration(int64(totalDuration)).String(),
			queriesPerSecond,
			float64(memStats.Alloc)/float64(MB),
		)
	}

	utils.WriteReport(config.Report.ReportFile, report)
}