-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* init commit' * Added tests * Test fix * Test fix
- Loading branch information
Showing
11 changed files
with
304 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package service | ||
|
||
import ( | ||
"github.com/devoteamnl/opendora/api/models" | ||
"github.com/devoteamnl/opendora/api/sql_client" | ||
"github.com/devoteamnl/opendora/api/sql_client/sql_queries" | ||
) | ||
|
||
type MetricMttrService struct { | ||
Client sql_client.ClientInterface | ||
} | ||
|
||
func (service MetricMttrService) ServeRequest(params ServiceParameters) (models.MetricResponse, error) { | ||
aggregationQueryMap := map[string]string{ | ||
"weekly": sql_queries.WeeklyMttrSql, | ||
"monthly": sql_queries.MonthlyMttrSql, | ||
"quarterly": sql_queries.QuarterlyMttrSql, | ||
} | ||
|
||
query := aggregationQueryMap[params.Aggregation] | ||
|
||
dataPoints, err := service.Client.QueryDeployments(query, sql_client.QueryParams{To: params.To, From: params.From, Project: params.Project}) | ||
|
||
return models.MetricResponse{Aggregation: params.Aggregation, DataPoints: dataPoints}, err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
package service | ||
|
||
import ( | ||
"fmt" | ||
"reflect" | ||
"testing" | ||
|
||
"github.com/devoteamnl/opendora/api/models" | ||
"github.com/devoteamnl/opendora/api/sql_client" | ||
"github.com/devoteamnl/opendora/api/sql_client/sql_queries" | ||
) | ||
|
||
func TestMetricMttrService_ServeRequest(t *testing.T) { | ||
|
||
exampleWeeklyDataPoints := []models.DataPoint{{Key: "202338", Value: 0}, {Key: "202337", Value: 1}, {Key: "202336", Value: 2}} | ||
exampleMonthlyDataPoints := []models.DataPoint{{Key: "23/04", Value: 6}, {Key: "23/03", Value: 5}, {Key: "23/02", Value: 4}} | ||
exampleQuarterlyDataPoints := []models.DataPoint{{Key: "2024-01-01", Value: 6}, {Key: "2023-10-01", Value: 5}, {Key: "2023-07-01", Value: 4}} | ||
|
||
dataMockMap := map[string]sql_client.MockDeploymentsDataReturn{ | ||
sql_queries.WeeklyMttrSql: {Data: exampleWeeklyDataPoints}, | ||
sql_queries.MonthlyMttrSql: {Data: exampleMonthlyDataPoints}, | ||
sql_queries.QuarterlyMttrSql: {Data: exampleQuarterlyDataPoints}} | ||
|
||
errorMockMap := map[string]sql_client.MockDeploymentsDataReturn{ | ||
sql_queries.WeeklyMttrSql: {Err: fmt.Errorf("error from weekly query")}, | ||
sql_queries.MonthlyMttrSql: {Err: fmt.Errorf("error from monthly query")}, | ||
sql_queries.QuarterlyMttrSql: {Err: fmt.Errorf("error from quarterly query")}, | ||
} | ||
|
||
tests := []struct { | ||
name string | ||
params ServiceParameters | ||
mockClient sql_client.MockClient | ||
expectResponse models.MetricResponse | ||
expectError string | ||
}{ | ||
{ | ||
name: "should return an error with an unexpected error from the database", | ||
params: ServiceParameters{TypeQuery: "mttr", Aggregation: "weekly", Project: "", To: 0, From: 0}, | ||
mockClient: sql_client.MockClient{MockDeploymentsDataMap: errorMockMap}, | ||
expectResponse: models.MetricResponse{Aggregation: "weekly", DataPoints: nil}, | ||
expectError: "error from weekly query", | ||
}, | ||
{ | ||
name: "should return an error with an unexpected error from the database", | ||
params: ServiceParameters{TypeQuery: "mttr", Aggregation: "monthly", Project: "", To: 0, From: 0}, | ||
mockClient: sql_client.MockClient{MockDeploymentsDataMap: errorMockMap}, | ||
expectResponse: models.MetricResponse{Aggregation: "monthly", DataPoints: nil}, | ||
expectError: "error from monthly query", | ||
}, | ||
{ | ||
name: "should return an error with an unexpected error from the database", | ||
params: ServiceParameters{TypeQuery: "mttr", Aggregation: "quarterly", Project: "", To: 0, From: 0}, | ||
mockClient: sql_client.MockClient{MockDeploymentsDataMap: errorMockMap}, | ||
expectResponse: models.MetricResponse{Aggregation: "quarterly", DataPoints: nil}, | ||
expectError: "error from quarterly query", | ||
}, | ||
{ | ||
name: "should return weekly data points from the database", | ||
params: ServiceParameters{TypeQuery: "mttr", Aggregation: "weekly", Project: "", To: 0, From: 0}, | ||
mockClient: sql_client.MockClient{MockDeploymentsDataMap: dataMockMap}, | ||
expectResponse: models.MetricResponse{Aggregation: "weekly", DataPoints: exampleWeeklyDataPoints}, | ||
expectError: "", | ||
}, | ||
{ | ||
name: "should return monthly data points from the database", | ||
params: ServiceParameters{TypeQuery: "mttr", Aggregation: "monthly", Project: "", To: 0, From: 0}, | ||
mockClient: sql_client.MockClient{MockDeploymentsDataMap: dataMockMap}, | ||
expectResponse: models.MetricResponse{Aggregation: "monthly", DataPoints: exampleMonthlyDataPoints}, | ||
expectError: "", | ||
}, | ||
{ | ||
name: "should return quarterly data points from the database", | ||
params: ServiceParameters{TypeQuery: "mttr", Aggregation: "quarterly", Project: "", To: 0, From: 0}, | ||
mockClient: sql_client.MockClient{MockDeploymentsDataMap: dataMockMap}, | ||
expectResponse: models.MetricResponse{Aggregation: "quarterly", DataPoints: exampleQuarterlyDataPoints}, | ||
expectError: "", | ||
}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
mttrService := MetricMttrService{Client: tt.mockClient} | ||
got, err := mttrService.ServeRequest(tt.params) | ||
|
||
if err == nil && tt.expectError != "" { | ||
t.Errorf("expected '%v' got no error", tt.expectError) | ||
} | ||
if err != nil && err.Error() != tt.expectError { | ||
t.Errorf("expected '%v' got '%v'", tt.expectError, err) | ||
} | ||
if !reflect.DeepEqual(got, tt.expectResponse) { | ||
t.Errorf("MttrService.ServeRequest() = %v, want %v", got, tt.expectResponse) | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
WITH _incidents AS ( | ||
SELECT | ||
DISTINCT i.id, | ||
DATE_FORMAT(i.created_date,'%y/%m') AS month, | ||
cast(lead_time_minutes AS signed) AS lead_time_minutes | ||
FROM | ||
issues i | ||
JOIN board_issues bi ON i.id = bi.issue_id | ||
JOIN boards b ON bi.board_id = b.id | ||
JOIN project_mapping pm ON b.id = pm.row_id AND pm.`table` = 'boards' | ||
WHERE | ||
( | ||
:project = "" | ||
OR LOWER(repos.name) LIKE CONCAT('%/', LOWER(:project)) | ||
) | ||
AND i.type = 'INCIDENT' | ||
AND i.lead_time_minutes IS NOT NULL | ||
), | ||
|
||
_find_median_mttr_each_month_ranks as( | ||
SELECT *, percent_rank() OVER(PARTITION BY month ORDER BY lead_time_minutes) AS ranks | ||
FROM _incidents | ||
), | ||
|
||
_mttr as( | ||
SELECT month, max(lead_time_minutes) AS median_time_to_resolve | ||
FROM _find_median_mttr_each_month_ranks | ||
WHERE ranks <= 0.5 | ||
GROUP BY month | ||
) | ||
|
||
SELECT | ||
cm.month AS data_key, | ||
CASE | ||
WHEN m.median_time_to_resolve IS NULL THEN 0 | ||
ELSE m.median_time_to_resolve/60 | ||
END AS data_value | ||
FROM | ||
calendar_months cm | ||
LEFT JOIN _mttr m ON cm.month = m.month | ||
WHERE cm.month_timestamp BETWEEN FROM_UNIXTIME(:from) | ||
AND FROM_UNIXTIME(:to) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
|
||
WITH RECURSIVE calendar_quarters AS ( | ||
SELECT | ||
DATE_ADD( | ||
MAKEDATE(YEAR(FROM_UNIXTIME(:from)), 1), | ||
INTERVAL QUARTER(FROM_UNIXTIME(:from)) -1 QUARTER | ||
) AS quarter_date | ||
UNION | ||
ALL | ||
SELECT | ||
DATE_ADD(quarter_date, INTERVAL 1 QUARTER) | ||
FROM | ||
calendar_quarters | ||
WHERE | ||
quarter_date < FROM_UNIXTIME(:to) | ||
), _incidents AS ( | ||
SELECT | ||
DISTINCT i.id, | ||
i.created_date AS quarter, | ||
cast(lead_time_minutes AS signed) AS lead_time_minutes | ||
FROM | ||
issues i | ||
JOIN board_issues bi ON i.id = bi.issue_id | ||
JOIN boards b ON bi.board_id = b.id | ||
JOIN project_mapping pm ON b.id = pm.row_id AND pm.`table` = 'boards' | ||
WHERE | ||
( | ||
:project = "" | ||
OR LOWER(repos.name) LIKE CONCAT('%/', LOWER(:project)) | ||
) | ||
AND i.type = 'INCIDENT' | ||
AND i.lead_time_minutes IS NOT NULL | ||
), | ||
|
||
_find_median_mttr_each_quarter_ranks as( | ||
SELECT *, percent_rank() OVER(PARTITION BY quarter ORDER BY lead_time_minutes) AS ranks | ||
FROM _incidents | ||
), | ||
|
||
_mttr as( | ||
SELECT quarter, max(lead_time_minutes) AS median_time_to_resolve | ||
FROM _find_median_mttr_each_quarter_ranks | ||
WHERE ranks <= 0.5 | ||
GROUP BY quarter | ||
) | ||
|
||
SELECT | ||
cq.quarter_date AS data_key, | ||
CASE | ||
WHEN m.median_time_to_resolve IS NULL THEN 0 | ||
ELSE m.median_time_to_resolve/60 | ||
END AS data_value | ||
FROM | ||
calendar_quarters cq | ||
LEFT JOIN _mttr m ON cq.quarter_date = m.quarter | ||
ORDER BY | ||
cq.quarter_date DESC |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
WITH RECURSIVE calendar_weeks AS ( | ||
SELECT | ||
STR_TO_DATE( | ||
CONCAT(YEARWEEK(FROM_UNIXTIME(:from)), ' Sunday'), | ||
'%X%V %W' | ||
) AS week_date | ||
UNION | ||
ALL | ||
SELECT | ||
DATE_ADD(week_date, INTERVAL 1 WEEK) | ||
FROM | ||
calendar_weeks | ||
WHERE | ||
week_date < FROM_UNIXTIME(:to) | ||
),_incidents AS ( | ||
SELECT | ||
DISTINCT i.id, | ||
YEARWEEK(i.created_date) AS week, | ||
cast(lead_time_minutes AS signed) AS lead_time_minutes | ||
FROM | ||
issues i | ||
JOIN board_issues bi ON i.id = bi.issue_id | ||
JOIN boards b ON bi.board_id = b.id | ||
JOIN project_mapping pm ON b.id = pm.row_id AND pm.`table` = 'boards' | ||
WHERE | ||
( | ||
:project = "" | ||
OR LOWER(repos.name) LIKE CONCAT('%/', LOWER(:project)) | ||
) | ||
AND i.type = 'INCIDENT' | ||
AND i.lead_time_minutes IS NOT NULL | ||
), | ||
|
||
_find_median_mttr_each_week_ranks as( | ||
SELECT *, percent_rank() OVER(PARTITION BY week ORDER BY lead_time_minutes) AS ranks | ||
FROM _incidents | ||
), | ||
|
||
_mttr as( | ||
SELECT week, max(lead_time_minutes) AS median_time_to_resolve | ||
FROM _find_median_mttr_each_week_ranks | ||
WHERE ranks <= 0.5 | ||
GROUP BY week | ||
) | ||
|
||
SELECT | ||
YEARWEEK(cw.week_date) AS data_key, | ||
CASE | ||
WHEN m.median_time_to_resolve IS NULL THEN 0 | ||
ELSE m.median_time_to_resolve/60 END AS data_value | ||
FROM | ||
calendar_weeks cw | ||
LEFT JOIN _mttr m ON YEARWEEK(cw.week_date) = m.week | ||
ORDER BY | ||
cw.week_date DESC |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters