@@ -30,6 +30,7 @@ import (
30
30
"runtime"
31
31
"strings"
32
32
"testing"
33
+ "time"
33
34
34
35
"golang.org/x/crypto/bcrypt"
35
36
"gopkg.in/square/go-jose.v2"
@@ -2925,3 +2926,146 @@ func makeScopesConfigWithDefault(scopeName string, collections []string) *Scopes
2925
2926
scopesConfig := makeScopesConfig (scopeName , collections )
2926
2927
return & scopesConfig
2927
2928
}
2929
+
2930
+ // TestInvalidDbConfigNoLongerPresentInBucket:
2931
+ // - Create rest tester with large config poll interval
2932
+ // - Create valid db
2933
+ // - Alter config in bucket to make it invalid
2934
+ // - Force config poll, assert it is picked up as invalid db config
2935
+ // - Delete the invalid db config form the bucket
2936
+ // - Force config poll reload and assert the invalid db is cleared
2937
+ func TestInvalidDbConfigNoLongerPresentInBucket (t * testing.T ) {
2938
+ if base .UnitTestUrlIsWalrus () {
2939
+ t .Skip ("test only works with CBS, requires bootstrap connection" )
2940
+ }
2941
+ rt := NewRestTester (t , & RestTesterConfig {
2942
+ CustomTestBucket : base .GetTestBucket (t ),
2943
+ PersistentConfig : true ,
2944
+ MutateStartupConfig : func (config * StartupConfig ) {
2945
+ // configure the interval time to not run
2946
+ config .Bootstrap .ConfigUpdateFrequency = base .NewConfigDuration (10 * time .Minute )
2947
+ },
2948
+ DatabaseConfig : nil ,
2949
+ })
2950
+ defer rt .Close ()
2951
+ realBucketName := rt .CustomTestBucket .GetName ()
2952
+ ctx := base .TestCtx (t )
2953
+ const dbName = "db1"
2954
+
2955
+ // create db with correct config
2956
+ dbConfig := rt .NewDbConfig ()
2957
+ resp := rt .CreateDatabase (dbName , dbConfig )
2958
+ RequireStatus (t , resp , http .StatusCreated )
2959
+
2960
+ // wait for db to come online
2961
+ require .NoError (t , rt .WaitForDBOnline ())
2962
+
2963
+ // grab the persisted db config from the bucket
2964
+ databaseConfig := DatabaseConfig {}
2965
+ _ , err := rt .ServerContext ().BootstrapContext .GetConfig (rt .Context (), realBucketName , rt .ServerContext ().Config .Bootstrap .ConfigGroupID , "db1" , & databaseConfig )
2966
+ require .NoError (t , err )
2967
+
2968
+ // update the persisted config to a fake bucket name
2969
+ newBucketName := "fakeBucket"
2970
+ _ , err = rt .UpdatePersistedBucketName (& databaseConfig , & newBucketName )
2971
+ require .NoError (t , err )
2972
+
2973
+ // force reload of configs from bucket
2974
+ rt .ServerContext ().ForceDbConfigsReload (t , ctx )
2975
+
2976
+ // assert the config is picked as invalid db config
2977
+ require .EventuallyWithT (t , func (c * assert.CollectT ) {
2978
+ invalidDatabases := rt .ServerContext ().AllInvalidDatabaseNames (t )
2979
+ assert .Equal (c , 1 , len (invalidDatabases ))
2980
+ assert .Equal (c , 0 , len (rt .ServerContext ().dbConfigs ))
2981
+ }, time .Second * 10 , time .Millisecond * 100 )
2982
+
2983
+ // remove the invalid config from the bucket
2984
+ rt .RemoveDbConfigFromBucket (dbName , realBucketName )
2985
+
2986
+ // force reload of configs from bucket
2987
+ rt .ServerContext ().ForceDbConfigsReload (t , ctx )
2988
+
2989
+ // assert the config is removed from tracking
2990
+ require .EventuallyWithT (t , func (c * assert.CollectT ) {
2991
+ invalidDatabases := rt .ServerContext ().AllInvalidDatabaseNames (t )
2992
+ assert .Equal (c , 0 , len (invalidDatabases ))
2993
+ assert .Equal (c , 0 , len (rt .ServerContext ().dbConfigs ))
2994
+ }, time .Second * 10 , time .Millisecond * 100 )
2995
+
2996
+ // create db again, should succeed
2997
+ resp = rt .CreateDatabase (dbName , dbConfig )
2998
+ RequireStatus (t , resp , http .StatusCreated )
2999
+ }
3000
+
3001
+ // TestNotFoundOnInvalidDatabase:
3002
+ // - Create rest tester with large config polling interval
3003
+ // - Insert a bad dbConfig into the bucket
3004
+ // - Manually fetch and load db from buckets
3005
+ // - Assert that the bad config is tracked as invalid config
3006
+ // - Delete the bad config manually and attempt to correct the db config through create db endpoint
3007
+ // - Assert db is removed form invalid db's and is now a running database on server context
3008
+ func TestNotFoundOnInvalidDatabase (t * testing.T ) {
3009
+ if base .UnitTestUrlIsWalrus () {
3010
+ t .Skip ("test only works with CBS, requires bootstrap connection" )
3011
+ }
3012
+ rt := NewRestTester (t , & RestTesterConfig {
3013
+ CustomTestBucket : base .GetTestBucket (t ),
3014
+ PersistentConfig : true ,
3015
+ MutateStartupConfig : func (config * StartupConfig ) {
3016
+ // configure the interval time to not run
3017
+ config .Bootstrap .ConfigUpdateFrequency = base .NewConfigDuration (100 * time .Second )
3018
+ },
3019
+ DatabaseConfig : nil ,
3020
+ })
3021
+ defer rt .Close ()
3022
+ realBucketName := rt .CustomTestBucket .GetName ()
3023
+
3024
+ // create a new invalid db config and persist to bucket
3025
+ badName := "badBucketName"
3026
+ dbConfig := rt .NewDbConfig ()
3027
+ dbConfig .Name = "db1"
3028
+
3029
+ version , err := GenerateDatabaseConfigVersionID (rt .Context (), "" , & dbConfig )
3030
+ require .NoError (t , err )
3031
+ metadataID , metadataIDError := rt .ServerContext ().BootstrapContext .ComputeMetadataIDForDbConfig (base .TestCtx (t ), & dbConfig )
3032
+ require .NoError (t , metadataIDError )
3033
+
3034
+ // insert the db config with bad bucket name
3035
+ dbConfig .Bucket = & badName
3036
+ persistedConfig := DatabaseConfig {
3037
+ Version : version ,
3038
+ MetadataID : metadataID ,
3039
+ DbConfig : dbConfig ,
3040
+ SGVersion : base .ProductVersion .String (),
3041
+ }
3042
+ rt .InsertDbConfigToBucket (& persistedConfig , rt .CustomTestBucket .GetName ())
3043
+
3044
+ // manually fetch and load db configs from bucket
3045
+ _ , err = rt .ServerContext ().fetchAndLoadConfigs (rt .Context (), false )
3046
+ require .NoError (t , err )
3047
+
3048
+ // assert the config is picked as invalid db config
3049
+ require .EventuallyWithT (t , func (c * assert.CollectT ) {
3050
+ invalidDatabases := rt .ServerContext ().AllInvalidDatabaseNames (t )
3051
+ assert .Equal (c , 1 , len (invalidDatabases ))
3052
+ }, time .Second * 10 , time .Millisecond * 100 )
3053
+
3054
+ resp := rt .SendAdminRequest (http .MethodGet , "/db1/" , "" )
3055
+ RequireStatus (t , resp , http .StatusNotFound )
3056
+ assert .Contains (t , resp .Body .String (), "You must update database config immediately" )
3057
+
3058
+ // delete the invalid db config to force the not found error
3059
+ rt .RemoveDbConfigFromBucket (dbConfig .Name , realBucketName )
3060
+
3061
+ // fix the bucket name and try fix corrupt db through create db endpoint
3062
+ dbConfig .Bucket = & realBucketName
3063
+ RequireStatus (t , rt .CreateDatabase (dbConfig .Name , dbConfig ), http .StatusCreated )
3064
+
3065
+ // assert the config is remove the invalid config and we have a running db
3066
+ require .EventuallyWithT (t , func (c * assert.CollectT ) {
3067
+ invalidDatabases := rt .ServerContext ().AllInvalidDatabaseNames (t )
3068
+ assert .Equal (c , 0 , len (invalidDatabases ))
3069
+ assert .Equal (c , 1 , len (rt .ServerContext ().dbConfigs ))
3070
+ }, time .Second * 10 , time .Millisecond * 100 )
3071
+ }
0 commit comments