X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/6f5431413448f52f3ae5c88553b7f7ee1532b9fd..0783caa882a7c45c24b5a054957a1568ad55ed99:/lib/costanalyzer/costanalyzer_test.go diff --git a/lib/costanalyzer/costanalyzer_test.go b/lib/costanalyzer/costanalyzer_test.go index 48e7733e18..b78b288ab0 100644 --- a/lib/costanalyzer/costanalyzer_test.go +++ b/lib/costanalyzer/costanalyzer_test.go @@ -33,7 +33,6 @@ func (s *Suite) TearDownSuite(c *check.C) { } func (s *Suite) SetUpSuite(c *check.C) { - arvadostest.StartAPI() arvadostest.StartKeep(2, true) // Get the various arvados, arvadosclient, and keep client objects @@ -53,7 +52,7 @@ func (s *Suite) SetUpSuite(c *check.C) { "IncludedScratch": 64000000000, "AddedScratch": 0, "Price": 0.292, - "Preemptible": false + "Preemptible": true }` standardD32sV3JSON := `{ "Name": "Standard_D32s_v3", @@ -153,44 +152,76 @@ func createNodeJSON(c *check.C, arv *arvadosclient.ArvadosClient, ac *arvados.Cl func (*Suite) TestUsage(c *check.C) { var stdout, stderr bytes.Buffer exitcode := Command.RunCommand("costanalyzer.test", []string{"-help", "-log-level=debug"}, &bytes.Buffer{}, &stdout, &stderr) - c.Check(exitcode, check.Equals, 1) + c.Check(exitcode, check.Equals, 0) c.Check(stdout.String(), check.Equals, "") c.Check(stderr.String(), check.Matches, `(?ms).*Usage:.*`) } +func (*Suite) TestTimestampRange(c *check.C) { + var stdout, stderr bytes.Buffer + resultsDir := c.MkDir() + // Run costanalyzer with a timestamp range. This should pick up two container requests in "Final" state. + exitcode := Command.RunCommand("costanalyzer.test", []string{"-output", resultsDir, "-begin", "2020-11-02T00:00:00", "-end", "2020-11-03T23:59:00"}, &bytes.Buffer{}, &stdout, &stderr) + c.Check(exitcode, check.Equals, 0) + c.Assert(stderr.String(), check.Matches, "(?ms).*supplied uuids in .*") + + uuidReport, err := ioutil.ReadFile(resultsDir + "/" + arvadostest.CompletedDiagnosticsContainerRequest1UUID + ".csv") + c.Assert(err, check.IsNil) + uuid2Report, err := ioutil.ReadFile(resultsDir + "/" + arvadostest.CompletedDiagnosticsContainerRequest2UUID + ".csv") + c.Assert(err, check.IsNil) + + c.Check(string(uuidReport), check.Matches, "(?ms).*TOTAL,,,,,,763.467,,,,0.01") + c.Check(string(uuid2Report), check.Matches, "(?ms).*TOTAL,,,,,,488.775,,,,0.01") + re := regexp.MustCompile(`(?ms).*supplied uuids in (.*?)\n`) + matches := re.FindStringSubmatch(stderr.String()) // matches[1] contains a string like 'results/2020-11-02-18-57-45-aggregate-costaccounting.csv' + + aggregateCostReport, err := ioutil.ReadFile(matches[1]) + c.Assert(err, check.IsNil) + + c.Check(string(aggregateCostReport), check.Matches, "(?ms).*TOTAL,1245.564,0.01") +} + func (*Suite) TestContainerRequestUUID(c *check.C) { var stdout, stderr bytes.Buffer + resultsDir := c.MkDir() // Run costanalyzer with 1 container request uuid - exitcode := Command.RunCommand("costanalyzer.test", []string{"-uuid", arvadostest.CompletedContainerRequestUUID, "-output", "results"}, &bytes.Buffer{}, &stdout, &stderr) + exitcode := Command.RunCommand("costanalyzer.test", []string{"-output", resultsDir, arvadostest.CompletedContainerRequestUUID}, &bytes.Buffer{}, &stdout, &stderr) c.Check(exitcode, check.Equals, 0) c.Assert(stderr.String(), check.Matches, "(?ms).*supplied uuids in .*") - uuidReport, err := ioutil.ReadFile("results/" + arvadostest.CompletedContainerRequestUUID + ".csv") + uuidReport, err := ioutil.ReadFile(resultsDir + "/" + arvadostest.CompletedContainerRequestUUID + ".csv") c.Assert(err, check.IsNil) - c.Check(string(uuidReport), check.Matches, "(?ms).*TOTAL,,,,,,,,,7.01302889") + // Make sure the 'preemptible' flag was picked up + c.Check(string(uuidReport), check.Matches, "(?ms).*,Standard_E4s_v3,true,.*") + c.Check(string(uuidReport), check.Matches, "(?ms).*TOTAL,,,,,,86462.000,,,,7.01") re := regexp.MustCompile(`(?ms).*supplied uuids in (.*?)\n`) matches := re.FindStringSubmatch(stderr.String()) // matches[1] contains a string like 'results/2020-11-02-18-57-45-aggregate-costaccounting.csv' aggregateCostReport, err := ioutil.ReadFile(matches[1]) c.Assert(err, check.IsNil) - c.Check(string(aggregateCostReport), check.Matches, "(?ms).*TOTAL,7.01302889") + c.Check(string(aggregateCostReport), check.Matches, "(?ms).*TOTAL,86462.000,7.01") } func (*Suite) TestCollectionUUID(c *check.C) { var stdout, stderr bytes.Buffer + resultsDir := c.MkDir() + + // Create a collection with no container_request property + ac := arvados.NewClientFromEnv() + var coll arvados.Collection + err := ac.RequestAndDecode(&coll, "POST", "arvados/v1/collections", nil, nil) + c.Assert(err, check.IsNil) - // Run costanalyzer with 1 collection uuid, without 'container_request' property - exitcode := Command.RunCommand("costanalyzer.test", []string{"-uuid", arvadostest.FooCollection, "-output", "results"}, &bytes.Buffer{}, &stdout, &stderr) + exitcode := Command.RunCommand("costanalyzer.test", []string{"-output", resultsDir, coll.UUID}, &bytes.Buffer{}, &stdout, &stderr) c.Check(exitcode, check.Equals, 2) c.Assert(stderr.String(), check.Matches, "(?ms).*does not have a 'container_request' property.*") - // Update the collection, attach a 'container_request' property - ac := arvados.NewClientFromEnv() - var coll arvados.Collection + stdout.Truncate(0) + stderr.Truncate(0) - // Update collection record - err := ac.RequestAndDecode(&coll, "PUT", "arvados/v1/collections/"+arvadostest.FooCollection, nil, map[string]interface{}{ + // Add a container_request property + err = ac.RequestAndDecode(&coll, "PATCH", "arvados/v1/collections/"+coll.UUID, nil, map[string]interface{}{ "collection": map[string]interface{}{ "properties": map[string]interface{}{ "container_request": arvadostest.CompletedContainerRequestUUID, @@ -199,40 +230,39 @@ func (*Suite) TestCollectionUUID(c *check.C) { }) c.Assert(err, check.IsNil) - stdout.Truncate(0) - stderr.Truncate(0) - - // Run costanalyzer with 1 collection uuid - exitcode = Command.RunCommand("costanalyzer.test", []string{"-uuid", arvadostest.FooCollection, "-output", "results"}, &bytes.Buffer{}, &stdout, &stderr) + // Re-run costanalyzer on the updated collection + resultsDir = c.MkDir() + exitcode = Command.RunCommand("costanalyzer.test", []string{"-output", resultsDir, coll.UUID}, &bytes.Buffer{}, &stdout, &stderr) c.Check(exitcode, check.Equals, 0) c.Assert(stderr.String(), check.Matches, "(?ms).*supplied uuids in .*") - uuidReport, err := ioutil.ReadFile("results/" + arvadostest.CompletedContainerRequestUUID + ".csv") + uuidReport, err := ioutil.ReadFile(resultsDir + "/" + arvadostest.CompletedContainerRequestUUID + ".csv") c.Assert(err, check.IsNil) - c.Check(string(uuidReport), check.Matches, "(?ms).*TOTAL,,,,,,,,,7.01302889") + c.Check(string(uuidReport), check.Matches, "(?ms).*TOTAL,,,,,,86462.000,,,,7.01") re := regexp.MustCompile(`(?ms).*supplied uuids in (.*?)\n`) matches := re.FindStringSubmatch(stderr.String()) // matches[1] contains a string like 'results/2020-11-02-18-57-45-aggregate-costaccounting.csv' aggregateCostReport, err := ioutil.ReadFile(matches[1]) c.Assert(err, check.IsNil) - c.Check(string(aggregateCostReport), check.Matches, "(?ms).*TOTAL,7.01302889") + c.Check(string(aggregateCostReport), check.Matches, "(?ms).*TOTAL,86462.000,7.01") } func (*Suite) TestDoubleContainerRequestUUID(c *check.C) { var stdout, stderr bytes.Buffer + resultsDir := c.MkDir() // Run costanalyzer with 2 container request uuids - exitcode := Command.RunCommand("costanalyzer.test", []string{"-uuid", arvadostest.CompletedContainerRequestUUID, "-uuid", arvadostest.CompletedContainerRequestUUID2, "-output", "results"}, &bytes.Buffer{}, &stdout, &stderr) + exitcode := Command.RunCommand("costanalyzer.test", []string{"-output", resultsDir, arvadostest.CompletedContainerRequestUUID, arvadostest.CompletedContainerRequestUUID2}, &bytes.Buffer{}, &stdout, &stderr) c.Check(exitcode, check.Equals, 0) c.Assert(stderr.String(), check.Matches, "(?ms).*supplied uuids in .*") - uuidReport, err := ioutil.ReadFile("results/" + arvadostest.CompletedContainerRequestUUID + ".csv") + uuidReport, err := ioutil.ReadFile(resultsDir + "/" + arvadostest.CompletedContainerRequestUUID + ".csv") c.Assert(err, check.IsNil) - c.Check(string(uuidReport), check.Matches, "(?ms).*TOTAL,,,,,,,,,7.01302889") + c.Check(string(uuidReport), check.Matches, "(?ms).*TOTAL,,,,,,86462.000,,,,7.01") - uuidReport2, err := ioutil.ReadFile("results/" + arvadostest.CompletedContainerRequestUUID2 + ".csv") + uuidReport2, err := ioutil.ReadFile(resultsDir + "/" + arvadostest.CompletedContainerRequestUUID2 + ".csv") c.Assert(err, check.IsNil) - c.Check(string(uuidReport2), check.Matches, "(?ms).*TOTAL,,,,,,,,,42.27031111") + c.Check(string(uuidReport2), check.Matches, "(?ms).*TOTAL,,,,,,86462.000,,,,42.27") re := regexp.MustCompile(`(?ms).*supplied uuids in (.*?)\n`) matches := re.FindStringSubmatch(stderr.String()) // matches[1] contains a string like 'results/2020-11-02-18-57-45-aggregate-costaccounting.csv' @@ -240,7 +270,7 @@ func (*Suite) TestDoubleContainerRequestUUID(c *check.C) { aggregateCostReport, err := ioutil.ReadFile(matches[1]) c.Assert(err, check.IsNil) - c.Check(string(aggregateCostReport), check.Matches, "(?ms).*TOTAL,49.28334000") + c.Check(string(aggregateCostReport), check.Matches, "(?ms).*TOTAL,172924.000,49.28") stdout.Truncate(0) stderr.Truncate(0) @@ -262,17 +292,18 @@ func (*Suite) TestDoubleContainerRequestUUID(c *check.C) { c.Assert(err, check.IsNil) // Run costanalyzer with the project uuid - exitcode = Command.RunCommand("costanalyzer.test", []string{"-uuid", arvadostest.AProjectUUID, "-cache=false", "-log-level", "debug", "-output", "results"}, &bytes.Buffer{}, &stdout, &stderr) + resultsDir = c.MkDir() + exitcode = Command.RunCommand("costanalyzer.test", []string{"-cache=false", "-log-level", "debug", "-output", resultsDir, arvadostest.AProjectUUID}, &bytes.Buffer{}, &stdout, &stderr) c.Check(exitcode, check.Equals, 0) c.Assert(stderr.String(), check.Matches, "(?ms).*supplied uuids in .*") - uuidReport, err = ioutil.ReadFile("results/" + arvadostest.CompletedContainerRequestUUID + ".csv") + uuidReport, err = ioutil.ReadFile(resultsDir + "/" + arvadostest.CompletedContainerRequestUUID + ".csv") c.Assert(err, check.IsNil) - c.Check(string(uuidReport), check.Matches, "(?ms).*TOTAL,,,,,,,,,7.01302889") + c.Check(string(uuidReport), check.Matches, "(?ms).*TOTAL,,,,,,86462.000,,,,7.01") - uuidReport2, err = ioutil.ReadFile("results/" + arvadostest.CompletedContainerRequestUUID2 + ".csv") + uuidReport2, err = ioutil.ReadFile(resultsDir + "/" + arvadostest.CompletedContainerRequestUUID2 + ".csv") c.Assert(err, check.IsNil) - c.Check(string(uuidReport2), check.Matches, "(?ms).*TOTAL,,,,,,,,,42.27031111") + c.Check(string(uuidReport2), check.Matches, "(?ms).*TOTAL,,,,,,86462.000,,,,42.27") re = regexp.MustCompile(`(?ms).*supplied uuids in (.*?)\n`) matches = re.FindStringSubmatch(stderr.String()) // matches[1] contains a string like 'results/2020-11-02-18-57-45-aggregate-costaccounting.csv' @@ -280,34 +311,47 @@ func (*Suite) TestDoubleContainerRequestUUID(c *check.C) { aggregateCostReport, err = ioutil.ReadFile(matches[1]) c.Assert(err, check.IsNil) - c.Check(string(aggregateCostReport), check.Matches, "(?ms).*TOTAL,49.28334000") + c.Check(string(aggregateCostReport), check.Matches, "(?ms).*TOTAL,172924.000,49.28") +} + +func (*Suite) TestUncommittedContainerRequest(c *check.C) { + var stdout, stderr bytes.Buffer + // Run costanalyzer with 2 container request uuids, one of which is in the Uncommitted state, without output directory specified + exitcode := Command.RunCommand("costanalyzer.test", []string{arvadostest.UncommittedContainerRequestUUID, arvadostest.CompletedDiagnosticsContainerRequest2UUID}, &bytes.Buffer{}, &stdout, &stderr) + c.Check(exitcode, check.Equals, 0) + c.Assert(stderr.String(), check.Not(check.Matches), "(?ms).*supplied uuids in .*") + c.Assert(stderr.String(), check.Matches, "(?ms).*No container associated with container request .*") + + // Check that the total amount was printed to stdout + c.Check(stdout.String(), check.Matches, "0.01\n") } func (*Suite) TestMultipleContainerRequestUUIDWithReuse(c *check.C) { var stdout, stderr bytes.Buffer - // Run costanalyzer with 2 container request uuids, as one comma separated -uuid argument - exitcode := Command.RunCommand("costanalyzer.test", []string{"-uuid", arvadostest.CompletedDiagnosticsContainerRequest1UUID + "," + arvadostest.CompletedDiagnosticsContainerRequest2UUID, "-output", "results"}, &bytes.Buffer{}, &stdout, &stderr) + // Run costanalyzer with 2 container request uuids, without output directory specified + exitcode := Command.RunCommand("costanalyzer.test", []string{arvadostest.CompletedDiagnosticsContainerRequest1UUID, arvadostest.CompletedDiagnosticsContainerRequest2UUID}, &bytes.Buffer{}, &stdout, &stderr) c.Check(exitcode, check.Equals, 0) - c.Assert(stderr.String(), check.Matches, "(?ms).*supplied uuids in .*") + c.Assert(stderr.String(), check.Not(check.Matches), "(?ms).*supplied uuids in .*") // Check that the total amount was printed to stdout - c.Check(stdout.String(), check.Matches, "0.01492030\n") + c.Check(stdout.String(), check.Matches, "0.01\n") stdout.Truncate(0) stderr.Truncate(0) // Run costanalyzer with 2 container request uuids - exitcode = Command.RunCommand("costanalyzer.test", []string{"-uuid", arvadostest.CompletedDiagnosticsContainerRequest1UUID, "-uuid", arvadostest.CompletedDiagnosticsContainerRequest2UUID, "-output", "results"}, &bytes.Buffer{}, &stdout, &stderr) + resultsDir := c.MkDir() + exitcode = Command.RunCommand("costanalyzer.test", []string{"-output", resultsDir, arvadostest.CompletedDiagnosticsContainerRequest1UUID, arvadostest.CompletedDiagnosticsContainerRequest2UUID}, &bytes.Buffer{}, &stdout, &stderr) c.Check(exitcode, check.Equals, 0) c.Assert(stderr.String(), check.Matches, "(?ms).*supplied uuids in .*") - uuidReport, err := ioutil.ReadFile("results/" + arvadostest.CompletedDiagnosticsContainerRequest1UUID + ".csv") + uuidReport, err := ioutil.ReadFile(resultsDir + "/" + arvadostest.CompletedDiagnosticsContainerRequest1UUID + ".csv") c.Assert(err, check.IsNil) - c.Check(string(uuidReport), check.Matches, "(?ms).*TOTAL,,,,,,,,,0.00916192") + c.Check(string(uuidReport), check.Matches, "(?ms).*TOTAL,,,,,,763.467,,,,0.01") - uuidReport2, err := ioutil.ReadFile("results/" + arvadostest.CompletedDiagnosticsContainerRequest2UUID + ".csv") + uuidReport2, err := ioutil.ReadFile(resultsDir + "/" + arvadostest.CompletedDiagnosticsContainerRequest2UUID + ".csv") c.Assert(err, check.IsNil) - c.Check(string(uuidReport2), check.Matches, "(?ms).*TOTAL,,,,,,,,,0.00588088") + c.Check(string(uuidReport2), check.Matches, "(?ms).*TOTAL,,,,,,488.775,,,,0.01") re := regexp.MustCompile(`(?ms).*supplied uuids in (.*?)\n`) matches := re.FindStringSubmatch(stderr.String()) // matches[1] contains a string like 'results/2020-11-02-18-57-45-aggregate-costaccounting.csv' @@ -315,5 +359,5 @@ func (*Suite) TestMultipleContainerRequestUUIDWithReuse(c *check.C) { aggregateCostReport, err := ioutil.ReadFile(matches[1]) c.Assert(err, check.IsNil) - c.Check(string(aggregateCostReport), check.Matches, "(?ms).*TOTAL,0.01492030") + c.Check(string(aggregateCostReport), check.Matches, "(?ms).*TOTAL,1245.564,0.01") }