diff --git a/.apigentools-info b/.apigentools-info index 02486825bb9..c0e6224d98e 100644 --- a/.apigentools-info +++ b/.apigentools-info @@ -4,13 +4,13 @@ "spec_versions": { "v1": { "apigentools_version": "1.2.0", - "regenerated": "2020-09-30 11:18:49.424044", - "spec_repo_commit": "cbeec4e" + "regenerated": "2020-09-30 14:10:51.893721", + "spec_repo_commit": "8738cfd" }, "v2": { "apigentools_version": "1.2.0", - "regenerated": "2020-09-30 11:18:55.050173", - "spec_repo_commit": "cbeec4e" + "regenerated": "2020-09-30 14:10:58.002512", + "spec_repo_commit": "8738cfd" } } } \ No newline at end of file diff --git a/tests/api/v2/datadog/cassettes/TestScenarios/Feature_Logs/Scenario_Aggregate_events_returns__OK__response.freeze b/tests/api/v2/datadog/cassettes/TestScenarios/Feature_Logs/Scenario_Aggregate_events_returns__OK__response.freeze new file mode 100644 index 00000000000..9b80462e35b --- /dev/null +++ b/tests/api/v2/datadog/cassettes/TestScenarios/Feature_Logs/Scenario_Aggregate_events_returns__OK__response.freeze @@ -0,0 +1 @@ +2020-09-24T10:27:02.137507+02:00 \ No newline at end of file diff --git a/tests/api/v2/datadog/cassettes/TestScenarios/Feature_Logs/Scenario_Aggregate_events_returns__OK__response.yaml b/tests/api/v2/datadog/cassettes/TestScenarios/Feature_Logs/Scenario_Aggregate_events_returns__OK__response.yaml new file mode 100644 index 00000000000..d2f8580c0d5 --- /dev/null +++ b/tests/api/v2/datadog/cassettes/TestScenarios/Feature_Logs/Scenario_Aggregate_events_returns__OK__response.yaml @@ -0,0 +1,65 @@ +--- +version: 1 +interactions: +- request: + body: | + {"compute":[{"aggregation":"count","interval":"300","metric":"test.aggregation.go-Feature_Logs-Scenario_Aggregate_events_returns__OK__response-local-1600936022","type":"timeseries"}],"filter":{"from":"1600348573","indexes":["main"],"query":"datadog-agent","to":"1600348600"}} + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + Dd-Operation-Id: + - AggregateLogs + User-Agent: + - datadog-api-client-go/1.0.0-beta.9+dev (go go1.14.1; os darwin; arch amd64) + X-Datadog-Parent-Id: + - "7918380587048278483" + X-Datadog-Sampling-Priority: + - "1" + X-Datadog-Trace-Id: + - "573202837971035806" + url: https://api.datadoghq.com/api/v2/logs/analytics/aggregate + method: POST + response: + body: '{"meta":{"status":"done","request_id":"RFRJa2YtZXZUYkdhcnBRNVZYeVdTQXwwZTVEcW9rcEpyZkZsS1NIVDhWbWt3","elapsed":0},"data":{"buckets":[]}}' + headers: + Cache-Control: + - no-cache + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Thu, 24 Sep 2020 08:27:02 GMT + Dd-Pool: + - dogweb + Pragma: + - no-cache + Set-Cookie: + - DD-PSHARD=233; Max-Age=604800; Path=/; expires=Thu, 01-Oct-2020 08:27:02 GMT; + secure; HttpOnly + Strict-Transport-Security: + - max-age=15724800; + Vary: + - Accept-Encoding + X-Content-Type-Options: + - nosniff + X-Dd-Debug: + - 1yK3PnBzCoxF/WGKEJeJqS2Jb9mutr3xDuvLdPbJCfX1HVDqeCXkaWYDO6wQpQhO + X-Dd-Version: + - "35.3086137" + X-Frame-Options: + - SAMEORIGIN + X-Ratelimit-Limit: + - "5" + X-Ratelimit-Period: + - "30" + X-Ratelimit-Remaining: + - "4" + X-Ratelimit-Reset: + - "28" + status: 200 OK + code: 200 + duration: "" diff --git a/tests/api/v2/datadog/cassettes/TestScenarios/Feature_Logs/Scenario_Get_a_list_of_logs_returns__OK__response.freeze b/tests/api/v2/datadog/cassettes/TestScenarios/Feature_Logs/Scenario_Get_a_list_of_logs_returns__OK__response.freeze new file mode 100644 index 00000000000..27a65220c15 --- /dev/null +++ b/tests/api/v2/datadog/cassettes/TestScenarios/Feature_Logs/Scenario_Get_a_list_of_logs_returns__OK__response.freeze @@ -0,0 +1 @@ +2020-09-24T10:27:01.932449+02:00 \ No newline at end of file diff --git a/tests/api/v2/datadog/cassettes/TestScenarios/Feature_Logs/Scenario_Get_a_list_of_logs_returns__OK__response.yaml b/tests/api/v2/datadog/cassettes/TestScenarios/Feature_Logs/Scenario_Get_a_list_of_logs_returns__OK__response.yaml new file mode 100644 index 00000000000..29c83dc1d65 --- /dev/null +++ b/tests/api/v2/datadog/cassettes/TestScenarios/Feature_Logs/Scenario_Get_a_list_of_logs_returns__OK__response.yaml @@ -0,0 +1,65 @@ +--- +version: 1 +interactions: +- request: + body: | + {"filter":{"from":"2020-09-17T11:48:36+01:00","indexes":["main"],"query":"datadog-agent","to":"2020-09-17T12:48:36+01:00"},"page":{"limit":5},"sort":"timestamp"} + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + Dd-Operation-Id: + - ListLogs + User-Agent: + - datadog-api-client-go/1.0.0-beta.9+dev (go go1.14.1; os darwin; arch amd64) + X-Datadog-Parent-Id: + - "4600892296438291285" + X-Datadog-Sampling-Priority: + - "1" + X-Datadog-Trace-Id: + - "7583226699408746109" + url: https://api.datadoghq.com/api/v2/logs/events/search + method: POST + response: + body: '{"data":[]}' + headers: + Cache-Control: + - no-cache + Connection: + - keep-alive + Content-Length: + - "11" + Content-Type: + - application/json + Date: + - Thu, 24 Sep 2020 08:27:02 GMT + Dd-Pool: + - dogweb + Pragma: + - no-cache + Set-Cookie: + - DD-PSHARD=233; Max-Age=604800; Path=/; expires=Thu, 01-Oct-2020 08:27:01 GMT; + secure; HttpOnly + Strict-Transport-Security: + - max-age=15724800; + X-Content-Type-Options: + - nosniff + X-Dd-Debug: + - YNPvfo/A+kRa92W7PZNTiFcSJq6YGkB9TIlX47+pHHndNDZ3ZySmub3fInFxn6Db + X-Dd-Version: + - "35.3086137" + X-Frame-Options: + - SAMEORIGIN + X-Ratelimit-Limit: + - "300" + X-Ratelimit-Period: + - "3600" + X-Ratelimit-Remaining: + - "298" + X-Ratelimit-Reset: + - "1978" + status: 200 OK + code: 200 + duration: "" diff --git a/tests/api/v2/datadog/cassettes/TestScenarios/Feature_Logs/Scenario_Get_a_quick_list_of_logs_returns__OK__response.freeze b/tests/api/v2/datadog/cassettes/TestScenarios/Feature_Logs/Scenario_Get_a_quick_list_of_logs_returns__OK__response.freeze new file mode 100644 index 00000000000..f019bed7df5 --- /dev/null +++ b/tests/api/v2/datadog/cassettes/TestScenarios/Feature_Logs/Scenario_Get_a_quick_list_of_logs_returns__OK__response.freeze @@ -0,0 +1 @@ +2020-09-24T10:27:00.796481+02:00 \ No newline at end of file diff --git a/tests/api/v2/datadog/cassettes/TestScenarios/Feature_Logs/Scenario_Get_a_quick_list_of_logs_returns__OK__response.yaml b/tests/api/v2/datadog/cassettes/TestScenarios/Feature_Logs/Scenario_Get_a_quick_list_of_logs_returns__OK__response.yaml new file mode 100644 index 00000000000..cb82319c113 --- /dev/null +++ b/tests/api/v2/datadog/cassettes/TestScenarios/Feature_Logs/Scenario_Get_a_quick_list_of_logs_returns__OK__response.yaml @@ -0,0 +1,62 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Dd-Operation-Id: + - ListLogsGet + User-Agent: + - datadog-api-client-go/1.0.0-beta.9+dev (go go1.14.1; os darwin; arch amd64) + X-Datadog-Parent-Id: + - "4883115807099481994" + X-Datadog-Sampling-Priority: + - "1" + X-Datadog-Trace-Id: + - "3201576817382276682" + url: https://api.datadoghq.com/api/v2/logs/events?filter%5Bfrom%5D=2020-09-17T11%3A48%3A36%2B01%3A00&filter%5Bindex%5D=main&filter%5Bquery%5D=datadog-agent&filter%5Bto%5D=2020-09-17T12%3A48%3A36%2B01%3A00&page%5Blimit%5D=5 + method: GET + response: + body: '{"data":[]}' + headers: + Cache-Control: + - no-cache + Connection: + - keep-alive + Content-Length: + - "11" + Content-Type: + - application/json + Date: + - Thu, 24 Sep 2020 08:27:01 GMT + Dd-Pool: + - dogweb + Pragma: + - no-cache + Set-Cookie: + - DD-PSHARD=233; Max-Age=604800; Path=/; expires=Thu, 01-Oct-2020 08:27:01 GMT; + secure; HttpOnly + Strict-Transport-Security: + - max-age=15724800; + X-Content-Type-Options: + - nosniff + X-Dd-Debug: + - iGG1BKNRTmPfZ6ji2H3Z/xn9c4eIM8cOugS+JJDlp5xOVDa6tvCgtO3MGJFoLiiG + X-Dd-Version: + - "35.3086137" + X-Frame-Options: + - SAMEORIGIN + X-Ratelimit-Limit: + - "300" + X-Ratelimit-Period: + - "3600" + X-Ratelimit-Remaining: + - "299" + X-Ratelimit-Reset: + - "1979" + status: 200 OK + code: 200 + duration: "" diff --git a/tests/api/v2/datadog/features/logs.feature b/tests/api/v2/datadog/features/logs.feature index de0d6918879..43e5f6b0798 100644 --- a/tests/api/v2/datadog/features/logs.feature +++ b/tests/api/v2/datadog/features/logs.feature @@ -8,25 +8,27 @@ Feature: Logs And a valid "appKeyAuth" key in the system And an instance of "Logs" API - @generated @skip Scenario: Get a quick list of logs returns "OK" response Given operation "ListLogsGet" enabled And new "ListLogsGet" request + And request contains "filter[query]" parameter with value "datadog-agent" + And request contains "filter[index]" parameter with value "main" + And request contains "filter[from]" parameter with value "2020-09-17T11:48:36+01:00" + And request contains "filter[to]" parameter with value "2020-09-17T12:48:36+01:00" + And request contains "page[limit]" parameter with value 5 When the request is sent Then the response status is 200 OK - @generated @skip Scenario: Get a list of logs returns "OK" response Given operation "ListLogs" enabled And new "ListLogs" request - And body {} + And body {"filter": {"query": "datadog-agent", "indexes": ["main"], "from": "2020-09-17T11:48:36+01:00", "to": "2020-09-17T12:48:36+01:00"}, "sort": "timestamp", "page": {"limit": 5}} When the request is sent Then the response status is 200 OK - @generated @skip Scenario: Aggregate events returns "OK" response Given operation "AggregateLogs" enabled And new "AggregateLogs" request - And body {} + And body {"compute": [{"aggregation": "count", "interval": "300", "metric": "test.aggregation.{{ unique }}", "type": "timeseries"}], "filter": {"from": "1600348573", "indexes": ["main"], "query": "datadog-agent", "to": "1600348600"}} When the request is sent Then the response status is 200 OK diff --git a/tests/api/v2/datadog/scenarios_test.go b/tests/api/v2/datadog/scenarios_test.go index 2b624ae08ce..31a013f8116 100644 --- a/tests/api/v2/datadog/scenarios_test.go +++ b/tests/api/v2/datadog/scenarios_test.go @@ -46,6 +46,7 @@ func undoCreateTeam(ctx gobdd.Context) { var requestsUndo = map[string]func(ctx gobdd.Context){ "AddPermissionToRole": undoIgnore, "AddUserToRole": undoIgnore, + "AggregateLogs": undoIgnore, "CreateRole": undoCreateRole, "CreateService": undoCreateService, "CreateTeam": undoCreateTeam, @@ -61,6 +62,8 @@ var requestsUndo = map[string]func(ctx gobdd.Context){ "GetTeam": undoIgnore, "GetTeams": undoIgnore, "GetUser": undoIgnore, + "ListLogs": undoIgnore, + "ListLogsGet": undoIgnore, "ListPermissions": undoIgnore, "ListRolePermissions": undoIgnore, "ListRoles": undoIgnore, @@ -112,6 +115,13 @@ func TestScenarios(t *testing.T) { tracer.SpanType("step"), tracer.ResourceName(parts[len(parts)-1]), ) + + testName := strings.Join(strings.Split(ct.(*testing.T).Name(), "/")[1:3], "/") + unique := tests.WithUniqueSurrounding(cctx, testName) + data := tests.GetData(ctx) + data["unique"] = unique + data["unique_lower"] = strings.ToLower(unique) + tests.SetCtx(ctx, cctx) }), gobdd.WithAfterStep(func(ctx gobdd.Context) { diff --git a/tests/scenarios.go b/tests/scenarios.go index c5a08008df9..2bba430fd6d 100644 --- a/tests/scenarios.go +++ b/tests/scenarios.go @@ -17,7 +17,6 @@ import ( "sort" "strconv" "strings" - "testing" "github.com/go-bdd/gobdd" "github.com/mcuadros/go-lookup" @@ -171,6 +170,25 @@ func newRequest(t gobdd.StepTest, ctx gobdd.Context, name string) { ctx.Set(requestArgsKey{}, make([]interface{}, 0)) } +// getRequestBuilder returns the reflect value of the current request in ctx +func getRequestBuilder(ctx gobdd.Context) (reflect.Value, error) { + c, err := ctx.Get(requestKey{}) + if err != nil { + return reflect.Value{}, fmt.Errorf("Missing requestKey{}") + } + f := c.(reflect.Value) + + in := make([]reflect.Value, f.Type().NumIn()) + + // first argument is always context.Context + in[0] = reflect.ValueOf(GetCtx(ctx)) + for i := 1; i < f.Type().NumIn(); i++ { + object := GetRequestArguments(ctx)[i-1] + in[i] = object.(reflect.Value) + } + return f.Call(in)[0], nil +} + func statusIs(t gobdd.StepTest, ctx gobdd.Context, expected int, text string) { // Execute() returns tripples -> 2nd value is *http.Response -> get StatusCode resp := GetResponse(ctx) @@ -189,28 +207,37 @@ func addParameterFrom(t gobdd.StepTest, ctx gobdd.Context, name string, path str ctx.Set(requestArgsKey{}, append(GetRequestArguments(ctx), value)) } -func requestIsSent(t gobdd.StepTest, ctx gobdd.Context) { - c, err := ctx.Get(requestKey{}) +func addParameterWithValue(t gobdd.StepTest, ctx gobdd.Context, param string, value string) { + // Get request builder for the current scenario + request, err := getRequestBuilder(ctx) if err != nil { - t.Error("Missing requestKey{}") + t.Error(err) } - f := c.(reflect.Value) + name := ToVarName(param) + // Get the method for setting the current parameter + method := request.MethodByName(name) - requestParameters := GetRequestParameters(ctx) - in := make([]reflect.Value, f.Type().NumIn()) + templatedValue := Templated(GetData(ctx), value) - // first argument is always context.Context - in[0] = reflect.ValueOf(GetCtx(ctx)) + if method.IsValid() { + at := reflect.New(method.Type().In(0)) + // Unmarshall the value specified in the step to the proper type and add it to the parameters + json.Unmarshal([]byte(templatedValue), at.Interface()) + GetRequestParameters(ctx)[param] = at.Elem() + } +} - for i := 1; i < f.Type().NumIn(); i++ { - object := GetRequestArguments(ctx)[i-1] - in[i] = object.(reflect.Value) +func requestIsSent(t gobdd.StepTest, ctx gobdd.Context) { + + request, err := getRequestBuilder(ctx) + if err != nil { + t.Error(err) } - request := f.Call(in)[0] + requestParameters := GetRequestParameters(ctx) for param, value := range requestParameters { - name := SnakeToCamelCase(param) + name := ToVarName(param) method := request.MethodByName(name) if method.IsValid() { if param == "body" { @@ -240,12 +267,7 @@ func requestIsSent(t gobdd.StepTest, ctx gobdd.Context) { } func body(t gobdd.StepTest, ctx gobdd.Context, body string) { - data := GetData(ctx) - name := strings.Join(strings.Split(t.(*testing.T).Name(), "/")[1:3], "/") - unique := WithUniqueSurrounding(GetCtx(ctx), name) - data["unique"] = unique - data["unique_lower"] = strings.ToLower(unique) - GetRequestParameters(ctx)["body"] = Templated(data, body) + GetRequestParameters(ctx)["body"] = Templated(GetData(ctx), body) } func stringToType(s string, t interface{}) (interface{}, error) { @@ -326,6 +348,7 @@ func ConfigureSteps(s *gobdd.Suite) { steps := map[string]interface{}{ `new "([^"]+)" request`: newRequest, `request contains "([^"]+)" parameter from "([^"]+)"`: addParameterFrom, + `request contains "([^"]+)" parameter with value (.+)`: addParameterWithValue, `the request is sent`: requestIsSent, `the response status is (\d+) (.*)`: statusIs, `body (.*)`: body, diff --git a/tests/test_utils.go b/tests/test_utils.go index a78bf25dcf1..0e05f2f7047 100644 --- a/tests/test_utils.go +++ b/tests/test_utils.go @@ -17,6 +17,7 @@ import ( "net/url" "os" "path/filepath" + "regexp" "runtime" "strings" "testing" @@ -140,6 +141,26 @@ func SnakeToCamelCase(snake string) (camel string) { return } +func ToVarName(param string) (varName string) { + isToUpper := true + + for _, v := range param { + if isToUpper { + varName += strings.ToUpper(string(v)) + isToUpper = false + } else { + if v == '_' { + isToUpper = true + } else if m, _ := regexp.Match("[()\\[\\].]", []byte{byte(v)}); m { + isToUpper = true + } else { + varName += string(v) + } + } + } + return +} + // Retry calls the call function for count times every interval while it returns false func Retry(interval time.Duration, count int, call func() bool) error { for i := 0; i < count; i++ {