Skip to content

Commit

Permalink
Merge pull request #2 from Pubx-ai/PUB-3288
Browse files Browse the repository at this point in the history
Update mocking and Testing Framework changes
  • Loading branch information
tej656 authored Dec 31, 2024
2 parents 5c415ab + 769821a commit c46ed6e
Show file tree
Hide file tree
Showing 19 changed files with 1,147 additions and 1,372 deletions.
1 change: 0 additions & 1 deletion analytics/build/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ func New(analytics *config.Analytics) analytics.Runner {
clock.New(),
)
if err == nil {
glog.Infof("PubxaiModule initialized")
modules["pubxai"] = pubxaiModule
} else {
glog.Errorf("Could not initialize Pubxai Module: %v", err)
Expand Down
7 changes: 5 additions & 2 deletions analytics/pubxai/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,15 @@ func NewConfigService(httpClient *http.Client, pubxId, endpoint, refreshInterval
if err != nil {
return nil, fmt.Errorf("fail to parse the module args, arg=analytics.pubxai.configuration_refresh_delay: %v", err)
}

endpointUrl, err := url.Parse(endpoint + "/config?pubxId=" + pubxId)
endpointUrl, err := url.Parse(endpoint + "/config")
if err != nil {
return nil, err
}

query := endpointUrl.Query()
query.Set("pubxId", pubxId)
endpointUrl.RawQuery = query.Encode()

configChan := make(chan *Configuration)

tr := task.NewTickerTaskFromFunc(refreshDuration, func() error {
Expand Down
263 changes: 173 additions & 90 deletions analytics/pubxai/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,113 +8,196 @@ import (
"testing"
"time"

"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
)

func TestNewConfigService(t *testing.T) {
httpClient := &http.Client{}
pubxId := "testPublisher"
endpoint := "http://example.com"
refreshInterval := "1m"

configService, err := NewConfigService(httpClient, pubxId, endpoint, refreshInterval)
assert.NoError(t, err)
assert.NotNil(t, configService)
}

func TestNewConfigService_InvalidDuration(t *testing.T) {
httpClient := &http.Client{}
pubxId := "testPublisher"
endpoint := "http://example.com"
refreshInterval := "invalid"
tests := []struct {
name string
httpClient *http.Client
pubxId string
endpoint string
refreshInterval string
wantErr bool
}{
{
name: "valid configuration",
httpClient: &http.Client{},
pubxId: "testPublisher",
endpoint: "http://example.com",
refreshInterval: "1m",
wantErr: false,
},
{
name: "invalid duration",
httpClient: &http.Client{},
pubxId: "testPublisher",
endpoint: "http://example.com",
refreshInterval: "invalid",
wantErr: true,
},
}

configService, err := NewConfigService(httpClient, pubxId, endpoint, refreshInterval)
assert.Error(t, err)
assert.Nil(t, configService)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
configService, err := NewConfigService(tt.httpClient, tt.pubxId, tt.endpoint, tt.refreshInterval)
if tt.wantErr {
assert.Error(t, err)
assert.Nil(t, configService)
} else {
assert.NoError(t, err)
assert.NotNil(t, configService)
}
})
}
}

func TestFetchConfig(t *testing.T) {
expectedConfig := &Configuration{
PublisherId: "testPublisher",
BufferInterval: "30s",
BufferSize: "100",
SamplingPercentage: 50,
tests := []struct {
name string
serverResp http.HandlerFunc // Changed type to http.HandlerFunc
wantConfig *Configuration
wantErr bool
}{
{
name: "successful fetch",
serverResp: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Explicit cast
config := &Configuration{
PublisherId: "testPublisher",
BufferInterval: "30s",
BufferSize: "100",
SamplingPercentage: 50,
}
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(config)
}),
wantConfig: &Configuration{
PublisherId: "testPublisher",
BufferInterval: "30s",
BufferSize: "100",
SamplingPercentage: 50,
},
wantErr: false,
},
{
name: "server error",
serverResp: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Explicit cast
w.WriteHeader(http.StatusInternalServerError)
}),
wantConfig: nil,
wantErr: true,
},
}

server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(expectedConfig)
}))
defer server.Close()

endpointUrl, _ := url.Parse(server.URL)

config, err := fetchConfig(server.Client(), endpointUrl)
assert.NoError(t, err)
assert.Equal(t, expectedConfig, config)
}

func TestFetchConfig_Error(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusInternalServerError)
}))
defer server.Close()

endpointUrl, _ := url.Parse(server.URL)

config, err := fetchConfig(server.Client(), endpointUrl)
assert.Error(t, err)
assert.Nil(t, config)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
server := httptest.NewServer(tt.serverResp) // No need for HandlerFunc here
defer server.Close()

endpointUrl, _ := url.Parse(server.URL)
config, err := fetchConfig(server.Client(), endpointUrl)

if tt.wantErr {
assert.Error(t, err)
assert.Nil(t, config)
} else {
assert.NoError(t, err)
assert.Equal(t, tt.wantConfig, config)
}
})
}
}

func TestConfigServiceImpl_Start(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

httpClient := &http.Client{}
pubxId := "testPublisher"
endpoint := "http://example.com"
refreshInterval := "1m"

configService, _ := NewConfigService(httpClient, pubxId, endpoint, refreshInterval)
configImpl := configService.(*ConfigServiceImpl)

stop := make(chan struct{})
configChan := configImpl.Start(stop)

// Ensure task starts correctly
time.Sleep(2 * time.Second)
close(stop)
// Ensure task stops correctly
time.Sleep(2 * time.Second)
assert.NotNil(t, configChan)
}

