func uploadPlot(dataPoints []*data.Point, s3Config *uploader.Config, cpuCsv []byte) {
	ag := aggregator.New(dataPoints, time.Duration(*interval)*time.Second)
	report := ag.Data()

	filename := time.Now().UTC().Format(time.RFC3339)

	csvData := report.GenerateCSV()
	loc, err := uploader.Upload(s3Config, bytes.NewBuffer(csvData), filename+".csv", false)
	if err != nil {
		fmt.Fprintf(os.Stderr, "uploading to s3 error: %s\n", err)
		os.Exit(1)
	}
	fmt.Fprintf(os.Stdout, "csv uploaded to %s\n", loc)

	fmt.Fprintln(os.Stderr, "Generating plot from csv data")
	plotBuffer, err := plotgen.Generate(filename, csvData, cpuCsv, *comparisonFile)
	if err != nil {
		fmt.Fprintf(os.Stderr, "failed to generate plot: %s\n", err)
		os.Exit(1)
	}

	loc, err = uploader.Upload(s3Config, plotBuffer, filename+".png", true)
	if err != nil {
		fmt.Fprintf(os.Stderr, "uploading to s3 error: %s\n", err)
		os.Exit(1)
	}
	fmt.Fprintf(os.Stdout, "png uploaded to %s\n", loc)
}
	&data.Point{time.Date(2016, 11, 1, 21, 04, 42, 760279114, time.UTC), time.Duration(28000000)},
	&data.Point{time.Date(2016, 11, 1, 21, 04, 43, 760213269, time.UTC), time.Duration(28000000)},
	&data.Point{time.Date(2016, 11, 1, 21, 04, 42, 760373651, time.UTC), time.Duration(27900000)},
	&data.Point{time.Date(2016, 11, 1, 21, 04, 43, 760159771, time.UTC), time.Duration(28200000)},
	&data.Point{time.Date(2016, 11, 1, 21, 04, 44, 760090065, time.UTC), time.Duration(29100000)},
	&data.Point{time.Date(2016, 11, 1, 21, 04, 44, 788256168, time.UTC), time.Duration(13800000)},
	&data.Point{time.Date(2016, 11, 1, 21, 04, 46, 788331398, time.UTC), time.Duration(13700000)},
	&data.Point{time.Date(2016, 11, 1, 21, 04, 45, 788291332, time.UTC), time.Duration(13800000)},
	&data.Point{time.Date(2016, 11, 1, 21, 04, 45, 788256153, time.UTC), time.Duration(14100000)},
	&data.Point{time.Date(2016, 11, 1, 21, 04, 46, 789231777, time.UTC), time.Duration(13600000)},
}

var _ = Describe("Aggregator", func() {
	Describe("Data", func() {
		It("returns data ordered by time that can be graphed in a throughput vs latency plot", func() {
			ag := aggregator.New(dataPoints, time.Second)
			report := ag.Data()

			expectedReport := aggregator.Report{
				aggregator.Point{Throughput: 3, Latency: time.Duration(28000000)},
				aggregator.Point{Throughput: 3, Latency: time.Duration(28000000)},
				aggregator.Point{Throughput: 3, Latency: time.Duration(27900000)},
				aggregator.Point{Throughput: 2, Latency: time.Duration(28200000)},
				aggregator.Point{Throughput: 2, Latency: time.Duration(28000000)},
				aggregator.Point{Throughput: 2, Latency: time.Duration(29100000)},
				aggregator.Point{Throughput: 2, Latency: time.Duration(13800000)},
				aggregator.Point{Throughput: 2, Latency: time.Duration(14100000)},
				aggregator.Point{Throughput: 2, Latency: time.Duration(13800000)},
				aggregator.Point{Throughput: 2, Latency: time.Duration(13700000)},
				aggregator.Point{Throughput: 2, Latency: time.Duration(13600000)},
			}