|
@@ -84,6 +84,20 @@ class OrganizationStatsTestV2(APITestCase, OutcomesSnubaTest):
|
|
|
}
|
|
|
)
|
|
|
|
|
|
+ # Add profile_duration outcome data
|
|
|
+ self.store_outcomes(
|
|
|
+ {
|
|
|
+ "org_id": self.org.id,
|
|
|
+ "timestamp": self.now - timedelta(hours=1),
|
|
|
+ "project_id": self.project.id,
|
|
|
+ "outcome": Outcome.ACCEPTED,
|
|
|
+ "reason": "none",
|
|
|
+ "category": DataCategory.PROFILE_DURATION,
|
|
|
+ "quantity": 1000, # Duration in milliseconds
|
|
|
+ },
|
|
|
+ 3,
|
|
|
+ )
|
|
|
+
|
|
|
def do_request(self, query, user=None, org=None, status_code=200):
|
|
|
self.login_as(user=user or self.user)
|
|
|
org_slug = (org or self.organization).slug
|
|
@@ -439,34 +453,39 @@ class OrganizationStatsTestV2(APITestCase, OutcomesSnubaTest):
|
|
|
)
|
|
|
|
|
|
assert result_sorted(response.data) == {
|
|
|
- "start": "2021-03-12T00:00:00Z",
|
|
|
"end": "2021-03-15T00:00:00Z",
|
|
|
- "intervals": ["2021-03-12T00:00:00Z", "2021-03-13T00:00:00Z", "2021-03-14T00:00:00Z"],
|
|
|
"groups": [
|
|
|
{
|
|
|
"by": {
|
|
|
+ "category": "attachment",
|
|
|
"outcome": "rate_limited",
|
|
|
"reason": "spike_protection",
|
|
|
- "category": "attachment",
|
|
|
},
|
|
|
- "totals": {"sum(quantity)": 1024},
|
|
|
"series": {"sum(quantity)": [0, 0, 1024]},
|
|
|
+ "totals": {"sum(quantity)": 1024},
|
|
|
},
|
|
|
{
|
|
|
- "by": {"outcome": "accepted", "reason": "none", "category": "error"},
|
|
|
- "totals": {"sum(quantity)": 6},
|
|
|
+ "by": {"category": "error", "outcome": "accepted", "reason": "none"},
|
|
|
"series": {"sum(quantity)": [0, 0, 6]},
|
|
|
+ "totals": {"sum(quantity)": 6},
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "by": {"category": "profile_duration", "outcome": "accepted", "reason": "none"},
|
|
|
+ "series": {"sum(quantity)": [0, 0, 3000]},
|
|
|
+ "totals": {"sum(quantity)": 3000},
|
|
|
},
|
|
|
{
|
|
|
"by": {
|
|
|
"category": "transaction",
|
|
|
- "reason": "spike_protection",
|
|
|
"outcome": "rate_limited",
|
|
|
+ "reason": "spike_protection",
|
|
|
},
|
|
|
- "totals": {"sum(quantity)": 1},
|
|
|
"series": {"sum(quantity)": [0, 0, 1]},
|
|
|
+ "totals": {"sum(quantity)": 1},
|
|
|
},
|
|
|
],
|
|
|
+ "intervals": ["2021-03-12T00:00:00Z", "2021-03-13T00:00:00Z", "2021-03-14T00:00:00Z"],
|
|
|
+ "start": "2021-03-12T00:00:00Z",
|
|
|
}
|
|
|
|
|
|
@freeze_time("2021-03-14T12:27:28.303Z")
|
|
@@ -543,18 +562,23 @@ class OrganizationStatsTestV2(APITestCase, OutcomesSnubaTest):
|
|
|
"groups": [
|
|
|
{
|
|
|
"by": {
|
|
|
+ "reason": "spike_protection",
|
|
|
"outcome": "rate_limited",
|
|
|
"category": "attachment",
|
|
|
- "reason": "spike_protection",
|
|
|
},
|
|
|
"totals": {"sum(quantity)": 1024, "sum(times_seen)": 1},
|
|
|
"series": {"sum(quantity)": [0, 0, 1024], "sum(times_seen)": [0, 0, 1]},
|
|
|
},
|
|
|
{
|
|
|
- "by": {"outcome": "accepted", "reason": "none", "category": "error"},
|
|
|
+ "by": {"category": "error", "reason": "none", "outcome": "accepted"},
|
|
|
"totals": {"sum(quantity)": 6, "sum(times_seen)": 6},
|
|
|
"series": {"sum(quantity)": [0, 0, 6], "sum(times_seen)": [0, 0, 6]},
|
|
|
},
|
|
|
+ {
|
|
|
+ "by": {"category": "profile_duration", "reason": "none", "outcome": "accepted"},
|
|
|
+ "totals": {"sum(quantity)": 3000, "sum(times_seen)": 3},
|
|
|
+ "series": {"sum(quantity)": [0, 0, 3000], "sum(times_seen)": [0, 0, 3]},
|
|
|
+ },
|
|
|
{
|
|
|
"by": {
|
|
|
"category": "transaction",
|
|
@@ -851,6 +875,61 @@ class OrganizationStatsTestV2(APITestCase, OutcomesSnubaTest):
|
|
|
],
|
|
|
}
|
|
|
|
|
|
+ @freeze_time("2021-03-14T12:27:28.303Z")
|
|
|
+ def test_profile_duration_filter(self):
|
|
|
+ """Test that profile_duration data is correctly filtered and returned"""
|
|
|
+ response = self.do_request(
|
|
|
+ {
|
|
|
+ "project": [-1],
|
|
|
+ "statsPeriod": "1d",
|
|
|
+ "interval": "1d",
|
|
|
+ "field": ["sum(quantity)"],
|
|
|
+ "category": ["profile_duration"],
|
|
|
+ },
|
|
|
+ status_code=200,
|
|
|
+ )
|
|
|
+
|
|
|
+ assert result_sorted(response.data) == {
|
|
|
+ "start": "2021-03-13T00:00:00Z",
|
|
|
+ "end": "2021-03-15T00:00:00Z",
|
|
|
+ "intervals": ["2021-03-13T00:00:00Z", "2021-03-14T00:00:00Z"],
|
|
|
+ "groups": [
|
|
|
+ {
|
|
|
+ "by": {},
|
|
|
+ "series": {"sum(quantity)": [0, 3000]}, # 3 outcomes * 1000ms = 3000
|
|
|
+ "totals": {"sum(quantity)": 3000},
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ }
|
|
|
+
|
|
|
+ @freeze_time("2021-03-14T12:27:28.303Z")
|
|
|
+ def test_profile_duration_groupby(self):
|
|
|
+ """Test that profile_duration data is correctly grouped"""
|
|
|
+ response = self.do_request(
|
|
|
+ {
|
|
|
+ "project": [-1],
|
|
|
+ "statsPeriod": "1d",
|
|
|
+ "interval": "1d",
|
|
|
+ "field": ["sum(quantity)"],
|
|
|
+ "groupBy": ["category"],
|
|
|
+ "category": ["profile_duration"],
|
|
|
+ },
|
|
|
+ status_code=200,
|
|
|
+ )
|
|
|
+
|
|
|
+ assert result_sorted(response.data) == {
|
|
|
+ "start": "2021-03-13T00:00:00Z",
|
|
|
+ "end": "2021-03-15T00:00:00Z",
|
|
|
+ "intervals": ["2021-03-13T00:00:00Z", "2021-03-14T00:00:00Z"],
|
|
|
+ "groups": [
|
|
|
+ {
|
|
|
+ "by": {"category": "profile_duration"},
|
|
|
+ "series": {"sum(quantity)": [0, 3000]},
|
|
|
+ "totals": {"sum(quantity)": 3000},
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
def result_sorted(result):
|
|
|
"""sort the groups of the results array by the `by` object, ensuring a stable order"""
|