func TestConfigServiceImpl_IsSameAs(t *testing.T) {
config1 := &Configuration{
PublisherId: "testPublisher",
BufferInterval: "30s",
BufferSize: "100",
SamplingPercentage: 50,
tests := []struct {
name string
refreshInterval string
}{
{
name: "start and stop service",
refreshInterval: "1m",
},
}

config2 := &Configuration{
PublisherId: "testPublisher",
BufferInterval: "30s",
BufferSize: "100",
SamplingPercentage: 50,
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
httpClient := &http.Client{}
pubxId := "testPublisher"
endpoint := "http://example.com"

configService, err := NewConfigService(httpClient, pubxId, endpoint, tt.refreshInterval)
assert.NoError(t, err)

configImpl := configService.(*ConfigServiceImpl)
stop := make(chan struct{})
done := make(chan struct{})

configChan := configImpl.Start(stop)
assert.NotNil(t, configChan)

// Signal completion after a brief interval
go func() {
time.Sleep(10 * time.Millisecond)
close(stop)
done <- struct{}{}
}()

select {
case <-done:
// Success: service started and stopped
case <-time.After(time.Second):
t.Fatal("timeout waiting for service to stop")
}
})
}
}

config3 := &Configuration{
PublisherId: "differentPublisher",
BufferInterval: "30s",
BufferSize: "100",
SamplingPercentage: 50,
func TestConfigServiceImpl_IsSameAs(t *testing.T) {
tests := []struct {
name string
config1 *Configuration
config2 *Configuration
expected bool
}{
{
name: "identical configs",
config1: &Configuration{
PublisherId: "testPublisher",
BufferInterval: "30s",
BufferSize: "100",
SamplingPercentage: 50,
},
config2: &Configuration{
PublisherId: "testPublisher",
BufferInterval: "30s",
BufferSize: "100",
SamplingPercentage: 50,
},
expected: true,
},
{
name: "different configs",
config1: &Configuration{
PublisherId: "testPublisher",
BufferInterval: "30s",
BufferSize: "100",
SamplingPercentage: 50,
},
config2: &Configuration{
PublisherId: "differentPublisher",
BufferInterval: "30s",
BufferSize: "100",
SamplingPercentage: 50,
},
expected: false,
},
}

configService := &ConfigServiceImpl{}

assert.True(t, configService.IsSameAs(config1, config2))
assert.False(t, configService.IsSameAs(config1, config3))
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
configService := &ConfigServiceImpl{}
result := configService.IsSameAs(tt.config1, tt.config2)
assert.Equal(t, tt.expected, result)
})
}
}
61 changes: 13 additions & 48 deletions analytics/pubxai/config/mocks/config.go
Original file line number Diff line number Diff line change
@@ -1,63 +1,28 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: ./analytics/pubxai/config/config.go

// Package mocks is a generated GoMock package.
package mocks

import (
reflect "reflect"

gomock "github.com/golang/mock/gomock"
config "github.com/prebid/prebid-server/v3/analytics/pubxai/config"
"github.com/prebid/prebid-server/v3/analytics/pubxai/config"
"github.com/stretchr/testify/mock"
)

// MockConfigService is a mock of ConfigService interface.
// MockConfigService is a mock of ConfigService interface using testify
type MockConfigService struct {
ctrl *gomock.Controller
recorder *MockConfigServiceMockRecorder
}

// MockConfigServiceMockRecorder is the mock recorder for MockConfigService.
type MockConfigServiceMockRecorder struct {
mock *MockConfigService
}

// NewMockConfigService creates a new mock instance.
func NewMockConfigService(ctrl *gomock.Controller) *MockConfigService {
mock := &MockConfigService{ctrl: ctrl}
mock.recorder = &MockConfigServiceMockRecorder{mock}
return mock
mock.Mock
}

// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockConfigService) EXPECT() *MockConfigServiceMockRecorder {
return m.recorder
// NewMockConfigService creates a new mock instance
func NewMockConfigService() *MockConfigService {
return &MockConfigService{}
}

// IsSameAs mocks base method.
// IsSameAs provides a mock function
func (m *MockConfigService) IsSameAs(a, b *config.Configuration) bool {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "IsSameAs", a, b)
ret0, _ := ret[0].(bool)
return ret0
}

// IsSameAs indicates an expected call of IsSameAs.
func (mr *MockConfigServiceMockRecorder) IsSameAs(a, b interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsSameAs", reflect.TypeOf((*MockConfigService)(nil).IsSameAs), a, b)
args := m.Called(a, b)
return args.Bool(0)
}

// Start mocks base method.
// Start provides a mock function
func (m *MockConfigService) Start(stop <-chan struct{}) <-chan *config.Configuration {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Start", stop)
ret0, _ := ret[0].(<-chan *config.Configuration)
return ret0
}

// Start indicates an expected call of Start.
func (mr *MockConfigServiceMockRecorder) Start(stop interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Start", reflect.TypeOf((*MockConfigService)(nil).Start), stop)
args := m.Called(stop)
return args.Get(0).(<-chan *config.Configuration)
}
Loading

0 comments on commit c46ed6e

Please sign in to comment.