func TestCreateHostBuckets(t *testing.T) { testutil.HandleTestingErr(db.ClearCollections(host.Collection), t, "couldnt reset host") Convey("With a starting time and a minute bucket size and inserting dynamic hosts with different time frames", t, func() { now := time.Now() bucketSize := time.Duration(10) * time.Second // -20 -> 20 beforeStartHost := host.Host{Id: "beforeStartHost", CreationTime: now.Add(time.Duration(-20) * time.Second), TerminationTime: now.Add(time.Duration(20) * time.Second), Provider: "ec2"} So(beforeStartHost.Insert(), ShouldBeNil) // 80 -> 120 afterEndHost := host.Host{Id: "afterEndHost", CreationTime: now.Add(time.Duration(80) * time.Second), TerminationTime: now.Add(time.Duration(120) * time.Second), Provider: "ec2"} So(afterEndHost.Insert(), ShouldBeNil) // 20 -> 40 h1 := host.Host{Id: "h1", CreationTime: now.Add(time.Duration(20) * time.Second), TerminationTime: now.Add(time.Duration(40) * time.Second), Provider: "ec2"} So(h1.Insert(), ShouldBeNil) // 10 -> 80 h2 := host.Host{Id: "h2", CreationTime: now.Add(time.Duration(10) * time.Second), TerminationTime: now.Add(time.Duration(80) * time.Second), Provider: "ec2"} So(h2.Insert(), ShouldBeNil) // 20 -> h3 := host.Host{Id: "h3", CreationTime: now.Add(time.Duration(20) * time.Second), TerminationTime: util.ZeroTime, Provider: "ec2", Status: evergreen.HostRunning} So(h3.Insert(), ShouldBeNil) // 5 -> 7 sameBucket := host.Host{Id: "sameBucket", CreationTime: now.Add(time.Duration(5) * time.Second), TerminationTime: now.Add(time.Duration(7) * time.Second), Provider: "ec2"} So(sameBucket.Insert(), ShouldBeNil) // 5 -> 30 h4 := host.Host{Id: "h4", CreationTime: now.Add(time.Duration(5) * time.Second), TerminationTime: now.Add(time.Duration(30) * time.Second), Provider: "ec2"} So(h4.Insert(), ShouldBeNil) Convey("for three buckets of 10 seconds, should only retrieve pertinent host docs", func() { endTime := now.Add(time.Duration(30) * time.Second) hosts, err := host.Find(host.ByDynamicWithinTime(now, endTime)) So(err, ShouldBeNil) So(len(hosts), ShouldEqual, 6) frameBounds := FrameBounds{ StartTime: now, EndTime: endTime, BucketSize: bucketSize, NumberBuckets: 3, } Convey("should create the correct buckets and bucket time accordingly", func() { buckets, errors := CreateHostBuckets(hosts, frameBounds) So(errors, ShouldBeEmpty) So(len(buckets), ShouldEqual, 3) So(int(buckets[0].TotalTime.Seconds()), ShouldEqual, 17) So(int(buckets[1].TotalTime.Seconds()), ShouldEqual, 30) So(int(math.Ceil(buckets[2].TotalTime.Seconds())), ShouldEqual, 40) }) }) }) }
// CreateAllHostUtilizationBuckets aggregates each bucket by creating a time frame given the number of days back // and the granularity wanted (ie. days, minutes, seconds, hours) all in seconds. It returns a list of Host utilization // information for each bucket. func CreateAllHostUtilizationBuckets(daysBack, granularity int) ([]HostUtilizationBucket, error) { bounds := CalculateBounds(daysBack, granularity) // find non-static hosts dynamicHosts, err := host.Find(host.ByDynamicWithinTime(bounds.StartTime, bounds.EndTime)) if err != nil { return nil, err } // find static hosts staticHosts, err := host.Find(host.AllStatic) if err != nil { return nil, err } dynamicBuckets, _ := CreateHostBuckets(dynamicHosts, bounds) staticBuckets, _ := CreateHostBuckets(staticHosts, bounds) tasks, err := task.Find(task.ByTimeRun(bounds.StartTime, bounds.EndTime).WithFields(task.StartTimeKey, task.FinishTimeKey, task.HostIdKey)) if err != nil { return nil, err } oldTasks, err := task.FindOld(task.ByTimeRun(bounds.StartTime, bounds.EndTime)) if err != nil { return nil, err } taskBuckets, _ := CreateTaskBuckets(tasks, oldTasks, bounds) bucketData := []HostUtilizationBucket{} for i, staticBucket := range staticBuckets { b := HostUtilizationBucket{ StaticHost: staticBucket.TotalTime, DynamicHost: dynamicBuckets[i].TotalTime, Task: taskBuckets[i].TotalTime, StartTime: bounds.StartTime.Add(time.Duration(i) * bounds.BucketSize), EndTime: bounds.StartTime.Add(time.Duration(i+1) * bounds.BucketSize), } bucketData = append(bucketData, b) } return bucketData, nil }