Documentation in literate-programming-style is available at:
https://redhatinsights.github.io/ccx-notification-service/packages/producer/servicelog/servicelogproducer_test.html
|
import (
"encoding/json"
"errors"
"io"
"net/http"
"net/http/httptest"
"testing"
"time"
"github.com/RedHatInsights/ccx-notification-service/conf"
"github.com/RedHatInsights/ccx-notification-service/tests/mocks"
"github.com/RedHatInsights/ccx-notification-service/types"
"github.com/RedHatInsights/insights-operator-utils/tests/helpers"
"github.com/rs/zerolog/log"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
func setupMockOCMGateway ( ) * mocks . OCMClient {
gateway := mocks . OCMClient { }
gateway . On ( "GetTokens" ,
mock . AnythingOfType ( "time.Duration" ) ) . Return (
func ( delay time . Duration ) string {
return "online_token"
} ,
func ( delay time . Duration ) string {
return "refresh_token"
} ,
func ( delay time . Duration ) error {
return nil
} ,
)
return & gateway
}
func setupMockOCMGatewayWithError ( ) * mocks . OCMClient {
gateway := mocks . OCMClient { }
gateway . On ( "GetTokens" ,
mock . AnythingOfType ( "time.Duration" ) ) . Return (
func ( delay time . Duration ) string {
return "online_token"
} ,
func ( delay time . Duration ) string {
return "refresh_token"
} ,
func ( delay time . Duration ) error {
return errors . New ( "Error retrieving token" )
} ,
)
return & gateway
}
func TestServiceLogProducerNew ( t * testing . T ) {
gateway := setupMockOCMGateway ( )
config := conf . ConfigStruct {
ServiceLog : conf . ServiceLogConfiguration {
ClientID : "test_id" ,
ClientSecret : "test_secret" ,
Enabled : true ,
URL : "http://testserver:8000/" ,
Timeout : 15 * time . Second ,
} ,
}
serviceLogConfiguration := conf . GetServiceLogConfiguration ( & config )
producer , err := New ( & serviceLogConfiguration , gateway )
helpers . FailOnError ( t , err )
assert . Equal ( t , producer . Configuration , conf . GetServiceLogConfiguration ( & config ) )
assert . Equal ( t , producer . AccessToken , "online_token" )
assert . Equal ( t , producer . TokenRefreshmentStartDelay , time . Second )
assert . Equal ( t , producer . TokenRefreshmentDelay , time . Second )
assert . Equal ( t , producer . TokenRefreshmentThreshold , 30 * time . Second )
}
func TestServiceLogProducerNewOnError ( t * testing . T ) {
gateway := setupMockOCMGatewayWithError ( )
config := conf . ConfigStruct {
ServiceLog : conf . ServiceLogConfiguration {
ClientID : "test_id" ,
ClientSecret : "test_secret" ,
Enabled : true ,
URL : "http://testserver:8000/" ,
Timeout : 15 * time . Second ,
} ,
}
serviceLogConfiguration := conf . GetServiceLogConfiguration ( & config )
_ , err := New ( & serviceLogConfiguration , gateway )
assert . NotNil ( t , err , "Error is expected to be returned" )
}
func TestServiceLogProducerSendMessage ( t * testing . T ) {
server := httptest . NewServer ( http . HandlerFunc ( func ( w http . ResponseWriter , r * http . Request ) {
if r . Header . Get ( "Authorization" ) != "Bearer online_token" {
t . Errorf ( "Expected 'Authorization: Bearer token' header, got: '%s'" , r . Header . Get ( "Authorization" ) )
}
|
check message content
|
assert . Equal ( t , message . ClusterUUID , types . ClusterName ( "e1a379e4-9ac5-4353-8f82-ad066a734f18" ) )
assert . Equal ( t , message . ServiceName , "test-service-name" )
assert . Equal ( t , message . Description , "test-description" )
assert . Equal ( t , message . Summary , "test-summary" )
assert . Equal ( t , message . CreatedBy , "test-service-created-by" )
assert . Equal ( t , message . Username , "test-service-username" )
w . WriteHeader ( http . StatusCreated )
_ , err = w . Write ( [ ] byte ( `{"id":"2DnciRjDYKGD0gU0pipXq9lFHGD","kind":"ClusterLog","href":"/api/service_logs/v1/cluster_logs/2DnciRjDYKGD0gU0pipXq9lFHGD","timestamp":"2022-08-24T10:53:35.375948253Z","severity":"Info","service_name":"test","cluster_uuid":"e1a379e4-9ac5-4353-8f82-ad066a734f18","summary":"test","description":"test","event_stream_id":"2DnciRaUyJQDY9mggxeiidkSWp0","created_by":"test-service-created-by","username":"test-service-username","created_at":"2022-08-24T10:53:35.375972704Z","email":"test@test.com"}` ) )
if err != nil {
log . Fatal ( ) . Msg ( err . Error ( ) )
}
} ) )
defer server . Close ( )
config := conf . ServiceLogConfiguration {
Enabled : true ,
URL : server . URL ,
Timeout : 15 * time . Second ,
}
producer := Producer {
Configuration : config ,
AccessToken : "online_token" ,
}
entry := types . ServiceLogEntry {
ClusterUUID : "e1a379e4-9ac5-4353-8f82-ad066a734f18" ,
Description : "test-description" ,
ServiceName : "test-service-name" ,
Summary : "test-summary" ,
CreatedBy : "test-service-created-by" ,
Username : "test-service-username" ,
}
msgBytes , err := json . Marshal ( entry )
helpers . FailOnError ( t , err )
_ , _ , err = producer . ProduceMessage ( msgBytes )
helpers . FailOnError ( t , err )
}
func TestServiceLogProducerInvalidMessage ( t * testing . T ) {
serviceLogServer := httptest . NewServer ( http . HandlerFunc ( func ( w http . ResponseWriter , r * http . Request ) {
if r . Header . Get ( "Authorization" ) != "Bearer online_token" {
t . Errorf ( "Expected 'Authorization: Bearer token' header, got: '%s'" , r . Header . Get ( "Authorization" ) )
}
w . WriteHeader ( http . StatusBadRequest )
_ , err := w . Write ( [ ] byte ( `{"id":"21","kind":"Error","href":"/api/service_logs/v1/errors/21","code":"OCM-CA-21","reason":"json: cannot unmarshal string into Go value of type openapi.ClusterLog","operation_id":"2DnejRUk4UfCwsDqhupK7lqxkzF"}` ) )
if err != nil {
log . Fatal ( ) . Msg ( err . Error ( ) )
}
} ) )
defer serviceLogServer . Close ( )
config := conf . ServiceLogConfiguration {
Enabled : true ,
URL : serviceLogServer . URL ,
Timeout : 15 * time . Second ,
}
producer := Producer {
Configuration : config ,
AccessToken : "online_token" ,
}
msgBytes , err := json . Marshal ( "nonsense" )
helpers . FailOnError ( t , err )
_ , _ , err = producer . ProduceMessage ( msgBytes )
assert . EqualError ( t , err , "received unexpected response status code - 400 Bad Request" )
}
func TestServiceLogProducerTooLongSummary ( t * testing . T ) {
server := httptest . NewServer ( http . HandlerFunc ( func ( w http . ResponseWriter , r * http . Request ) {
if r . Header . Get ( "Authorization" ) != "Bearer online_token" {
t . Errorf ( "Expected 'Authorization: Bearer token' header, got: '%s'" , r . Header . Get ( "Authorization" ) )
}
w . WriteHeader ( http . StatusInternalServerError )
_ , err := w . Write ( [ ] byte ( ` {"id":"9","kind":"Error","href":"/api/service_logs/v1/errors/9","code":"OCM-CA-9","reason":"Unable to create ServiceLog: pq: value too long for type character varying(255)","operation_id":"2DnjyKFcq7XD7koOn5AksQ93GQf"}` ) )
if err != nil {
log . Fatal ( ) . Msg ( err . Error ( ) )
}
} ) )
defer server . Close ( )
config := conf . ServiceLogConfiguration {
Enabled : true ,
URL : server . URL ,
Timeout : 15 * time . Second ,
}
producer := Producer {
Configuration : config ,
AccessToken : "online_token" ,
}
entry := types . ServiceLogEntry {
ClusterUUID : "e1a379e4-9ac5-4353-8f82-ad066a734f18" ,
Description : "test" ,
ServiceName : "test" ,
CreatedBy : "test-service" ,
Summary : "This summary is more than 255 characters long. " ,
}
msgBytes , err := json . Marshal ( entry )
helpers . FailOnError ( t , err )
_ , _ , err = producer . ProduceMessage ( msgBytes )
assert . EqualError ( t , err , "received unexpected response status code - 500 Internal Server Error" )
}
func TestServiceLogProducerInvalidServiceLogURL ( t * testing . T ) {
serviceLogServer := httptest . NewServer ( http . HandlerFunc ( func ( w http . ResponseWriter , r * http . Request ) {
if r . Header . Get ( "Authorization" ) != "Bearer online_token" {
t . Errorf ( "Expected 'Authorization: Bearer token' header, got: '%s'" , r . Header . Get ( "Authorization" ) )
}
w . WriteHeader ( http . StatusBadRequest )
_ , err := w . Write ( [ ] byte ( `{"id":"21","kind":"Error","href":"/api/service_logs/v1/errors/21","code":"OCM-CA-21","reason":"json: cannot unmarshal string into Go value of type openapi.ClusterLog","operation_id":"2DnejRUk4UfCwsDqhupK7lqxkzF"}` ) )
if err != nil {
log . Fatal ( ) . Msg ( err . Error ( ) )
}
} ) )
defer serviceLogServer . Close ( )
config := conf . ServiceLogConfiguration {
Enabled : true ,
URL : "\\:" ,
Timeout : 15 * time . Second ,
}
producer := Producer {
Configuration : config ,
AccessToken : "online_token" ,
}
msgBytes , err := json . Marshal ( "nonsense" )
helpers . FailOnError ( t , err )
_ , _ , err = producer . ProduceMessage ( msgBytes )
assert . EqualError ( t , err , "parse \"http://\\\\:\": invalid character \"\\\\\" in host name" )
}
func TestServiceLogProducerClose ( t * testing . T ) {
producer := Producer {
Configuration : conf . ServiceLogConfiguration { } ,
}
err := producer . Close ( )
helpers . FailOnError ( t , err )
}
func TestServiceLogProducerInvalidURL ( t * testing . T ) {
config := conf . ServiceLogConfiguration {
Enabled : true ,
URL : "http://testserver:8000/" ,
Timeout : 15 * time . Second ,
}
producer := Producer {
Configuration : config ,
AccessToken : "online_token" ,
}
entry := types . ServiceLogEntry {
ClusterUUID : "e1a379e4-9ac5-4353-8f82-ad066a734f18" ,
Description : "test" ,
ServiceName : "test" ,
CreatedBy : "test-service" ,
Summary : "test" ,
}
msgBytes , err := json . Marshal ( entry )
helpers . FailOnError ( t , err )
_ , _ , err = producer . ProduceMessage ( msgBytes )
assert . Error ( t , err )
}
func TestServiceLogProducerOldToken ( t * testing . T ) {
serviceLogServer := httptest . NewServer ( http . HandlerFunc ( func ( w http . ResponseWriter , r * http . Request ) {
if r . Header . Get ( "Authorization" ) != "Bearer online_token" {
w . WriteHeader ( http . StatusUnauthorized )
return
}
w . WriteHeader ( http . StatusCreated )
_ , err := w . Write ( [ ] byte ( `{"id":"2DnciRjDYKGD0gU0pipXq9lFHGD","kind":"ClusterLog","href":"/api/service_logs/v1/cluster_logs/2DnciRjDYKGD0gU0pipXq9lFHGD","timestamp":"2022-08-24T10:53:35.375948253Z","severity":"Info","service_name":"test","cluster_uuid":"e1a379e4-9ac5-4353-8f82-ad066a734f18","summary":"test","description":"test","event_stream_id":"2DnciRaUyJQDY9mggxeiidkSWp0","created_by":"test-service","created_at":"2022-08-24T10:53:35.375972704Z","email":"test@test.com"}` ) )
if err != nil {
log . Fatal ( ) . Msg ( err . Error ( ) )
}
} ) )
defer serviceLogServer . Close ( )
config := conf . ServiceLogConfiguration {
Enabled : true ,
URL : serviceLogServer . URL ,
Timeout : 15 * time . Second ,
}
gateway := setupMockOCMGateway ( )
producer := Producer {
Configuration : config ,
OCMClient : gateway ,
AccessToken : "old_token" ,
}
entry := types . ServiceLogEntry {
ClusterUUID : "e1a379e4-9ac5-4353-8f82-ad066a734f18" ,
Description : "test" ,
ServiceName : "test" ,
CreatedBy : "test-service" ,
Summary : "test" ,
}
msgBytes , err := json . Marshal ( entry )
helpers . FailOnError ( t , err )
_ , _ , err = producer . ProduceMessage ( msgBytes )
assert . NoError ( t , err )
}
|