config_test.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1. // Copyright 2020 gorse Project Authors
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package config
  15. import (
  16. "bytes"
  17. "fmt"
  18. "os"
  19. "path/filepath"
  20. "strings"
  21. "testing"
  22. "time"
  23. "github.com/sclevine/yj/convert"
  24. "github.com/spf13/viper"
  25. "github.com/stretchr/testify/assert"
  26. )
  27. func TestUnmarshal(t *testing.T) {
  28. data, err := os.ReadFile("config.toml")
  29. assert.NoError(t, err)
  30. text := string(data)
  31. text = strings.Replace(text, "dashboard_user_name = \"\"", "dashboard_user_name = \"admin\"", -1)
  32. text = strings.Replace(text, "dashboard_password = \"\"", "dashboard_password = \"password\"", -1)
  33. text = strings.Replace(text, "admin_api_key = \"\"", "admin_api_key = \"super_api_key\"", -1)
  34. text = strings.Replace(text, "api_key = \"\"", "api_key = \"19260817\"", -1)
  35. text = strings.Replace(text, "table_prefix = \"\"", "table_prefix = \"gorse_\"", -1)
  36. text = strings.Replace(text, "cache_table_prefix = \"gorse_\"", "cache_table_prefix = \"gorse_cache_\"", -1)
  37. text = strings.Replace(text, "data_table_prefix = \"gorse_\"", "data_table_prefix = \"gorse_data_\"", -1)
  38. text = strings.Replace(text, "http_cors_domains = []", "http_cors_domains = [\".*\"]", -1)
  39. text = strings.Replace(text, "http_cors_methods = []", "http_cors_methods = [\"GET\",\"PATCH\",\"POST\"]", -1)
  40. r, err := convert.TOML{}.Decode(bytes.NewBufferString(text))
  41. assert.NoError(t, err)
  42. encodings := []convert.Encoding{convert.TOML{}, convert.YAML{}, convert.JSON{}}
  43. for _, encoding := range encodings {
  44. t.Run(encoding.String(), func(t *testing.T) {
  45. filePath := filepath.Join(os.TempDir(), fmt.Sprintf("config.%s", strings.ToLower(encoding.String())))
  46. fp, err := os.Create(filePath)
  47. assert.NoError(t, err)
  48. err = encoding.Encode(fp, r)
  49. assert.NoError(t, err)
  50. config, err := LoadConfig(filePath, false)
  51. assert.NoError(t, err)
  52. // [database]
  53. assert.Equal(t, "redis://localhost:6379/0", config.Database.CacheStore)
  54. assert.Equal(t, "mysql://gorse:gorse_pass@tcp(localhost:3306)/gorse", config.Database.DataStore)
  55. assert.Equal(t, "gorse_", config.Database.TablePrefix)
  56. assert.Equal(t, "gorse_cache_", config.Database.CacheTablePrefix)
  57. assert.Equal(t, "gorse_data_", config.Database.DataTablePrefix)
  58. // [master]
  59. assert.Equal(t, 8086, config.Master.Port)
  60. assert.Equal(t, "0.0.0.0", config.Master.Host)
  61. assert.Equal(t, 8088, config.Master.HttpPort)
  62. assert.Equal(t, "0.0.0.0", config.Master.HttpHost)
  63. assert.Equal(t, []string{".*"}, config.Master.HttpCorsDomains)
  64. assert.Equal(t, []string{"GET", "PATCH", "POST"}, config.Master.HttpCorsMethods)
  65. assert.Equal(t, 1, config.Master.NumJobs)
  66. assert.Equal(t, 10*time.Second, config.Master.MetaTimeout)
  67. assert.Equal(t, "admin", config.Master.DashboardUserName)
  68. assert.Equal(t, "password", config.Master.DashboardPassword)
  69. assert.Equal(t, "super_api_key", config.Master.AdminAPIKey)
  70. // [server]
  71. assert.Equal(t, 10, config.Server.DefaultN)
  72. assert.Equal(t, "19260817", config.Server.APIKey)
  73. assert.Equal(t, 5*time.Second, config.Server.ClockError)
  74. assert.True(t, config.Server.AutoInsertUser)
  75. assert.True(t, config.Server.AutoInsertItem)
  76. assert.Equal(t, 10*time.Second, config.Server.CacheExpire)
  77. // [recommend]
  78. assert.Equal(t, 100, config.Recommend.CacheSize)
  79. assert.Equal(t, 72*time.Hour, config.Recommend.CacheExpire)
  80. // [recommend.data_source]
  81. assert.Equal(t, []string{"star", "like"}, config.Recommend.DataSource.PositiveFeedbackTypes)
  82. assert.Equal(t, []string{"read"}, config.Recommend.DataSource.ReadFeedbackTypes)
  83. assert.Equal(t, uint(0), config.Recommend.DataSource.PositiveFeedbackTTL)
  84. assert.Equal(t, uint(0), config.Recommend.DataSource.ItemTTL)
  85. // [recommend.popular]
  86. assert.Equal(t, 30*24*time.Hour, config.Recommend.Popular.PopularWindow)
  87. // [recommend.user_neighbors]
  88. assert.Equal(t, "similar", config.Recommend.UserNeighbors.NeighborType)
  89. assert.True(t, config.Recommend.UserNeighbors.EnableIndex)
  90. assert.Equal(t, float32(0.8), config.Recommend.UserNeighbors.IndexRecall)
  91. assert.Equal(t, 3, config.Recommend.UserNeighbors.IndexFitEpoch)
  92. // [recommend.item_neighbors]
  93. assert.Equal(t, "similar", config.Recommend.ItemNeighbors.NeighborType)
  94. assert.True(t, config.Recommend.ItemNeighbors.EnableIndex)
  95. assert.Equal(t, float32(0.8), config.Recommend.ItemNeighbors.IndexRecall)
  96. assert.Equal(t, 3, config.Recommend.ItemNeighbors.IndexFitEpoch)
  97. // [recommend.collaborative]
  98. assert.True(t, config.Recommend.Collaborative.EnableIndex)
  99. assert.Equal(t, float32(0.9), config.Recommend.Collaborative.IndexRecall)
  100. assert.Equal(t, 3, config.Recommend.Collaborative.IndexFitEpoch)
  101. assert.Equal(t, 60*time.Minute, config.Recommend.Collaborative.ModelFitPeriod)
  102. assert.Equal(t, 360*time.Minute, config.Recommend.Collaborative.ModelSearchPeriod)
  103. assert.Equal(t, 100, config.Recommend.Collaborative.ModelSearchEpoch)
  104. assert.Equal(t, 10, config.Recommend.Collaborative.ModelSearchTrials)
  105. assert.False(t, config.Recommend.Collaborative.EnableModelSizeSearch)
  106. // [recommend.replacement]
  107. assert.False(t, config.Recommend.Replacement.EnableReplacement)
  108. assert.Equal(t, 0.8, config.Recommend.Replacement.PositiveReplacementDecay)
  109. assert.Equal(t, 0.6, config.Recommend.Replacement.ReadReplacementDecay)
  110. // [recommend.offline]
  111. assert.Equal(t, time.Minute, config.Recommend.Offline.CheckRecommendPeriod)
  112. assert.Equal(t, 24*time.Hour, config.Recommend.Offline.RefreshRecommendPeriod)
  113. assert.True(t, config.Recommend.Offline.EnableColRecommend)
  114. assert.False(t, config.Recommend.Offline.EnableItemBasedRecommend)
  115. assert.True(t, config.Recommend.Offline.EnableUserBasedRecommend)
  116. assert.False(t, config.Recommend.Offline.EnablePopularRecommend)
  117. assert.True(t, config.Recommend.Offline.EnableLatestRecommend)
  118. assert.True(t, config.Recommend.Offline.EnableClickThroughPrediction)
  119. assert.Equal(t, map[string]float64{"popular": 0.1, "latest": 0.2}, config.Recommend.Offline.ExploreRecommend)
  120. value, exist := config.Recommend.Offline.GetExploreRecommend("popular")
  121. assert.Equal(t, true, exist)
  122. assert.Equal(t, 0.1, value)
  123. value, exist = config.Recommend.Offline.GetExploreRecommend("latest")
  124. assert.Equal(t, true, exist)
  125. assert.Equal(t, 0.2, value)
  126. _, exist = config.Recommend.Offline.GetExploreRecommend("unknown")
  127. assert.Equal(t, false, exist)
  128. // [recommend.online]
  129. assert.Equal(t, []string{"item_based", "latest"}, config.Recommend.Online.FallbackRecommend)
  130. assert.Equal(t, 10, config.Recommend.Online.NumFeedbackFallbackItemBased)
  131. // [tracing]
  132. assert.False(t, config.Tracing.EnableTracing)
  133. assert.Equal(t, "jaeger", config.Tracing.Exporter)
  134. assert.Equal(t, "http://localhost:14268/api/traces", config.Tracing.CollectorEndpoint)
  135. assert.Equal(t, "always", config.Tracing.Sampler)
  136. assert.Equal(t, 1.0, config.Tracing.Ratio)
  137. // [experimental]
  138. assert.Equal(t, 128, config.Experimental.DeepLearningBatchSize)
  139. })
  140. }
  141. }
  142. func TestSetDefault(t *testing.T) {
  143. setDefault()
  144. viper.SetConfigType("toml")
  145. err := viper.ReadConfig(strings.NewReader(""))
  146. assert.NoError(t, err)
  147. var config Config
  148. err = viper.Unmarshal(&config)
  149. assert.NoError(t, err)
  150. assert.Equal(t, GetDefaultConfig(), &config)
  151. }
  152. type environmentVariable struct {
  153. key string
  154. value string
  155. }
  156. func TestBindEnv(t *testing.T) {
  157. variables := []environmentVariable{
  158. {"GORSE_CACHE_STORE", "redis://<cache_store>"},
  159. {"GORSE_DATA_STORE", "mysql://<data_store>"},
  160. {"GORSE_TABLE_PREFIX", "gorse_"},
  161. {"GORSE_DATA_TABLE_PREFIX", "gorse_data_"},
  162. {"GORSE_CACHE_TABLE_PREFIX", "gorse_cache_"},
  163. {"GORSE_MASTER_PORT", "123"},
  164. {"GORSE_MASTER_HOST", "<master_host>"},
  165. {"GORSE_MASTER_HTTP_PORT", "456"},
  166. {"GORSE_MASTER_HTTP_HOST", "<master_http_host>"},
  167. {"GORSE_MASTER_JOBS", "789"},
  168. {"GORSE_DASHBOARD_USER_NAME", "user_name"},
  169. {"GORSE_DASHBOARD_PASSWORD", "password"},
  170. {"GORSE_DASHBOARD_AUTH_SERVER", "http://127.0.0.1:8888"},
  171. {"GORSE_DASHBOARD_REDACTED", "true"},
  172. {"GORSE_ADMIN_API_KEY", "<admin_api_key>"},
  173. {"GORSE_SERVER_API_KEY", "<server_api_key>"},
  174. }
  175. for _, variable := range variables {
  176. t.Setenv(variable.key, variable.value)
  177. }
  178. config, err := LoadConfig("config.toml", false)
  179. assert.NoError(t, err)
  180. assert.Equal(t, "redis://<cache_store>", config.Database.CacheStore)
  181. assert.Equal(t, "mysql://<data_store>", config.Database.DataStore)
  182. assert.Equal(t, "gorse_", config.Database.TablePrefix)
  183. assert.Equal(t, "gorse_cache_", config.Database.CacheTablePrefix)
  184. assert.Equal(t, "gorse_data_", config.Database.DataTablePrefix)
  185. assert.Equal(t, 123, config.Master.Port)
  186. assert.Equal(t, "<master_host>", config.Master.Host)
  187. assert.Equal(t, 456, config.Master.HttpPort)
  188. assert.Equal(t, "<master_http_host>", config.Master.HttpHost)
  189. assert.Equal(t, 789, config.Master.NumJobs)
  190. assert.Equal(t, "user_name", config.Master.DashboardUserName)
  191. assert.Equal(t, "password", config.Master.DashboardPassword)
  192. assert.Equal(t, "http://127.0.0.1:8888", config.Master.DashboardAuthServer)
  193. assert.Equal(t, true, config.Master.DashboardRedacted)
  194. assert.Equal(t, "<admin_api_key>", config.Master.AdminAPIKey)
  195. assert.Equal(t, "<server_api_key>", config.Server.APIKey)
  196. // check default values
  197. assert.Equal(t, 100, config.Recommend.CacheSize)
  198. }
  199. func TestTablePrefixCompat(t *testing.T) {
  200. data, err := os.ReadFile("config.toml")
  201. assert.NoError(t, err)
  202. text := string(data)
  203. text = strings.Replace(text, "cache_table_prefix = \"\"", "", -1)
  204. text = strings.Replace(text, "data_table_prefix = \"\"", "", -1)
  205. text = strings.Replace(text, "table_prefix = \"\"", "table_prefix = \"gorse_\"", -1)
  206. path := filepath.Join(t.TempDir(), "config.toml")
  207. err = os.WriteFile(path, []byte(text), os.ModePerm)
  208. assert.NoError(t, err)
  209. config, err := LoadConfig(path, false)
  210. assert.NoError(t, err)
  211. assert.Equal(t, "gorse_", config.Database.TablePrefix)
  212. assert.Equal(t, "gorse_", config.Database.CacheTablePrefix)
  213. assert.Equal(t, "gorse_", config.Database.DataTablePrefix)
  214. }
  215. func TestConfig_UserNeighborDigest(t *testing.T) {
  216. cfg1, cfg2 := GetDefaultConfig(), GetDefaultConfig()
  217. cfg1.Recommend.UserNeighbors.NeighborType = "auto"
  218. cfg2.Recommend.UserNeighbors.NeighborType = "manual"
  219. assert.NotEqual(t, cfg1.UserNeighborDigest(), cfg2.UserNeighborDigest())
  220. cfg1, cfg2 = GetDefaultConfig(), GetDefaultConfig()
  221. cfg1.Recommend.UserNeighbors.EnableIndex = true
  222. cfg2.Recommend.UserNeighbors.EnableIndex = false
  223. assert.NotEqual(t, cfg1.UserNeighborDigest(), cfg2.UserNeighborDigest())
  224. cfg1, cfg2 = GetDefaultConfig(), GetDefaultConfig()
  225. cfg1.Recommend.UserNeighbors.NeighborType = "auto"
  226. cfg2.Recommend.UserNeighbors.NeighborType = "auto"
  227. cfg1.Recommend.DataSource.PositiveFeedbackTypes = []string{"positive"}
  228. cfg2.Recommend.DataSource.PositiveFeedbackTypes = []string{"negative"}
  229. assert.NotEqual(t, cfg1.UserNeighborDigest(), cfg2.UserNeighborDigest())
  230. cfg1, cfg2 = GetDefaultConfig(), GetDefaultConfig()
  231. cfg1.Recommend.UserNeighbors.NeighborType = "related"
  232. cfg2.Recommend.UserNeighbors.NeighborType = "related"
  233. cfg1.Recommend.DataSource.PositiveFeedbackTypes = []string{"positive"}
  234. cfg2.Recommend.DataSource.PositiveFeedbackTypes = []string{"negative"}
  235. assert.NotEqual(t, cfg1.UserNeighborDigest(), cfg2.UserNeighborDigest())
  236. cfg1, cfg2 = GetDefaultConfig(), GetDefaultConfig()
  237. cfg1.Recommend.UserNeighbors.NeighborType = "similar"
  238. cfg2.Recommend.UserNeighbors.NeighborType = "similar"
  239. cfg1.Recommend.DataSource.PositiveFeedbackTypes = []string{"positive"}
  240. cfg2.Recommend.DataSource.PositiveFeedbackTypes = []string{"negative"}
  241. assert.Equal(t, cfg1.UserNeighborDigest(), cfg2.UserNeighborDigest())
  242. cfg1, cfg2 = GetDefaultConfig(), GetDefaultConfig()
  243. cfg1.Recommend.UserNeighbors.EnableIndex = true
  244. cfg2.Recommend.UserNeighbors.EnableIndex = true
  245. cfg1.Recommend.UserNeighbors.IndexRecall = 0.5
  246. cfg2.Recommend.UserNeighbors.IndexRecall = 0.6
  247. assert.NotEqual(t, cfg1.UserNeighborDigest(), cfg2.UserNeighborDigest())
  248. cfg1, cfg2 = GetDefaultConfig(), GetDefaultConfig()
  249. cfg1.Recommend.UserNeighbors.EnableIndex = true
  250. cfg2.Recommend.UserNeighbors.EnableIndex = true
  251. cfg1.Recommend.UserNeighbors.IndexFitEpoch = 10
  252. cfg2.Recommend.UserNeighbors.IndexFitEpoch = 11
  253. assert.NotEqual(t, cfg1.UserNeighborDigest(), cfg2.UserNeighborDigest())
  254. }
  255. func TestConfig_ItemNeighborDigest(t *testing.T) {
  256. cfg1, cfg2 := GetDefaultConfig(), GetDefaultConfig()
  257. cfg1.Recommend.ItemNeighbors.NeighborType = "auto"
  258. cfg2.Recommend.ItemNeighbors.NeighborType = "related"
  259. assert.NotEqual(t, cfg1.ItemNeighborDigest(), cfg2.ItemNeighborDigest())
  260. cfg1, cfg2 = GetDefaultConfig(), GetDefaultConfig()
  261. cfg1.Recommend.ItemNeighbors.EnableIndex = true
  262. cfg2.Recommend.ItemNeighbors.EnableIndex = false
  263. assert.NotEqual(t, cfg1.ItemNeighborDigest(), cfg2.ItemNeighborDigest())
  264. cfg1, cfg2 = GetDefaultConfig(), GetDefaultConfig()
  265. cfg1.Recommend.ItemNeighbors.NeighborType = "auto"
  266. cfg2.Recommend.ItemNeighbors.NeighborType = "auto"
  267. cfg1.Recommend.DataSource.PositiveFeedbackTypes = []string{"positive"}
  268. cfg2.Recommend.DataSource.PositiveFeedbackTypes = []string{"negative"}
  269. assert.NotEqual(t, cfg1.ItemNeighborDigest(), cfg2.ItemNeighborDigest())
  270. cfg1, cfg2 = GetDefaultConfig(), GetDefaultConfig()
  271. cfg1.Recommend.ItemNeighbors.NeighborType = "related"
  272. cfg2.Recommend.ItemNeighbors.NeighborType = "related"
  273. cfg1.Recommend.DataSource.PositiveFeedbackTypes = []string{"positive"}
  274. cfg2.Recommend.DataSource.PositiveFeedbackTypes = []string{"negative"}
  275. assert.NotEqual(t, cfg1.ItemNeighborDigest(), cfg2.ItemNeighborDigest())
  276. cfg1, cfg2 = GetDefaultConfig(), GetDefaultConfig()
  277. cfg1.Recommend.ItemNeighbors.NeighborType = "similar"
  278. cfg2.Recommend.ItemNeighbors.NeighborType = "similar"
  279. cfg1.Recommend.DataSource.PositiveFeedbackTypes = []string{"positive"}
  280. cfg2.Recommend.DataSource.PositiveFeedbackTypes = []string{"negative"}
  281. assert.Equal(t, cfg1.ItemNeighborDigest(), cfg2.ItemNeighborDigest())
  282. cfg1, cfg2 = GetDefaultConfig(), GetDefaultConfig()
  283. cfg1.Recommend.ItemNeighbors.EnableIndex = true
  284. cfg2.Recommend.ItemNeighbors.EnableIndex = true
  285. cfg1.Recommend.ItemNeighbors.IndexRecall = 0.5
  286. cfg2.Recommend.ItemNeighbors.IndexRecall = 0.6
  287. assert.NotEqual(t, cfg1.ItemNeighborDigest(), cfg2.ItemNeighborDigest())
  288. cfg1, cfg2 = GetDefaultConfig(), GetDefaultConfig()
  289. cfg1.Recommend.ItemNeighbors.EnableIndex = true
  290. cfg2.Recommend.ItemNeighbors.EnableIndex = true
  291. cfg1.Recommend.ItemNeighbors.IndexFitEpoch = 10
  292. cfg2.Recommend.ItemNeighbors.IndexFitEpoch = 11
  293. assert.NotEqual(t, cfg1.ItemNeighborDigest(), cfg2.ItemNeighborDigest())
  294. }
  295. func TestConfig_OfflineRecommendDigest(t *testing.T) {
  296. // test explore recommendation
  297. cfg1, cfg2 := GetDefaultConfig(), GetDefaultConfig()
  298. cfg1.Recommend.Offline.ExploreRecommend = map[string]float64{"a": 0.5, "b": 0.6}
  299. cfg2.Recommend.Offline.ExploreRecommend = map[string]float64{"a": 0.6, "b": 0.5}
  300. assert.NotEqual(t, cfg1.OfflineRecommendDigest(), cfg2.OfflineRecommendDigest())
  301. // test latest recommendation
  302. cfg1, cfg2 = GetDefaultConfig(), GetDefaultConfig()
  303. cfg1.Recommend.Offline.EnableLatestRecommend = true
  304. cfg2.Recommend.Offline.EnableLatestRecommend = false
  305. assert.NotEqual(t, cfg1.OfflineRecommendDigest(), cfg2.OfflineRecommendDigest())
  306. // test popular recommendation
  307. cfg1, cfg2 = GetDefaultConfig(), GetDefaultConfig()
  308. cfg1.Recommend.Offline.EnablePopularRecommend = true
  309. cfg2.Recommend.Offline.EnablePopularRecommend = false
  310. assert.NotEqual(t, cfg1.OfflineRecommendDigest(), cfg2.OfflineRecommendDigest())
  311. cfg1, cfg2 = GetDefaultConfig(), GetDefaultConfig()
  312. cfg1.Recommend.Offline.EnablePopularRecommend = true
  313. cfg2.Recommend.Offline.EnablePopularRecommend = true
  314. cfg1.Recommend.Popular.PopularWindow = 10
  315. cfg2.Recommend.Popular.PopularWindow = 11
  316. assert.NotEqual(t, cfg1.OfflineRecommendDigest(), cfg2.OfflineRecommendDigest())
  317. cfg1, cfg2 = GetDefaultConfig(), GetDefaultConfig()
  318. cfg1.Recommend.Offline.EnablePopularRecommend = false
  319. cfg2.Recommend.Offline.EnablePopularRecommend = false
  320. cfg1.Recommend.Popular.PopularWindow = 10
  321. cfg2.Recommend.Popular.PopularWindow = 11
  322. assert.Equal(t, cfg1.OfflineRecommendDigest(), cfg2.OfflineRecommendDigest())
  323. // test user-based recommendation
  324. cfg1, cfg2 = GetDefaultConfig(), GetDefaultConfig()
  325. cfg1.Recommend.Offline.EnableUserBasedRecommend = true
  326. cfg2.Recommend.Offline.EnableUserBasedRecommend = false
  327. assert.NotEqual(t, cfg1.OfflineRecommendDigest(), cfg2.OfflineRecommendDigest())
  328. cfg1, cfg2 = GetDefaultConfig(), GetDefaultConfig()
  329. cfg1.Recommend.Offline.EnableUserBasedRecommend = true
  330. cfg2.Recommend.Offline.EnableUserBasedRecommend = true
  331. assert.NotEqual(t, cfg1.OfflineRecommendDigest(WithUserNeighborDigest("1")), cfg2.OfflineRecommendDigest(WithUserNeighborDigest("2")))
  332. cfg1, cfg2 = GetDefaultConfig(), GetDefaultConfig()
  333. cfg1.Recommend.Offline.EnableUserBasedRecommend = false
  334. cfg2.Recommend.Offline.EnableUserBasedRecommend = false
  335. assert.Equal(t, cfg1.OfflineRecommendDigest(WithUserNeighborDigest("1")), cfg2.OfflineRecommendDigest(WithUserNeighborDigest("2")))
  336. // test item-based recommendation
  337. cfg1, cfg2 = GetDefaultConfig(), GetDefaultConfig()
  338. cfg1.Recommend.Offline.EnableItemBasedRecommend = true
  339. cfg2.Recommend.Offline.EnableItemBasedRecommend = false
  340. assert.NotEqual(t, cfg1.OfflineRecommendDigest(), cfg2.OfflineRecommendDigest())
  341. cfg1, cfg2 = GetDefaultConfig(), GetDefaultConfig()
  342. cfg1.Recommend.Offline.EnableItemBasedRecommend = true
  343. cfg2.Recommend.Offline.EnableItemBasedRecommend = true
  344. assert.NotEqual(t, cfg1.OfflineRecommendDigest(WithItemNeighborDigest("1")), cfg2.OfflineRecommendDigest(WithItemNeighborDigest("2")))
  345. cfg1, cfg2 = GetDefaultConfig(), GetDefaultConfig()
  346. cfg1.Recommend.Offline.EnableItemBasedRecommend = false
  347. cfg2.Recommend.Offline.EnableItemBasedRecommend = false
  348. assert.Equal(t, cfg1.OfflineRecommendDigest(WithItemNeighborDigest("1")), cfg2.OfflineRecommendDigest(WithItemNeighborDigest("2")))
  349. // test collaborative-filtering recommendation
  350. cfg1, cfg2 = GetDefaultConfig(), GetDefaultConfig()
  351. cfg1.Recommend.Offline.EnableColRecommend = true
  352. cfg2.Recommend.Offline.EnableColRecommend = false
  353. assert.NotEqual(t, cfg1.OfflineRecommendDigest(), cfg2.OfflineRecommendDigest())
  354. cfg1, cfg2 = GetDefaultConfig(), GetDefaultConfig()
  355. cfg1.Recommend.Offline.EnableColRecommend = true
  356. cfg2.Recommend.Offline.EnableColRecommend = true
  357. cfg1.Recommend.Collaborative.EnableIndex = true
  358. cfg2.Recommend.Collaborative.EnableIndex = false
  359. assert.NotEqual(t, cfg1.OfflineRecommendDigest(), cfg2.OfflineRecommendDigest())
  360. cfg1, cfg2 = GetDefaultConfig(), GetDefaultConfig()
  361. cfg1.Recommend.Offline.EnableColRecommend = true
  362. cfg2.Recommend.Offline.EnableColRecommend = true
  363. cfg1.Recommend.Collaborative.EnableIndex = true
  364. cfg2.Recommend.Collaborative.EnableIndex = true
  365. cfg1.Recommend.Collaborative.IndexRecall = 0.4
  366. cfg2.Recommend.Collaborative.IndexRecall = 0.5
  367. assert.NotEqual(t, cfg1.OfflineRecommendDigest(), cfg2.OfflineRecommendDigest())
  368. cfg1, cfg2 = GetDefaultConfig(), GetDefaultConfig()
  369. cfg1.Recommend.Offline.EnableColRecommend = true
  370. cfg2.Recommend.Offline.EnableColRecommend = true
  371. cfg1.Recommend.Collaborative.EnableIndex = false
  372. cfg2.Recommend.Collaborative.EnableIndex = false
  373. cfg1.Recommend.Collaborative.IndexRecall = 0.4
  374. cfg2.Recommend.Collaborative.IndexRecall = 0.5
  375. assert.Equal(t, cfg1.OfflineRecommendDigest(), cfg2.OfflineRecommendDigest())
  376. cfg1, cfg2 = GetDefaultConfig(), GetDefaultConfig()
  377. cfg1.Recommend.Offline.EnableColRecommend = false
  378. cfg2.Recommend.Offline.EnableColRecommend = false
  379. assert.NotEqual(t, cfg1.OfflineRecommendDigest(WithCollaborative(true)), cfg2.OfflineRecommendDigest())
  380. // test click-through rate prediction recommendation
  381. cfg1, cfg2 = GetDefaultConfig(), GetDefaultConfig()
  382. cfg1.Recommend.Offline.EnableClickThroughPrediction = true
  383. cfg2.Recommend.Offline.EnableClickThroughPrediction = false
  384. assert.NotEqual(t, cfg1.OfflineRecommendDigest(), cfg2.OfflineRecommendDigest())
  385. cfg1, cfg2 = GetDefaultConfig(), GetDefaultConfig()
  386. cfg1.Recommend.Offline.EnableClickThroughPrediction = false
  387. cfg2.Recommend.Offline.EnableClickThroughPrediction = false
  388. assert.NotEqual(t, cfg1.OfflineRecommendDigest(WithRanking(true)), cfg2.OfflineRecommendDigest())
  389. // test replacement
  390. cfg1, cfg2 = GetDefaultConfig(), GetDefaultConfig()
  391. cfg1.Recommend.Replacement.EnableReplacement = true
  392. cfg2.Recommend.Replacement.EnableReplacement = false
  393. assert.NotEqual(t, cfg1.OfflineRecommendDigest(), cfg2.OfflineRecommendDigest())
  394. cfg1, cfg2 = GetDefaultConfig(), GetDefaultConfig()
  395. cfg1.Recommend.Replacement.EnableReplacement = true
  396. cfg2.Recommend.Replacement.EnableReplacement = true
  397. cfg1.Recommend.Replacement.PositiveReplacementDecay = 0.1
  398. cfg2.Recommend.Replacement.PositiveReplacementDecay = 0.2
  399. assert.NotEqual(t, cfg1.OfflineRecommendDigest(), cfg2.OfflineRecommendDigest())
  400. cfg1, cfg2 = GetDefaultConfig(), GetDefaultConfig()
  401. cfg1.Recommend.Replacement.EnableReplacement = false
  402. cfg2.Recommend.Replacement.EnableReplacement = false
  403. cfg1.Recommend.Replacement.PositiveReplacementDecay = 0.1
  404. cfg2.Recommend.Replacement.PositiveReplacementDecay = 0.2
  405. assert.Equal(t, cfg1.OfflineRecommendDigest(), cfg2.OfflineRecommendDigest())
  406. }