github.com/masterhung0112/hk_server/v5@v5.0.0-20220302090640-ec71aef15e1c/config/diff_test.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See LICENSE.txt for license information.
     3  
     4  package config
     5  
     6  import (
     7  	"testing"
     8  
     9  	"github.com/masterhung0112/hk_server/v5/model"
    10  
    11  	"github.com/stretchr/testify/require"
    12  )
    13  
    14  func defaultConfigGen() *model.Config {
    15  	cfg := &model.Config{}
    16  	cfg.SetDefaults()
    17  	return cfg
    18  }
    19  
    20  func BenchmarkDiff(b *testing.B) {
    21  	b.Run("equal empty", func(b *testing.B) {
    22  		baseCfg := &model.Config{}
    23  		actualCfg := &model.Config{}
    24  		b.ResetTimer()
    25  		for i := 0; i < b.N; i++ {
    26  			_, _ = Diff(baseCfg, actualCfg)
    27  		}
    28  	})
    29  
    30  	b.Run("equal with defaults", func(b *testing.B) {
    31  		baseCfg := defaultConfigGen()
    32  		actualCfg := defaultConfigGen()
    33  		b.ResetTimer()
    34  		for i := 0; i < b.N; i++ {
    35  			_, _ = Diff(baseCfg, actualCfg)
    36  		}
    37  	})
    38  
    39  	b.Run("actual empty", func(b *testing.B) {
    40  		baseCfg := defaultConfigGen()
    41  		actualCfg := &model.Config{}
    42  		b.ResetTimer()
    43  		for i := 0; i < b.N; i++ {
    44  			_, _ = Diff(baseCfg, actualCfg)
    45  		}
    46  	})
    47  
    48  	b.Run("base empty", func(b *testing.B) {
    49  		baseCfg := &model.Config{}
    50  		actualCfg := defaultConfigGen()
    51  		b.ResetTimer()
    52  		for i := 0; i < b.N; i++ {
    53  			_, _ = Diff(baseCfg, actualCfg)
    54  		}
    55  	})
    56  
    57  	b.Run("some diffs", func(b *testing.B) {
    58  		baseCfg := defaultConfigGen()
    59  		actualCfg := defaultConfigGen()
    60  		baseCfg.ServiceSettings.SiteURL = model.NewString("http://localhost")
    61  		baseCfg.ServiceSettings.ReadTimeout = model.NewInt(300)
    62  		baseCfg.SqlSettings.QueryTimeout = model.NewInt(0)
    63  		actualCfg.PluginSettings.EnableUploads = nil
    64  		actualCfg.TeamSettings.MaxChannelsPerTeam = model.NewInt64(100000)
    65  		actualCfg.FeatureFlags = nil
    66  		actualCfg.SqlSettings.DataSourceReplicas = []string{
    67  			"ds0",
    68  			"ds1",
    69  			"ds2",
    70  		}
    71  		b.ResetTimer()
    72  		for i := 0; i < b.N; i++ {
    73  			_, _ = Diff(baseCfg, actualCfg)
    74  		}
    75  	})
    76  }
    77  
    78  func TestDiff(t *testing.T) {
    79  	tcs := []struct {
    80  		name   string
    81  		base   *model.Config
    82  		actual *model.Config
    83  		diffs  ConfigDiffs
    84  		err    string
    85  	}{
    86  		{
    87  			"nil",
    88  			nil,
    89  			nil,
    90  			nil,
    91  			"input configs should not be nil",
    92  		},
    93  		{
    94  			"empty",
    95  			&model.Config{},
    96  			&model.Config{},
    97  			nil,
    98  			"",
    99  		},
   100  		{
   101  			"defaults",
   102  			defaultConfigGen(),
   103  			defaultConfigGen(),
   104  			nil,
   105  			"",
   106  		},
   107  		{
   108  			"default base, actual empty",
   109  			defaultConfigGen(),
   110  			&model.Config{},
   111  			ConfigDiffs{
   112  				{
   113  					"",
   114  					*defaultConfigGen(),
   115  					model.Config{},
   116  				},
   117  			},
   118  			"",
   119  		},
   120  		{
   121  			"empty base, actual default",
   122  			&model.Config{},
   123  			defaultConfigGen(),
   124  			ConfigDiffs{
   125  				{
   126  					"",
   127  					model.Config{},
   128  					*defaultConfigGen(),
   129  				},
   130  			},
   131  			"",
   132  		},
   133  		{
   134  			"string change",
   135  			defaultConfigGen(),
   136  			func() *model.Config {
   137  				cfg := defaultConfigGen()
   138  				cfg.ServiceSettings.SiteURL = model.NewString("http://changed")
   139  				return cfg
   140  			}(),
   141  			ConfigDiffs{
   142  				{
   143  					Path:      "ServiceSettings.SiteURL",
   144  					BaseVal:   *defaultConfigGen().ServiceSettings.SiteURL,
   145  					ActualVal: "http://changed",
   146  				},
   147  			},
   148  			"",
   149  		},
   150  		{
   151  			"string nil",
   152  			defaultConfigGen(),
   153  			func() *model.Config {
   154  				cfg := defaultConfigGen()
   155  				cfg.ServiceSettings.SiteURL = nil
   156  				return cfg
   157  			}(),
   158  			ConfigDiffs{
   159  				{
   160  					Path:    "ServiceSettings.SiteURL",
   161  					BaseVal: defaultConfigGen().ServiceSettings.SiteURL,
   162  					ActualVal: func() *string {
   163  						return nil
   164  					}(),
   165  				},
   166  			},
   167  			"",
   168  		},
   169  		{
   170  			"bool change",
   171  			defaultConfigGen(),
   172  			func() *model.Config {
   173  				cfg := defaultConfigGen()
   174  				cfg.PluginSettings.Enable = model.NewBool(!*cfg.PluginSettings.Enable)
   175  				return cfg
   176  			}(),
   177  			ConfigDiffs{
   178  				{
   179  					Path:      "PluginSettings.Enable",
   180  					BaseVal:   true,
   181  					ActualVal: false,
   182  				},
   183  			},
   184  			"",
   185  		},
   186  		{
   187  			"bool nil",
   188  			defaultConfigGen(),
   189  			func() *model.Config {
   190  				cfg := defaultConfigGen()
   191  				cfg.PluginSettings.Enable = nil
   192  				return cfg
   193  			}(),
   194  			ConfigDiffs{
   195  				{
   196  					Path:    "PluginSettings.Enable",
   197  					BaseVal: defaultConfigGen().PluginSettings.Enable,
   198  					ActualVal: func() *bool {
   199  						return nil
   200  					}(),
   201  				},
   202  			},
   203  			"",
   204  		},
   205  		{
   206  			"int change",
   207  			defaultConfigGen(),
   208  			func() *model.Config {
   209  				cfg := defaultConfigGen()
   210  				cfg.ServiceSettings.ReadTimeout = model.NewInt(0)
   211  				return cfg
   212  			}(),
   213  			ConfigDiffs{
   214  				{
   215  					Path:      "ServiceSettings.ReadTimeout",
   216  					BaseVal:   *defaultConfigGen().ServiceSettings.ReadTimeout,
   217  					ActualVal: 0,
   218  				},
   219  			},
   220  			"",
   221  		},
   222  		{
   223  			"int nil",
   224  			defaultConfigGen(),
   225  			func() *model.Config {
   226  				cfg := defaultConfigGen()
   227  				cfg.ServiceSettings.ReadTimeout = nil
   228  				return cfg
   229  			}(),
   230  			ConfigDiffs{
   231  				{
   232  					Path:    "ServiceSettings.ReadTimeout",
   233  					BaseVal: defaultConfigGen().ServiceSettings.ReadTimeout,
   234  					ActualVal: func() *int {
   235  						return nil
   236  					}(),
   237  				},
   238  			},
   239  			"",
   240  		},
   241  		{
   242  			"slice addition",
   243  			defaultConfigGen(),
   244  			func() *model.Config {
   245  				cfg := defaultConfigGen()
   246  				cfg.SqlSettings.DataSourceReplicas = []string{
   247  					"ds0",
   248  					"ds1",
   249  				}
   250  				return cfg
   251  			}(),
   252  			ConfigDiffs{
   253  				{
   254  					Path:    "SqlSettings.DataSourceReplicas",
   255  					BaseVal: defaultConfigGen().SqlSettings.DataSourceReplicas,
   256  					ActualVal: []string{
   257  						"ds0",
   258  						"ds1",
   259  					},
   260  				},
   261  			},
   262  			"",
   263  		},
   264  		{
   265  			"slice deletion",
   266  			func() *model.Config {
   267  				cfg := defaultConfigGen()
   268  				cfg.SqlSettings.DataSourceReplicas = []string{
   269  					"ds0",
   270  					"ds1",
   271  				}
   272  				return cfg
   273  			}(),
   274  			func() *model.Config {
   275  				cfg := defaultConfigGen()
   276  				cfg.SqlSettings.DataSourceReplicas = []string{
   277  					"ds0",
   278  				}
   279  				return cfg
   280  			}(),
   281  			ConfigDiffs{
   282  				{
   283  					Path: "SqlSettings.DataSourceReplicas",
   284  					BaseVal: []string{
   285  						"ds0",
   286  						"ds1",
   287  					},
   288  					ActualVal: []string{
   289  						"ds0",
   290  					},
   291  				},
   292  			},
   293  			"",
   294  		},
   295  		{
   296  			"slice nil",
   297  			func() *model.Config {
   298  				cfg := defaultConfigGen()
   299  				cfg.SqlSettings.DataSourceReplicas = []string{
   300  					"ds0",
   301  					"ds1",
   302  				}
   303  				return cfg
   304  			}(),
   305  			func() *model.Config {
   306  				cfg := defaultConfigGen()
   307  				cfg.SqlSettings.DataSourceReplicas = nil
   308  				return cfg
   309  			}(),
   310  			ConfigDiffs{
   311  				{
   312  					Path: "SqlSettings.DataSourceReplicas",
   313  					BaseVal: []string{
   314  						"ds0",
   315  						"ds1",
   316  					},
   317  					ActualVal: func() []string {
   318  						return nil
   319  					}(),
   320  				},
   321  			},
   322  			"",
   323  		},
   324  		{
   325  			"map change",
   326  			defaultConfigGen(),
   327  			func() *model.Config {
   328  				cfg := defaultConfigGen()
   329  				cfg.PluginSettings.PluginStates["com.mattermost.nps"] = &model.PluginState{
   330  					Enable: !cfg.PluginSettings.PluginStates["com.mattermost.nps"].Enable,
   331  				}
   332  				return cfg
   333  			}(),
   334  			ConfigDiffs{
   335  				{
   336  					Path:    "PluginSettings.PluginStates",
   337  					BaseVal: defaultConfigGen().PluginSettings.PluginStates,
   338  					ActualVal: map[string]*model.PluginState{
   339  						"com.mattermost.nps": {
   340  							Enable: !defaultConfigGen().PluginSettings.PluginStates["com.mattermost.nps"].Enable,
   341  						},
   342  					},
   343  				},
   344  			},
   345  			"",
   346  		},
   347  		{
   348  			"map addition",
   349  			defaultConfigGen(),
   350  			func() *model.Config {
   351  				cfg := defaultConfigGen()
   352  				cfg.PluginSettings.PluginStates["com.mattermost.newplugin"] = &model.PluginState{
   353  					Enable: true,
   354  				}
   355  				return cfg
   356  			}(),
   357  			ConfigDiffs{
   358  				{
   359  					Path:    "PluginSettings.PluginStates",
   360  					BaseVal: defaultConfigGen().PluginSettings.PluginStates,
   361  					ActualVal: map[string]*model.PluginState{
   362  						"com.mattermost.nps": {
   363  							Enable: defaultConfigGen().PluginSettings.PluginStates["com.mattermost.nps"].Enable,
   364  						},
   365  						"com.mattermost.newplugin": {
   366  							Enable: true,
   367  						},
   368  					},
   369  				},
   370  			},
   371  			"",
   372  		},
   373  		{
   374  			"map deletion",
   375  			defaultConfigGen(),
   376  			func() *model.Config {
   377  				cfg := defaultConfigGen()
   378  				delete(cfg.PluginSettings.PluginStates, "com.mattermost.nps")
   379  				return cfg
   380  			}(),
   381  			ConfigDiffs{
   382  				{
   383  					Path:    "PluginSettings.PluginStates",
   384  					BaseVal: defaultConfigGen().PluginSettings.PluginStates,
   385  					ActualVal: func() interface{} {
   386  						return map[string]*model.PluginState{}
   387  					}(),
   388  				},
   389  			},
   390  			"",
   391  		},
   392  		{
   393  			"map nil",
   394  			defaultConfigGen(),
   395  			func() *model.Config {
   396  				cfg := defaultConfigGen()
   397  				cfg.PluginSettings.PluginStates = nil
   398  				return cfg
   399  			}(),
   400  			ConfigDiffs{
   401  				{
   402  					Path:    "PluginSettings.PluginStates",
   403  					BaseVal: defaultConfigGen().PluginSettings.PluginStates,
   404  					ActualVal: func() map[string]*model.PluginState {
   405  						return nil
   406  					}(),
   407  				},
   408  			},
   409  			"",
   410  		},
   411  		{
   412  			"map type change",
   413  			func() *model.Config {
   414  				cfg := defaultConfigGen()
   415  				cfg.PluginSettings.Plugins = map[string]map[string]interface{}{
   416  					"com.mattermost.newplugin": {
   417  						"key": true,
   418  					},
   419  				}
   420  				return cfg
   421  			}(),
   422  			func() *model.Config {
   423  				cfg := defaultConfigGen()
   424  				cfg.PluginSettings.Plugins = map[string]map[string]interface{}{
   425  					"com.mattermost.newplugin": {
   426  						"key": "string",
   427  					},
   428  				}
   429  				return cfg
   430  			}(),
   431  			ConfigDiffs{
   432  				{
   433  					Path: "PluginSettings.Plugins",
   434  					BaseVal: func() interface{} {
   435  						return map[string]map[string]interface{}{
   436  							"com.mattermost.newplugin": {
   437  								"key": true,
   438  							},
   439  						}
   440  					}(),
   441  					ActualVal: func() interface{} {
   442  						return map[string]map[string]interface{}{
   443  							"com.mattermost.newplugin": {
   444  								"key": "string",
   445  							},
   446  						}
   447  					}(),
   448  				},
   449  			},
   450  			"",
   451  		},
   452  	}
   453  
   454  	for _, tc := range tcs {
   455  		t.Run(tc.name, func(t *testing.T) {
   456  			diffs, err := Diff(tc.base, tc.actual)
   457  			if tc.err != "" {
   458  				require.EqualError(t, err, tc.err)
   459  				require.Nil(t, diffs)
   460  			} else {
   461  				require.NoError(t, err)
   462  			}
   463  			require.Equal(t, tc.diffs, diffs)
   464  		})
   465  	}
   466  }