github.com/prebid/prebid-server/v2@v2.18.0/config/stored_requests_test.go (about)

     1  package config
     2  
     3  import (
     4  	"errors"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/assert"
     8  )
     9  
    10  func TestInMemoryCacheValidationStoredRequests(t *testing.T) {
    11  	assertNoErrs(t, (&InMemoryCache{
    12  		Type: "unbounded",
    13  	}).validate(RequestDataType, nil))
    14  	assertNoErrs(t, (&InMemoryCache{
    15  		Type: "none",
    16  	}).validate(RequestDataType, nil))
    17  	assertNoErrs(t, (&InMemoryCache{
    18  		Type:             "lru",
    19  		RequestCacheSize: 1000,
    20  		ImpCacheSize:     1000,
    21  		RespCacheSize:    1000,
    22  	}).validate(RequestDataType, nil))
    23  	assertErrsExist(t, (&InMemoryCache{
    24  		Type: "unrecognized",
    25  	}).validate(RequestDataType, nil))
    26  	assertErrsExist(t, (&InMemoryCache{
    27  		Type:         "unbounded",
    28  		ImpCacheSize: 1000,
    29  	}).validate(RequestDataType, nil))
    30  	assertErrsExist(t, (&InMemoryCache{
    31  		Type:             "unbounded",
    32  		RequestCacheSize: 1000,
    33  	}).validate(RequestDataType, nil))
    34  	assertErrsExist(t, (&InMemoryCache{
    35  		Type:          "unbounded",
    36  		RespCacheSize: 1000,
    37  	}).validate(RequestDataType, nil))
    38  	assertErrsExist(t, (&InMemoryCache{
    39  		Type: "unbounded",
    40  		TTL:  500,
    41  	}).validate(RequestDataType, nil))
    42  	assertErrsExist(t, (&InMemoryCache{
    43  		Type:             "lru",
    44  		RequestCacheSize: 0,
    45  		ImpCacheSize:     1000,
    46  		RespCacheSize:    1000,
    47  	}).validate(RequestDataType, nil))
    48  	assertErrsExist(t, (&InMemoryCache{
    49  		Type:             "lru",
    50  		RequestCacheSize: 1000,
    51  		ImpCacheSize:     0,
    52  		RespCacheSize:    1000,
    53  	}).validate(RequestDataType, nil))
    54  	assertErrsExist(t, (&InMemoryCache{
    55  		Type:             "lru",
    56  		RequestCacheSize: 1000,
    57  		ImpCacheSize:     1000,
    58  		RespCacheSize:    0,
    59  	}).validate(RequestDataType, nil))
    60  	assertErrsExist(t, (&InMemoryCache{
    61  		Type: "lru",
    62  		Size: 1000,
    63  	}).validate(RequestDataType, nil))
    64  }
    65  
    66  func TestInMemoryCacheValidationSingleCache(t *testing.T) {
    67  	assertNoErrs(t, (&InMemoryCache{
    68  		Type: "unbounded",
    69  	}).validate(AccountDataType, nil))
    70  	assertNoErrs(t, (&InMemoryCache{
    71  		Type: "none",
    72  	}).validate(AccountDataType, nil))
    73  	assertNoErrs(t, (&InMemoryCache{
    74  		Type: "lru",
    75  		Size: 1000,
    76  	}).validate(AccountDataType, nil))
    77  	assertErrsExist(t, (&InMemoryCache{
    78  		Type: "unrecognized",
    79  	}).validate(AccountDataType, nil))
    80  	assertErrsExist(t, (&InMemoryCache{
    81  		Type: "unbounded",
    82  		Size: 1000,
    83  	}).validate(AccountDataType, nil))
    84  	assertErrsExist(t, (&InMemoryCache{
    85  		Type: "unbounded",
    86  		TTL:  500,
    87  	}).validate(AccountDataType, nil))
    88  	assertErrsExist(t, (&InMemoryCache{
    89  		Type: "lru",
    90  		Size: 0,
    91  	}).validate(AccountDataType, nil))
    92  	assertErrsExist(t, (&InMemoryCache{
    93  		Type:             "lru",
    94  		RequestCacheSize: 1000,
    95  	}).validate(AccountDataType, nil))
    96  	assertErrsExist(t, (&InMemoryCache{
    97  		Type:         "lru",
    98  		ImpCacheSize: 1000,
    99  	}).validate(AccountDataType, nil))
   100  	assertErrsExist(t, (&InMemoryCache{
   101  		Type:          "lru",
   102  		RespCacheSize: 1000,
   103  	}).validate(AccountDataType, nil))
   104  }
   105  
   106  func TestDatabaseConfigValidation(t *testing.T) {
   107  	tests := []struct {
   108  		description            string
   109  		connectionStr          string
   110  		cacheInitQuery         string
   111  		cacheInitTimeout       int
   112  		cacheUpdateQuery       string
   113  		cacheUpdateRefreshRate int
   114  		cacheUpdateTimeout     int
   115  		existingErrors         []error
   116  		wantErrorCount         int
   117  	}{
   118  		{
   119  			description:   "No connection string",
   120  			connectionStr: "",
   121  		},
   122  		{
   123  			description:   "Connection string but no queries",
   124  			connectionStr: "some-connection-string",
   125  		},
   126  		{
   127  			description:      "Valid cache init query with non-zero timeout",
   128  			connectionStr:    "some-connection-string",
   129  			cacheInitQuery:   "SELECT * FROM table;",
   130  			cacheInitTimeout: 1,
   131  		},
   132  		{
   133  			description:      "Valid cache init query with zero timeout",
   134  			connectionStr:    "some-connection-string",
   135  			cacheInitQuery:   "SELECT * FROM table;",
   136  			cacheInitTimeout: 0,
   137  			wantErrorCount:   1,
   138  		},
   139  		{
   140  			description:      "Invalid cache init query contains wildcard",
   141  			connectionStr:    "some-connection-string",
   142  			cacheInitQuery:   "SELECT * FROM table WHERE $LAST_UPDATED",
   143  			cacheInitTimeout: 1,
   144  			wantErrorCount:   1,
   145  		},
   146  		{
   147  			description:            "Valid cache update query with non-zero timeout and refresh rate",
   148  			connectionStr:          "some-connection-string",
   149  			cacheUpdateQuery:       "SELECT * FROM table WHERE $LAST_UPDATED",
   150  			cacheUpdateRefreshRate: 1,
   151  			cacheUpdateTimeout:     1,
   152  		},
   153  		{
   154  			description:            "Valid cache update query with zero timeout and non-zero refresh rate",
   155  			connectionStr:          "some-connection-string",
   156  			cacheUpdateQuery:       "SELECT * FROM table WHERE $LAST_UPDATED",
   157  			cacheUpdateRefreshRate: 1,
   158  			cacheUpdateTimeout:     0,
   159  			wantErrorCount:         1,
   160  		},
   161  		{
   162  			description:            "Valid cache update query with non-zero timeout and zero refresh rate",
   163  			connectionStr:          "some-connection-string",
   164  			cacheUpdateQuery:       "SELECT * FROM table WHERE $LAST_UPDATED",
   165  			cacheUpdateRefreshRate: 0,
   166  			cacheUpdateTimeout:     1,
   167  			wantErrorCount:         1,
   168  		},
   169  		{
   170  			description:            "Invalid cache update query missing wildcard",
   171  			connectionStr:          "some-connection-string",
   172  			cacheUpdateQuery:       "SELECT * FROM table",
   173  			cacheUpdateRefreshRate: 1,
   174  			cacheUpdateTimeout:     1,
   175  			wantErrorCount:         1,
   176  		},
   177  		{
   178  			description:      "Multiple errors: valid queries missing timeouts and refresh rates plus existing error",
   179  			connectionStr:    "some-connection-string",
   180  			cacheInitQuery:   "SELECT * FROM table;",
   181  			cacheUpdateQuery: "SELECT * FROM table WHERE $LAST_UPDATED",
   182  			existingErrors:   []error{errors.New("existing error before calling validate")},
   183  			wantErrorCount:   4,
   184  		},
   185  	}
   186  
   187  	for _, tt := range tests {
   188  		dbConfig := &DatabaseConfig{
   189  			ConnectionInfo: DatabaseConnection{
   190  				Database: tt.connectionStr,
   191  			},
   192  			CacheInitialization: DatabaseCacheInitializer{
   193  				Query:   tt.cacheInitQuery,
   194  				Timeout: tt.cacheInitTimeout,
   195  			},
   196  			PollUpdates: DatabaseUpdatePolling{
   197  				Query:       tt.cacheUpdateQuery,
   198  				RefreshRate: tt.cacheUpdateRefreshRate,
   199  				Timeout:     tt.cacheUpdateTimeout,
   200  			},
   201  		}
   202  
   203  		errs := dbConfig.validate(RequestDataType, tt.existingErrors)
   204  		assert.Equal(t, tt.wantErrorCount, len(errs), tt.description)
   205  	}
   206  }
   207  
   208  func assertErrsExist(t *testing.T, err []error) {
   209  	t.Helper()
   210  	if len(err) == 0 {
   211  		t.Error("Expected error was not not found.")
   212  	}
   213  }
   214  
   215  func assertNoErrs(t *testing.T, err []error) {
   216  	t.Helper()
   217  	if len(err) > 0 {
   218  		t.Errorf("Got unexpected error(s): %v", err)
   219  	}
   220  }
   221  
   222  func assertStringsEqual(t *testing.T, actual string, expected string) {
   223  	if actual != expected {
   224  		t.Errorf("Queries did not match.\n\"%s\" -- expected\n\"%s\" -- actual", expected, actual)
   225  
   226  	}
   227  }
   228  
   229  func TestResolveConfig(t *testing.T) {
   230  	cfg := &Configuration{
   231  		StoredRequests: StoredRequests{
   232  			Files: FileFetcherConfig{
   233  				Enabled: true,
   234  				Path:    "/test-path"},
   235  			Database: DatabaseConfig{
   236  				ConnectionInfo: DatabaseConnection{
   237  					Driver:   "postgres",
   238  					Database: "db",
   239  					Host:     "pghost",
   240  					Port:     5,
   241  					Username: "user",
   242  					Password: "pass",
   243  				},
   244  				FetcherQueries: DatabaseFetcherQueries{
   245  					AmpQueryTemplate: "amp-fetcher-query",
   246  				},
   247  				CacheInitialization: DatabaseCacheInitializer{
   248  					AmpQuery: "amp-cache-init-query",
   249  				},
   250  				PollUpdates: DatabaseUpdatePolling{
   251  					AmpQuery: "amp-poll-query",
   252  				},
   253  			},
   254  			HTTP: HTTPFetcherConfig{
   255  				AmpEndpoint: "amp-http-fetcher-endpoint",
   256  			},
   257  			InMemoryCache: InMemoryCache{
   258  				Type:             "none",
   259  				TTL:              50,
   260  				RequestCacheSize: 1,
   261  				ImpCacheSize:     2,
   262  			},
   263  			CacheEvents: CacheEventsConfig{
   264  				Enabled: true,
   265  			},
   266  			HTTPEvents: HTTPEventsConfig{
   267  				AmpEndpoint: "amp-http-events-endpoint",
   268  			},
   269  		},
   270  	}
   271  
   272  	cfg.StoredRequests.Database.FetcherQueries.QueryTemplate = "auc-fetcher-query"
   273  	cfg.StoredRequests.Database.CacheInitialization.Query = "auc-cache-init-query"
   274  	cfg.StoredRequests.Database.PollUpdates.Query = "auc-poll-query"
   275  	cfg.StoredRequests.HTTP.Endpoint = "auc-http-fetcher-endpoint"
   276  	cfg.StoredRequests.HTTPEvents.Endpoint = "auc-http-events-endpoint"
   277  
   278  	resolvedStoredRequestsConfig(cfg)
   279  	auc := &cfg.StoredRequests
   280  	amp := &cfg.StoredRequestsAMP
   281  
   282  	// Auction should have the non-amp values in it
   283  	assertStringsEqual(t, auc.CacheEvents.Endpoint, "/storedrequests/openrtb2")
   284  
   285  	// Amp should have the amp values in it
   286  	assertStringsEqual(t, amp.Database.FetcherQueries.QueryTemplate, cfg.StoredRequests.Database.FetcherQueries.AmpQueryTemplate)
   287  	assertStringsEqual(t, amp.Database.CacheInitialization.Query, cfg.StoredRequests.Database.CacheInitialization.AmpQuery)
   288  	assertStringsEqual(t, amp.Database.PollUpdates.Query, cfg.StoredRequests.Database.PollUpdates.AmpQuery)
   289  	assertStringsEqual(t, amp.HTTP.Endpoint, cfg.StoredRequests.HTTP.AmpEndpoint)
   290  	assertStringsEqual(t, amp.HTTPEvents.Endpoint, cfg.StoredRequests.HTTPEvents.AmpEndpoint)
   291  	assertStringsEqual(t, amp.CacheEvents.Endpoint, "/storedrequests/amp")
   292  }