Example #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)
}
func main() {
	flag.Parse()

	var clientConfig ClientDomainVerificationTestConfigFile
	err := utils.ReadConfigFile(configFilePath, &clientConfig)
	config.ShelterConfig = clientConfig.Config

	if err == utils.ErrConfigFileUndefined {
		fmt.Println(err.Error())
		fmt.Println("Usage:")
		flag.PrintDefaults()
		return

	} else if err != nil {
		utils.Fatalln("Error reading configuration file", err)
	}

	utils.StartDNSServer(clientConfig.DNSServerPort, clientConfig.Scan.UDPMaxSize)
	finishRESTServer := utils.StartRESTServer()
	defer finishRESTServer()
	utils.StartWebClient()

	scanDomain()
	queryDomain()

	utils.Println("SUCCESS!")
}
Example #3
0
func main() {
	flag.Parse()

	var config ScanQuerierTestConfigFile
	err := utils.ReadConfigFile(configFilePath, &config)

	if err == utils.ErrConfigFileUndefined {
		fmt.Println(err.Error())
		fmt.Println("Usage:")
		flag.PrintDefaults()
		return

	} else if err != nil {
		utils.Fatalln("Error reading configuration file", err)
	}

	utils.StartDNSServer(config.Server.Port, config.Scan.UDPMaxSize)

	domainWithNoDNSErrors(config)
	domainWithNoDNSSECErrors(config)
	domainDNSTimeout(config)
	domainDNSUnknownHost(config)

	// Scan querier performance report is optional and only generated when the report file
	// path parameter is given
	if report {
		scanQuerierReport(config)
	}

	if inputReport {
		inputScanReport(config)
	}

	utils.Println("SUCCESS!")
}
Example #4
0
func main() {
	flag.Parse()

	var config ScanCollectorTestConfigFile
	err := utils.ReadConfigFile(configFilePath, &config)

	if err == utils.ErrConfigFileUndefined {
		fmt.Println(err.Error())
		fmt.Println("Usage:")
		flag.PrintDefaults()
		return

	} else if err != nil {
		utils.Fatalln("Error reading configuration file", err)
	}

	database, databaseSession, err := mongodb.Open(
		[]string{config.Database.URI},
		config.Database.Name,
		false, "", "",
	)
	if err != nil {
		utils.Fatalln("Error connecting the database", err)
	}
	defer databaseSession.Close()

	// Remove all data before starting the test. This is necessary because maybe in the last
	// test there was an error and the data wasn't removed from the database
	utils.ClearDatabase(database)

	domainWithErrors(config, database)
	domainWithNoErrors(config, database)

	utils.Println("SUCCESS!")
}
Example #5
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)
}
Example #6
0
func main() {
	flag.Parse()

	var config DomainDAOTestConfigFile
	err := utils.ReadConfigFile(configFilePath, &config)

	if err == utils.ErrConfigFileUndefined {
		fmt.Println(err.Error())
		fmt.Println("Usage:")
		flag.PrintDefaults()
		return

	} else if err != nil {
		utils.Fatalln("Error reading configuration file", err)
	}

	database, databaseSession, err := mongodb.Open(
		[]string{config.Database.URI},
		config.Database.Name,
		false, "", "",
	)

	if err != nil {
		utils.Fatalln("Error connecting the database", err)
	}
	defer databaseSession.Close()

	domainDAO := dao.DomainDAO{
		Database: database,
	}

	// If there was some problem in the last test, there could be some data in the
	// database, so let's clear it to don't affect this test. We avoid checking the error,
	// because if the collection does not exist yet, it will be created in the first
	// insert
	domainDAO.RemoveAll()

	domainLifeCycle(domainDAO)
	domainsLifeCycle(domainDAO)
	domainUniqueFQDN(domainDAO)
	domainConcurrency(domainDAO)
	domainsPagination(domainDAO)
	domainsNotification(domainDAO)
	domainsExpand(domainDAO)
	domainFilter(domainDAO)

	// Domain DAO performance report is optional and only generated when the report file
	// path parameter is given
	if report {
		domainDAOPerformanceReport(config.Report.ReportFile, domainDAO)
	}

	utils.Println("SUCCESS!")
}
func main() {
	flag.Parse()

	err := utils.ReadConfigFile(configFilePath, &config.ShelterConfig)

	if err == utils.ErrConfigFileUndefined {
		fmt.Println(err.Error())
		fmt.Println("Usage:")
		flag.PrintDefaults()
		return

	} else if err != nil {
		utils.Fatalln("Error reading configuration file", err)
	}

	database, databaseSession, err := mongodb.Open(
		config.ShelterConfig.Database.URIs,
		config.ShelterConfig.Database.Name,
		false, "", "",
	)

	if err != nil {
		utils.Fatalln("Error connecting the database", err)
	}
	defer databaseSession.Close()

	// If there was some problem in the last test, there could be some data in the
	// database, so let's clear it to don't affect this test. We avoid checking the error,
	// because if the collection does not exist yet, it will be created in the first
	// insert
	utils.ClearDatabase(database)

	invalidFQDN(database)
	createDomain(database)
	updateDomain(database)
	retrieveDomain(database)
	retrieveDomainMetadata(database)
	retrieveDomainIfModifiedSince(database)
	retrieveDomainIfUnmodifiedSince(database)
	retrieveDomainIfMatch(database)
	retrieveDomainIfNoneMatch(database)
	updateDomainIfModifiedSince(database)
	updateDomainIfUnmodifiedSince(database)
	updateDomainIfMatch(database)
	updateDomainIfNoneMatch(database)
	deleteDomainIfModifiedSince(database)
	deleteDomainIfUnmodifiedSince(database)
	deleteDomainIfMatch(database)
	deleteDomainIfNoneMatch(database)
	deleteDomain(database)
	retrieveUnknownDomain(database)

	utils.Println("SUCCESS!")
}
Example #8
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)
}
Example #9
0
func main() {
	flag.Parse()

	err := utils.ReadConfigFile(configFilePath, &config.ShelterConfig)

	if err == utils.ErrConfigFileUndefined {
		fmt.Println(err.Error())
		fmt.Println("Usage:")
		flag.PrintDefaults()
		return

	} else if err != nil {
		utils.Fatalln("Error reading configuration file", err)
	}

	database, databaseSession, err := mongodb.Open(
		config.ShelterConfig.Database.URIs,
		config.ShelterConfig.Database.Name,
		config.ShelterConfig.Database.Auth.Enabled,
		config.ShelterConfig.Database.Auth.Username,
		config.ShelterConfig.Database.Auth.Password,
	)

	if err != nil {
		utils.Fatalln("Error connecting the database", err)
	}
	defer databaseSession.Close()

	// If there was some problem in the last test, there could be some data in the database,
	// so let's clear it to don't affect this test. We avoid checking the error, because if
	// the collection does not exist yet, it will be created in the first insert
	utils.ClearDatabase(database)

	messageChannel, errorChannel, err := utils.StartMailServer(config.ShelterConfig.Notification.SMTPServer.Port)
	if err != nil {
		utils.Fatalln("Error starting the mail server", err)
	}

	domainDAO := dao.DomainDAO{
		Database: database,
	}

	templateName := createTemplateFile()
	defer removeTemplateFile(templateName)

	simpleNotification(domainDAO, templateName, messageChannel, errorChannel)

	utils.Println("SUCCESS!")
}
Example #10
0
func main() {
	flag.Parse()

	err := utils.ReadConfigFile(configFilePath, &config.ShelterConfig)

	if err == utils.ErrConfigFileUndefined {
		fmt.Println(err.Error())
		fmt.Println("Usage:")
		flag.PrintDefaults()
		return

	} else if err != nil {
		utils.Fatalln("Error reading configuration file", err)
	}

	finishRESTServer := utils.StartRESTServer()
	defer finishRESTServer()
	utils.StartWebClient()

	database, databaseSession, err := mongodb.Open(
		config.ShelterConfig.Database.URIs,
		config.ShelterConfig.Database.Name,
		config.ShelterConfig.Database.Auth.Enabled,
		config.ShelterConfig.Database.Auth.Username,
		config.ShelterConfig.Database.Auth.Password,
	)

	if err != nil {
		utils.Fatalln("Error connecting the database", err)
	}
	defer databaseSession.Close()

	// If there was some problem in the last test, there could be some data in the
	// database, so let's clear it to don't affect this test. We avoid checking the error,
	// because if the collection does not exist yet, it will be created in the first
	// insert
	utils.ClearDatabase(database)

	createScans(database)
	retrieveScans()
	retrieveScansWithPagination()
	retrieveScansWithCache()
	retrieveCurrentScan()

	utils.Println("SUCCESS!")
}
func main() {
	flag.Parse()

	var restConfig RESTHandlerDomainVerificationTestConfigFile
	err := utils.ReadConfigFile(configFilePath, &restConfig)
	config.ShelterConfig = restConfig.Config

	if err == utils.ErrConfigFileUndefined {
		fmt.Println(err.Error())
		fmt.Println("Usage:")
		flag.PrintDefaults()
		return

	} else if err != nil {
		utils.Fatalln("Error reading configuration file", err)
	}

	database, databaseSession, err := mongodb.Open(
		restConfig.Database.URIs,
		restConfig.Database.Name,
		false, "", "",
	)

	if err != nil {
		utils.Fatalln("Error connecting the database", err)
	}
	defer databaseSession.Close()

	domainDAO := dao.DomainDAO{
		Database: database,
	}

	// If there was some problem in the last test, there could be some data in the
	// database, so let's clear it to don't affect this test. We avoid checking the error,
	// because if the collection does not exist yet, it will be created in the first
	// insert
	domainDAO.RemoveAll()

	utils.StartDNSServer(restConfig.DNSServerPort, restConfig.Scan.UDPMaxSize)

	scanDomain()
	scanPersistedDomain(domainDAO)
	queryDomain()

	utils.Println("SUCCESS!")
}
Example #12
0
func main() {
	flag.Parse()

	var config ScanDAOTestConfigFile
	err := utils.ReadConfigFile(configFilePath, &config)

	if err == utils.ErrConfigFileUndefined {
		fmt.Println(err.Error())
		fmt.Println("Usage:")
		flag.PrintDefaults()
		return

	} else if err != nil {
		utils.Fatalln("Error reading configuration file", err)
	}

	database, databaseSession, err := mongodb.Open(
		[]string{config.Database.URI},
		config.Database.Name,
		false, "", "",
	)

	if err != nil {
		utils.Fatalln("Error connecting the database", err)
	}
	defer databaseSession.Close()

	scanDAO := dao.ScanDAO{
		Database: database,
	}

	// If there was some problem in the last test, there could be some data in the
	// database, so let's clear it to don't affect this test. We avoid checking the error,
	// because if the collection does not exist yet, it will be created in the first
	// insert
	scanDAO.RemoveAll()

	scanLifeCycle(scanDAO)
	scanConcurrency(scanDAO)
	scanStatistics(scanDAO)
	scansPagination(scanDAO)
	scansExpand(scanDAO)

	utils.Println("SUCCESS!")
}
Example #13
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)
}
Example #14
0
func main() {
	flag.Parse()

	var scanConfig ScanTestConfigFile
	err := utils.ReadConfigFile(configFilePath, &scanConfig)
	config.ShelterConfig = scanConfig.Config

	if err == utils.ErrConfigFileUndefined {
		fmt.Println(err.Error())
		fmt.Println("Usage:")
		flag.PrintDefaults()
		return

	} else if err != nil {
		utils.Fatalln("Error reading configuration file", err)
	}

	database, databaseSession, err := mongodb.Open(
		scanConfig.Database.URIs,
		scanConfig.Database.Name,
		scanConfig.Database.Auth.Enabled,
		scanConfig.Database.Auth.Username,
		scanConfig.Database.Auth.Password,
	)

	if err != nil {
		utils.Fatalln("Error connecting the database", err)
	}
	defer databaseSession.Close()

	// Remove all data before starting the test. This is necessary because maybe in the last
	// test there was an error and the data wasn't removed from the database
	utils.ClearDatabase(database)

	server = utils.StartDNSServer(scanConfig.DNSServerPort, scanConfig.Scan.UDPMaxSize)

	domainDAO := dao.DomainDAO{
		Database: database,
	}

	// Register a scan only to avoid warning messages in the integration test execution
	scheduler.Register(scheduler.Job{
		Type:          scheduler.JobTypeScan,
		NextExecution: time.Now().Add(10 * time.Minute),
		Task:          func() {},
	})

	domainWithNoErrors(domainDAO)
	domainWithNoErrorsOnTheFly()
	domainQuery()
	domainQueryWithDNSSECErrors()

	// Scan performance report is optional and only generated when the report file
	// path parameter is given
	if report {
		if cpuProfile {
			f := utils.StartCPUProfile(scanConfig.Report.Profile.CPUFile)
			defer f()
		}

		if memoryProfile {
			f := utils.StartMemoryProfile(scanConfig.Report.Profile.MemoryFile)
			defer f()
		}

		if goProfile {
			f := utils.StartGoRoutinesProfile(scanConfig.Report.Profile.GoRoutinesFile)
			defer f()
		}

		scanDAO := dao.ScanDAO{
			Database: database,
		}

		scanReport(domainDAO, scanDAO, scanConfig)
	}

	// This test is after all others because it will ask on real nameservers, so we need to
	// change to port 53
	scan.DNSPort = 53
	brDomainWithoutDNSSEC(domainDAO)

	utils.Println("SUCCESS!")
}
Example #15
0
func main() {
	flag.Parse()

	var restConfig RESTTestConfigFile
	err := utils.ReadConfigFile(configFilePath, &restConfig)
	config.ShelterConfig = restConfig.Config

	if err == utils.ErrConfigFileUndefined {
		fmt.Println(err.Error())
		fmt.Println("Usage:")
		flag.PrintDefaults()
		return

	} else if err != nil {
		utils.Fatalln("Error reading configuration file", err)
	}

	database, databaseSession, err := mongodb.Open(
		config.ShelterConfig.Database.URIs,
		config.ShelterConfig.Database.Name,
		config.ShelterConfig.Database.Auth.Enabled,
		config.ShelterConfig.Database.Auth.Username,
		config.ShelterConfig.Database.Auth.Password,
	)

	if err != nil {
		utils.Fatalln("Error connecting the database", err)
	}
	defer databaseSession.Close()

	// If there was some problem in the last test, there could be some data in the database,
	// so let's clear it to don't affect this test. We avoid checking the error, because if
	// the collection does not exist yet, it will be created in the first insert
	utils.ClearDatabase(database)

	finishRESTServer := utils.StartRESTServer()
	defer finishRESTServer()

	domainLifeCycle()

	// REST performance report is optional and only generated when the report file path parameter is
	// given
	if report {
		if cpuProfile {
			f := utils.StartCPUProfile(restConfig.Report.Profile.CPUFile)
			defer f()
		}

		if memoryProfile {
			f := utils.StartMemoryProfile(restConfig.Report.Profile.MemoryFile)
			defer f()
		}

		if goProfile {
			f := utils.StartGoRoutinesProfile(restConfig.Report.Profile.GoRoutinesFile)
			defer f()
		}

		restReport(restConfig)
	}

	utils.Println("SUCCESS!")
}