diff --git a/api/openapi.yaml b/api/openapi.yaml index c414643..fe7456f 100644 --- a/api/openapi.yaml +++ b/api/openapi.yaml @@ -6,6 +6,31 @@ info: servers: - url: /api paths: + # Health + /healthz: + get: + summary: Health Check + responses: + '200': + description: Service is healthy + content: + application/json: + schema: + type: object + properties: + status: + type: string + example: "ok" + '500': + description: Service is unhealthy + content: + application/json: + schema: + type: object + properties: + status: + type: string + example: "unhealthy" # TestSuites /testsuites: get: diff --git a/charts/qualitytrace/Chart.yaml b/charts/qualitytrace/Chart.yaml index fcf7053..6fe929a 100644 --- a/charts/qualitytrace/Chart.yaml +++ b/charts/qualitytrace/Chart.yaml @@ -8,4 +8,4 @@ dependencies: description: A Helm chart for QualityTrace name: qualitytrace type: application -version: 1.0.0 +version: 1.0.1 diff --git a/charts/qualitytrace/templates/deployment.yaml b/charts/qualitytrace/templates/deployment.yaml index a0d07ac..ff3ada7 100644 --- a/charts/qualitytrace/templates/deployment.yaml +++ b/charts/qualitytrace/templates/deployment.yaml @@ -68,14 +68,14 @@ spec: - name: otlp-http containerPort: {{ .Values.server.otlpHttpPort }} protocol: TCP - # livenessProbe: - # httpGet: - # path: {{ include "qualitytrace.pathPrefix" . }} - # port: http - # readinessProbe: - # httpGet: - # path: {{ include "qualitytrace.pathPrefix" . }} - # port: http + livenessProbe: + httpGet: + path: {{ include "qualitytrace.pathPrefix" . }}healthz + port: http + readinessProbe: + httpGet: + path: {{ include "qualitytrace.pathPrefix" . }}healthz + port: http resources: {{- toYaml .Values.resources | nindent 12 }} volumeMounts: diff --git a/cli/openapi/api_default.go b/cli/openapi/api_default.go new file mode 100644 index 0000000..f50cee9 --- /dev/null +++ b/cli/openapi/api_default.go @@ -0,0 +1,130 @@ +/* +TraceTest + +OpenAPI definition for TraceTest endpoint and resources + +API version: 0.2.1 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "bytes" + "context" + "io/ioutil" + "net/http" + "net/url" +) + +// DefaultApiService DefaultApi service +type DefaultApiService service + +type ApiHealthzGetRequest struct { + ctx context.Context + ApiService *DefaultApiService +} + +func (r ApiHealthzGetRequest) Execute() (*HealthzGet200Response, *http.Response, error) { + return r.ApiService.HealthzGetExecute(r) +} + +/* +HealthzGet Health Check + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiHealthzGetRequest +*/ +func (a *DefaultApiService) HealthzGet(ctx context.Context) ApiHealthzGetRequest { + return ApiHealthzGetRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// +// @return HealthzGet200Response +func (a *DefaultApiService) HealthzGetExecute(r ApiHealthzGetRequest) (*HealthzGet200Response, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *HealthzGet200Response + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "DefaultApiService.HealthzGet") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/healthz" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := ioutil.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = ioutil.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 500 { + var v HealthzGet500Response + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} diff --git a/cli/openapi/client.go b/cli/openapi/client.go index f9a3836..1fdeeab 100644 --- a/cli/openapi/client.go +++ b/cli/openapi/client.go @@ -51,6 +51,8 @@ type APIClient struct { ApiApi *ApiApiService + DefaultApi *DefaultApiService + ResourceApiApi *ResourceApiApiService } @@ -71,6 +73,7 @@ func NewAPIClient(cfg *Configuration) *APIClient { // API Services c.ApiApi = (*ApiApiService)(&c.common) + c.DefaultApi = (*DefaultApiService)(&c.common) c.ResourceApiApi = (*ResourceApiApiService)(&c.common) return c diff --git a/cli/openapi/model__healthz_get_200_response.go b/cli/openapi/model__healthz_get_200_response.go new file mode 100644 index 0000000..358c5e5 --- /dev/null +++ b/cli/openapi/model__healthz_get_200_response.go @@ -0,0 +1,124 @@ +/* +TraceTest + +OpenAPI definition for TraceTest endpoint and resources + +API version: 0.2.1 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the HealthzGet200Response type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &HealthzGet200Response{} + +// HealthzGet200Response struct for HealthzGet200Response +type HealthzGet200Response struct { + Status *string `json:"status,omitempty"` +} + +// NewHealthzGet200Response instantiates a new HealthzGet200Response object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewHealthzGet200Response() *HealthzGet200Response { + this := HealthzGet200Response{} + return &this +} + +// NewHealthzGet200ResponseWithDefaults instantiates a new HealthzGet200Response object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewHealthzGet200ResponseWithDefaults() *HealthzGet200Response { + this := HealthzGet200Response{} + return &this +} + +// GetStatus returns the Status field value if set, zero value otherwise. +func (o *HealthzGet200Response) GetStatus() string { + if o == nil || isNil(o.Status) { + var ret string + return ret + } + return *o.Status +} + +// GetStatusOk returns a tuple with the Status field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HealthzGet200Response) GetStatusOk() (*string, bool) { + if o == nil || isNil(o.Status) { + return nil, false + } + return o.Status, true +} + +// HasStatus returns a boolean if a field has been set. +func (o *HealthzGet200Response) HasStatus() bool { + if o != nil && !isNil(o.Status) { + return true + } + + return false +} + +// SetStatus gets a reference to the given string and assigns it to the Status field. +func (o *HealthzGet200Response) SetStatus(v string) { + o.Status = &v +} + +func (o HealthzGet200Response) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o HealthzGet200Response) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !isNil(o.Status) { + toSerialize["status"] = o.Status + } + return toSerialize, nil +} + +type NullableHealthzGet200Response struct { + value *HealthzGet200Response + isSet bool +} + +func (v NullableHealthzGet200Response) Get() *HealthzGet200Response { + return v.value +} + +func (v *NullableHealthzGet200Response) Set(val *HealthzGet200Response) { + v.value = val + v.isSet = true +} + +func (v NullableHealthzGet200Response) IsSet() bool { + return v.isSet +} + +func (v *NullableHealthzGet200Response) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableHealthzGet200Response(val *HealthzGet200Response) *NullableHealthzGet200Response { + return &NullableHealthzGet200Response{value: val, isSet: true} +} + +func (v NullableHealthzGet200Response) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableHealthzGet200Response) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/cli/openapi/model__healthz_get_500_response.go b/cli/openapi/model__healthz_get_500_response.go new file mode 100644 index 0000000..3eac63b --- /dev/null +++ b/cli/openapi/model__healthz_get_500_response.go @@ -0,0 +1,124 @@ +/* +TraceTest + +OpenAPI definition for TraceTest endpoint and resources + +API version: 0.2.1 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the HealthzGet500Response type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &HealthzGet500Response{} + +// HealthzGet500Response struct for HealthzGet500Response +type HealthzGet500Response struct { + Status *string `json:"status,omitempty"` +} + +// NewHealthzGet500Response instantiates a new HealthzGet500Response object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewHealthzGet500Response() *HealthzGet500Response { + this := HealthzGet500Response{} + return &this +} + +// NewHealthzGet500ResponseWithDefaults instantiates a new HealthzGet500Response object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewHealthzGet500ResponseWithDefaults() *HealthzGet500Response { + this := HealthzGet500Response{} + return &this +} + +// GetStatus returns the Status field value if set, zero value otherwise. +func (o *HealthzGet500Response) GetStatus() string { + if o == nil || isNil(o.Status) { + var ret string + return ret + } + return *o.Status +} + +// GetStatusOk returns a tuple with the Status field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *HealthzGet500Response) GetStatusOk() (*string, bool) { + if o == nil || isNil(o.Status) { + return nil, false + } + return o.Status, true +} + +// HasStatus returns a boolean if a field has been set. +func (o *HealthzGet500Response) HasStatus() bool { + if o != nil && !isNil(o.Status) { + return true + } + + return false +} + +// SetStatus gets a reference to the given string and assigns it to the Status field. +func (o *HealthzGet500Response) SetStatus(v string) { + o.Status = &v +} + +func (o HealthzGet500Response) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o HealthzGet500Response) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !isNil(o.Status) { + toSerialize["status"] = o.Status + } + return toSerialize, nil +} + +type NullableHealthzGet500Response struct { + value *HealthzGet500Response + isSet bool +} + +func (v NullableHealthzGet500Response) Get() *HealthzGet500Response { + return v.value +} + +func (v *NullableHealthzGet500Response) Set(val *HealthzGet500Response) { + v.value = val + v.isSet = true +} + +func (v NullableHealthzGet500Response) IsSet() bool { + return v.isSet +} + +func (v *NullableHealthzGet500Response) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableHealthzGet500Response(val *HealthzGet500Response) *NullableHealthzGet500Response { + return &NullableHealthzGet500Response{value: val, isSet: true} +} + +func (v NullableHealthzGet500Response) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableHealthzGet500Response) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/docker-compose.yaml b/docker-compose.yaml index 228c96b..7b7cd54 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -18,7 +18,7 @@ services: - 11633:11633 command: --provisioning-file /app/provisioning.yaml healthcheck: - test: ["CMD", "wget", "--spider", "localhost:11633"] + test: ["CMD", "wget", "--spider", "localhost:11633/healthz"] interval: 1s timeout: 3s retries: 60 diff --git a/server/app/app.go b/server/app/app.go index 585c022..057f600 100644 --- a/server/app/app.go +++ b/server/app/app.go @@ -7,6 +7,7 @@ import ( "log" "net/http" "os" + "encoding/json" "github.com/gorilla/handlers" "github.com/gorilla/mux" @@ -356,8 +357,8 @@ func (app *App) Start(opts ...appOption) error { registerTestRunner(testRunnerRepo, apiRouter, provisioner, tracer) registerTestResource(testRepo, apiRouter, provisioner, tracer) - isQualitytraceDev := os.Getenv("QUALITYTRACE_DEV") != "" - registerSPAHandler(router, app.cfg, configFromDB.IsAnalyticsEnabled(), serverID, isQualitytraceDev) + isTracetestDev := os.Getenv("TRACETEST_DEV") != "" + registerSPAHandler(router, app.cfg, configFromDB.IsAnalyticsEnabled(), serverID, isTracetestDev) if isNewInstall { provision(provisioner, app.provisioningFile) @@ -379,7 +380,7 @@ func (app *App) Start(opts ...appOption) error { return nil } -func registerSPAHandler(router *mux.Router, cfg httpServerConfig, analyticsEnabled bool, serverID string, isQualitytraceDev bool) { +func registerSPAHandler(router *mux.Router, cfg httpServerConfig, analyticsEnabled bool, serverID string, isTracetestDev bool) { router. PathPrefix(cfg.ServerPathPrefix()). Handler( @@ -389,7 +390,7 @@ func registerSPAHandler(router *mux.Router, cfg httpServerConfig, analyticsEnabl serverID, version.Version, version.Env, - isQualitytraceDev, + isTracetestDev, ), ) } @@ -551,6 +552,12 @@ func registerWSHandler(router *mux.Router, mappers mappings.Mappings, subscripti router.Handle("/ws", wsRouter.Handler()) } +func healthCheckHandler(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + response := map[string]string{"status": "ok"} + json.NewEncoder(w).Encode(response) +} + func controller( cfg httpServerConfig, @@ -596,6 +603,8 @@ func controller( mappers, )) + // Register the /healthz endpoint + router.HandleFunc("/healthz", healthCheckHandler).Methods("GET") return router, mappers } diff --git a/server/app/test_pipeline.go b/server/app/test_pipeline.go index 449584e..fb59959 100644 --- a/server/app/test_pipeline.go +++ b/server/app/test_pipeline.go @@ -1,7 +1,6 @@ package app import ( - "github.com/jackc/pgx/v5/pgxpool" "github.com/intelops/qualitytrace/agent/tracedb" "github.com/intelops/qualitytrace/server/config" "github.com/intelops/qualitytrace/server/datastore" @@ -16,6 +15,7 @@ import ( "github.com/intelops/qualitytrace/server/subscription" "github.com/intelops/qualitytrace/server/test" "github.com/intelops/qualitytrace/server/testconnection" + "github.com/jackc/pgx/v5/pgxpool" "go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/trace" ) diff --git a/server/executor/poller_executor_test.go b/server/executor/poller_executor_test.go index e62d8b0..6ac15ef 100644 --- a/server/executor/poller_executor_test.go +++ b/server/executor/poller_executor_test.go @@ -152,7 +152,7 @@ func Test_PollerExecutor_ExecuteRequest_NoRootSpan_TwoSpansCase(t *testing.T) { StartTime: firstSpan.EndTime, EndTime: firstSpan.EndTime.Add(retryDelay), Attributes: traces.NewAttributes(map[string]string{ - "testSpan": "true", + "testSpan": "true", traces.QualitytraceMetadataFieldParentID: firstSpan.ID.String(), }), Children: []*traces.Span{}, @@ -268,7 +268,7 @@ func Test_PollerExecutor_ExecuteRequest_WithRootSpan_OneSpanCase(t *testing.T) { StartTime: time.Now(), EndTime: time.Now().Add(retryDelay), Attributes: traces.NewAttributes(map[string]string{ - "testSpan": "true", + "testSpan": "true", traces.QualitytraceMetadataFieldParentID: rootSpanID.String(), }), Children: []*traces.Span{}, @@ -329,7 +329,7 @@ func Test_PollerExecutor_ExecuteRequest_WithRootSpan_OneDelayedSpanCase(t *testi StartTime: time.Now(), EndTime: time.Now().Add(retryDelay), Attributes: traces.NewAttributes(map[string]string{ - "testSpan": "true", + "testSpan": "true", traces.QualitytraceMetadataFieldParentID: rootSpan.ID.String(), }), Children: []*traces.Span{}, @@ -398,7 +398,7 @@ func Test_PollerExecutor_ExecuteRequest_WithRootSpan_TwoSpansCase(t *testing.T) StartTime: time.Now(), EndTime: time.Now().Add(retryDelay), Attributes: traces.NewAttributes(map[string]string{ - "testSpan": "true", + "testSpan": "true", traces.QualitytraceMetadataFieldParentID: rootSpan.ID.String(), }), Children: []*traces.Span{}, @@ -410,7 +410,7 @@ func Test_PollerExecutor_ExecuteRequest_WithRootSpan_TwoSpansCase(t *testing.T) StartTime: firstSpan.EndTime, EndTime: firstSpan.EndTime.Add(retryDelay), Attributes: traces.NewAttributes(map[string]string{ - "testSpan": "true", + "testSpan": "true", traces.QualitytraceMetadataFieldParentID: firstSpan.ID.String(), }), Children: []*traces.Span{}, diff --git a/server/openapi/api.go b/server/openapi/api.go index 5a58865..d525224 100644 --- a/server/openapi/api.go +++ b/server/openapi/api.go @@ -54,6 +54,13 @@ type ApiApiRouter interface { UpdateWizard(http.ResponseWriter, *http.Request) } +// DefaultApiRouter defines the required methods for binding the api requests to a responses for the DefaultApi +// The DefaultApiRouter implementation should parse necessary information from the http request, +// pass the data to a DefaultApiServicer to perform the required actions, then write the service results to the http response. +type DefaultApiRouter interface { + HealthzGet(http.ResponseWriter, *http.Request) +} + // ResourceApiApiRouter defines the required methods for binding the api requests to a responses for the ResourceApiApi // The ResourceApiApiRouter implementation should parse necessary information from the http request, // pass the data to a ResourceApiApiServicer to perform the required actions, then write the service results to the http response. @@ -136,6 +143,14 @@ type ApiApiServicer interface { UpdateWizard(context.Context, Wizard) (ImplResponse, error) } +// DefaultApiServicer defines the api actions for the DefaultApi service +// This interface intended to stay up to date with the openapi yaml used to generate it, +// while the service implementation can be ignored with the .openapi-generator-ignore file +// and updated with the logic required for the API. +type DefaultApiServicer interface { + HealthzGet(context.Context) (ImplResponse, error) +} + // ResourceApiApiServicer defines the api actions for the ResourceApiApi service // This interface intended to stay up to date with the openapi yaml used to generate it, // while the service implementation can be ignored with the .openapi-generator-ignore file diff --git a/server/openapi/api_default.go b/server/openapi/api_default.go new file mode 100644 index 0000000..eb3827c --- /dev/null +++ b/server/openapi/api_default.go @@ -0,0 +1,73 @@ +/* + * TraceTest + * + * OpenAPI definition for TraceTest endpoint and resources + * + * API version: 0.2.1 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +import ( + // "encoding/json" + "net/http" + "strings" + + // "github.com/gorilla/mux" +) + +// DefaultApiController binds http requests to an api service and writes the service results to the http response +type DefaultApiController struct { + service DefaultApiServicer + errorHandler ErrorHandler +} + +// DefaultApiOption for how the controller is set up. +type DefaultApiOption func(*DefaultApiController) + +// WithDefaultApiErrorHandler inject ErrorHandler into controller +func WithDefaultApiErrorHandler(h ErrorHandler) DefaultApiOption { + return func(c *DefaultApiController) { + c.errorHandler = h + } +} + +// NewDefaultApiController creates a default api controller +func NewDefaultApiController(s DefaultApiServicer, opts ...DefaultApiOption) Router { + controller := &DefaultApiController{ + service: s, + errorHandler: DefaultErrorHandler, + } + + for _, opt := range opts { + opt(controller) + } + + return controller +} + +// Routes returns all the api routes for the DefaultApiController +func (c *DefaultApiController) Routes() Routes { + return Routes{ + { + "HealthzGet", + strings.ToUpper("Get"), + "/api/healthz", + c.HealthzGet, + }, + } +} + +// HealthzGet - Health Check +func (c *DefaultApiController) HealthzGet(w http.ResponseWriter, r *http.Request) { + result, err := c.service.HealthzGet(r.Context()) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) + +} diff --git a/server/openapi/api_default_service.go b/server/openapi/api_default_service.go new file mode 100644 index 0000000..9c60a7c --- /dev/null +++ b/server/openapi/api_default_service.go @@ -0,0 +1,45 @@ +/* + * TraceTest + * + * OpenAPI definition for TraceTest endpoint and resources + * + * API version: 0.2.1 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +import ( + "context" + "encoding/json" + "net/http" +) + +// DefaultApiService is a service that implements the logic for the DefaultApiServicer +// This service should implement the business logic for every endpoint for the DefaultApi API. +// Include any external packages or services that will be required by this service. +type DefaultApiService struct { +} + +// NewDefaultApiService creates a default api service +func NewDefaultApiService() DefaultApiServicer { + return &DefaultApiService{} +} + +// HealthzGet - Health Check +func (s *DefaultApiService) HealthzGet(ctx context.Context) (ImplResponse, error) { + healthStatus := HealthzGet200Response{ + Status: "ok", + } + + responseBody, err := json.Marshal(healthStatus) + if err != nil { + errorStatus := HealthzGet500Response{ + Status: "error", + } + errorBody, _ := json.Marshal(errorStatus) + return Response(http.StatusInternalServerError, errorBody), err + } + + return Response(http.StatusOK, responseBody), nil +} \ No newline at end of file diff --git a/server/openapi/model__healthz_get_200_response.go b/server/openapi/model__healthz_get_200_response.go new file mode 100644 index 0000000..ce42a3b --- /dev/null +++ b/server/openapi/model__healthz_get_200_response.go @@ -0,0 +1,31 @@ +/* + * TraceTest + * + * OpenAPI definition for TraceTest endpoint and resources + * + * API version: 0.2.1 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +type HealthzGet200Response struct { + Status string `json:"status,omitempty"` +} + +// AssertHealthzGet200ResponseRequired checks if the required fields are not zero-ed +func AssertHealthzGet200ResponseRequired(obj HealthzGet200Response) error { + return nil +} + +// AssertRecurseHealthzGet200ResponseRequired recursively checks if required fields are not zero-ed in a nested slice. +// Accepts only nested slice of HealthzGet200Response (e.g. [][]HealthzGet200Response), otherwise ErrTypeAssertionError is thrown. +func AssertRecurseHealthzGet200ResponseRequired(objSlice interface{}) error { + return AssertRecurseInterfaceRequired(objSlice, func(obj interface{}) error { + aHealthzGet200Response, ok := obj.(HealthzGet200Response) + if !ok { + return ErrTypeAssertionError + } + return AssertHealthzGet200ResponseRequired(aHealthzGet200Response) + }) +} diff --git a/server/openapi/model__healthz_get_500_response.go b/server/openapi/model__healthz_get_500_response.go new file mode 100644 index 0000000..8d4219d --- /dev/null +++ b/server/openapi/model__healthz_get_500_response.go @@ -0,0 +1,31 @@ +/* + * TraceTest + * + * OpenAPI definition for TraceTest endpoint and resources + * + * API version: 0.2.1 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +type HealthzGet500Response struct { + Status string `json:"status,omitempty"` +} + +// AssertHealthzGet500ResponseRequired checks if the required fields are not zero-ed +func AssertHealthzGet500ResponseRequired(obj HealthzGet500Response) error { + return nil +} + +// AssertRecurseHealthzGet500ResponseRequired recursively checks if required fields are not zero-ed in a nested slice. +// Accepts only nested slice of HealthzGet500Response (e.g. [][]HealthzGet500Response), otherwise ErrTypeAssertionError is thrown. +func AssertRecurseHealthzGet500ResponseRequired(objSlice interface{}) error { + return AssertRecurseInterfaceRequired(objSlice, func(obj interface{}) error { + aHealthzGet500Response, ok := obj.(HealthzGet500Response) + if !ok { + return ErrTypeAssertionError + } + return AssertHealthzGet500ResponseRequired(aHealthzGet500Response) + }) +} diff --git a/server/test/test_repository.go b/server/test/test_repository.go index 6eef984..9f219c2 100644 --- a/server/test/test_repository.go +++ b/server/test/test_repository.go @@ -208,7 +208,7 @@ func (r *repository) GetTestSuiteSteps(ctx context.Context, id id.ID, version in sortQuery := ` ORDER BY ts.step_number ASC` query, params := sqlutil.TenantWithPrefix(ctx, getTestSQL+testMaxVersionQuery+` INNER JOIN test_suite_steps ts ON t.id = ts.test_id WHERE ts.test_suite_id = $1 AND ts.test_suite_version = $2`, "t.", id, version) - stmt, err := r.db.Prepare(query + " "+sortQuery) + stmt, err := r.db.Prepare(query + " " + sortQuery) if err != nil { return []Test{}, fmt.Errorf("prepare 2: %w", err) } diff --git a/server/testsuite/testsuite_run_repository.go b/server/testsuite/testsuite_run_repository.go index 2ea4280..9e17026 100644 --- a/server/testsuite/testsuite_run_repository.go +++ b/server/testsuite/testsuite_run_repository.go @@ -340,7 +340,7 @@ func (td *RunRepository) GetTestSuiteRun(ctx context.Context, ID id.ID, runID in func (td *RunRepository) GetLatestRunByTestSuiteVersion(ctx context.Context, ID id.ID, version int) (TestSuiteRun, error) { sortQuery := " ORDER BY created_at DESC LIMIT 1" query, params := sqlutil.Tenant(ctx, selectTestSuiteRunQuery+" WHERE test_suite_id = $1 AND test_suite_version = $2", ID, version) - stmt, err := td.db.Prepare(query +" "+sortQuery) + stmt, err := td.db.Prepare(query + " " + sortQuery) if err != nil { return TestSuiteRun{}, fmt.Errorf("prepare: %w", err) } @@ -359,7 +359,7 @@ func (td *RunRepository) GetLatestRunByTestSuiteVersion(ctx context.Context, ID func (td *RunRepository) GetTestSuiteRuns(ctx context.Context, ID id.ID, take, skip int32) ([]TestSuiteRun, error) { sortQuery := " ORDER BY created_at DESC LIMIT $2 OFFSET $3" query, params := sqlutil.Tenant(ctx, selectTestSuiteRunQuery+" WHERE test_suite_id = $1", ID.String(), take, skip) - stmt, err := td.db.Prepare(query +" "+ sortQuery) + stmt, err := td.db.Prepare(query + " " + sortQuery) if err != nil { return []TestSuiteRun{}, fmt.Errorf("prepare: %w", err) }