func TestInitializeCurrentScan(t *testing.T) { if err := InitializeCurrentScan(); err == nil { t.Fatal("Not alerting about scheduler without scan job") } nextExecution := time.Now().Add(10 * time.Minute) scheduler.Register(scheduler.Job{ Type: scheduler.JobTypeScan, NextExecution: nextExecution, Task: func() {}, }) if err := InitializeCurrentScan(); err != nil { t.Fatal(err) } if shelterCurrentScan.Status != ScanStatusWaitingExecution { t.Error("Wrong initial status of the current scan") } if !shelterCurrentScan.ScheduledAt.Equal(nextExecution) { t.Error("Wrong next execution time of the current scan") } scheduler.Clear() }
func TestFinishAndSaveScan(t *testing.T) { scheduler.Register(scheduler.Job{ Type: scheduler.JobTypeScan, NextExecution: time.Now().Add(10 * time.Minute), Task: func() {}, }) StartNewScan() called := false if err := FinishAndSaveScan(false, func(s *Scan) error { if s.Status != ScanStatusExecuted { t.Error("Not setting finish scan information correctly") } called = true return nil }); err != nil { t.Fatal(err) } if !called { t.Error("Not calling scan save method") } if shelterCurrentScan.Status != ScanStatusWaitingExecution { t.Error("Not setting next scan information correctly") } called = false if err := FinishAndSaveScan(true, func(s *Scan) error { if s.Status != ScanStatusExecutedWithErrors { t.Error("Not setting finish scan information correctly " + "when we had errors") } called = true return nil }); err != nil { t.Fatal(err) } if !called { t.Error("Not calling scan save method when we had errors") } if err := FinishAndSaveScan(true, func(s *Scan) error { return errors.New("Error saving scan!") }); err == nil { t.Error("Not returning err detected by save method") } scheduler.Clear() if err := FinishAndSaveScan(true, func(s *Scan) error { return nil }); err == nil { t.Error("Not returning err when next scan is not found") } }
// The main function of the system is responsable for deploying all system components that // are enabled. For now we have the REST server and the scan system func main() { runtime.GOMAXPROCS(runtime.NumCPU()) logPath := filepath.Join( config.ShelterConfig.BasePath, config.ShelterConfig.LogFilename, ) if err := log.SetOutput(logPath); err != nil { log.Println(err) return } defer log.Close() if config.ShelterConfig.RESTServer.Enabled { var err error restListeners, err = rest.Listen() if err != nil { log.Println("Error while aquiring interfaces for REST server. Details:", err) os.Exit(ErrListeningRESTInterfaces) } if err := rest.Start(restListeners); err != nil { log.Println("Error starting the REST server. Details:", err) os.Exit(ErrStartingRESTServer) } log.Info("REST server started") } if config.ShelterConfig.WebClient.Enabled { var err error clientListeners, err = client.Listen() if err != nil { log.Println("Error while aquiring interfaces for Client server. Details:", err) os.Exit(ErrListeningClientInterfaces) } if err := client.Start(clientListeners); err != nil { log.Println("Error starting the Client server. Details:", err) os.Exit(ErrStartingWebClient) } log.Info("Web client started") } if config.ShelterConfig.Scan.Enabled { // Attention: Cannot use timezone abbreviations // http://stackoverflow.com/questions/25368415/golang-timezone-parsing scanTime, err := time.Parse("15:04:05 -0700", config.ShelterConfig.Scan.Time) if err != nil { log.Println("Scan time not in a valid format. Details:", err) os.Exit(ErrScanTimeFormat) } scanTime = scanTime.UTC() now := time.Now().UTC() nextExecution := time.Date( now.Year(), now.Month(), now.Day(), scanTime.Hour(), scanTime.Minute(), scanTime.Second(), scanTime.Nanosecond(), scanTime.Location(), ) scheduler.Register(scheduler.Job{ Type: scheduler.JobTypeScan, NextExecution: nextExecution, Interval: time.Duration(config.ShelterConfig.Scan.IntervalHours) * time.Hour, Task: scan.ScanDomains, }) // Must be called after registering in scheduler, because we retrieve the next execution time // from it if err := model.InitializeCurrentScan(); err != nil { log.Println("Current scan information got an error while initializing. Details:", err) os.Exit(ErrCurrentScanInitialize) } } if config.ShelterConfig.Notification.Enabled { if err := notification.LoadTemplates(); err != nil { log.Println("Error loading notification templates. Details:", err) os.Exit(ErrNotificationTemplates) } // Attention: Cannot use timezone abbreviations // http://stackoverflow.com/questions/25368415/golang-timezone-parsing notificationTime, err := time.Parse("15:04:05 -0700", config.ShelterConfig.Scan.Time) if err != nil { log.Println("Scan time not in a valid format. Details:", err) os.Exit(ErrScanTimeFormat) } notificationTime = notificationTime.UTC() now := time.Now().UTC() nextExecution := time.Date( now.Year(), now.Month(), now.Day(), notificationTime.Hour(), notificationTime.Minute(), notificationTime.Second(), notificationTime.Nanosecond(), notificationTime.Location(), ) scheduler.Register(scheduler.Job{ Type: scheduler.JobTypeNotification, NextExecution: nextExecution, Interval: time.Duration(config.ShelterConfig.Notification.IntervalHours) * time.Hour, Task: notification.Notify, }) } scheduler.Start() select {} }
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!") }