@@ -25,13 +25,136 @@ import (
2525
2626 "github.com/DATA-DOG/go-sqlmock"
2727 "github.com/blang/semver"
28+ "k8s.io/utils/ptr"
2829
30+ apiv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1"
2931 "github.com/cloudnative-pg/cloudnative-pg/pkg/postgres"
3032
3133 . "github.com/onsi/ginkgo/v2"
3234 . "github.com/onsi/gomega"
3335)
3436
37+ var _ = Describe ("areAllParamsUpdated" , func () {
38+ It ("should return true when all params match" , func () {
39+ decreased := map [string ]int {"max_connections" : 90 , "max_worker_processes" : 4 }
40+ controldata := map [string ]int {"max_connections" : 90 , "max_worker_processes" : 4 }
41+ Expect (areAllParamsUpdated (decreased , controldata )).To (BeTrue ())
42+ })
43+
44+ It ("should return false when a param doesn't match" , func () {
45+ decreased := map [string ]int {"max_connections" : 90 }
46+ controldata := map [string ]int {"max_connections" : 100 }
47+ Expect (areAllParamsUpdated (decreased , controldata )).To (BeFalse ())
48+ })
49+
50+ It ("should return false when a param is missing from controldata" , func () {
51+ decreased := map [string ]int {"max_connections" : 90 }
52+ controldata := map [string ]int {}
53+ Expect (areAllParamsUpdated (decreased , controldata )).To (BeFalse ())
54+ })
55+
56+ It ("should return true for empty decreased values" , func () {
57+ decreased := map [string ]int {}
58+ controldata := map [string ]int {"max_connections" : 100 }
59+ Expect (areAllParamsUpdated (decreased , controldata )).To (BeTrue ())
60+ })
61+ })
62+
63+ var _ = Describe ("updateResultForDecrease" , func () {
64+ // decreasedSettingsQuery matches the SQL used by GetDecreasedSensibleSettings
65+ decreasedSettingsQuery := regexp .QuoteMeta (
66+ `SELECT pending_settings.name, CAST(coalesce(new_setting,default_setting) AS INTEGER) as new_setting` )
67+
68+ Context ("when there are no decreased standby-sensitive settings" , func () {
69+ It ("should not modify the result" , func () {
70+ db , mock , err := sqlmock .New ()
71+ Expect (err ).ToNot (HaveOccurred ())
72+
73+ mock .ExpectQuery (decreasedSettingsQuery ).
74+ WillReturnRows (sqlmock .NewRows ([]string {"name" , "new_setting" }))
75+
76+ instance := & Instance {}
77+ result := & postgres.PostgresqlStatus {
78+ IsPrimary : false ,
79+ PendingRestart : true ,
80+ }
81+
82+ err = updateResultForDecrease (instance , db , result )
83+ Expect (err ).ToNot (HaveOccurred ())
84+ Expect (result .PendingRestart ).To (BeTrue ())
85+ Expect (result .PendingRestartForDecrease ).To (BeFalse ())
86+ Expect (mock .ExpectationsWereMet ()).To (Succeed ())
87+ })
88+ })
89+
90+ Context ("when this is a primary instance" , func () {
91+ It ("should keep PendingRestart true and set PendingRestartForDecrease" , func () {
92+ db , mock , err := sqlmock .New ()
93+ Expect (err ).ToNot (HaveOccurred ())
94+
95+ mock .ExpectQuery (decreasedSettingsQuery ).
96+ WillReturnRows (sqlmock .NewRows ([]string {"name" , "new_setting" }).
97+ AddRow ("max_connections" , 90 ))
98+
99+ instance := & Instance {}
100+ result := & postgres.PostgresqlStatus {
101+ IsPrimary : true ,
102+ PendingRestart : true ,
103+ }
104+
105+ err = updateResultForDecrease (instance , db , result )
106+ Expect (err ).ToNot (HaveOccurred ())
107+ Expect (result .PendingRestart ).To (BeTrue ())
108+ Expect (result .PendingRestartForDecrease ).To (BeTrue ())
109+ Expect (mock .ExpectationsWereMet ()).To (Succeed ())
110+ })
111+ })
112+
113+ Context ("when this is a replica cluster instance" , func () {
114+ DescribeTable ("should keep PendingRestart true regardless of pod role" ,
115+ func (podName string , currentPrimary string ) {
116+ db , mock , err := sqlmock .New ()
117+ Expect (err ).ToNot (HaveOccurred ())
118+
119+ mock .ExpectQuery (decreasedSettingsQuery ).
120+ WillReturnRows (sqlmock .NewRows ([]string {"name" , "new_setting" }).
121+ AddRow ("max_connections" , 95 ))
122+
123+ instance := (& Instance {}).WithPodName (podName )
124+ instance .SetCluster (& apiv1.Cluster {
125+ Spec : apiv1.ClusterSpec {
126+ ReplicaCluster : & apiv1.ReplicaClusterConfiguration {
127+ Enabled : ptr .To (true ),
128+ Source : "cluster-example" ,
129+ },
130+ },
131+ Status : apiv1.ClusterStatus {
132+ CurrentPrimary : currentPrimary ,
133+ },
134+ })
135+
136+ result := & postgres.PostgresqlStatus {
137+ IsPrimary : false ,
138+ PendingRestart : true ,
139+ }
140+
141+ err = updateResultForDecrease (instance , db , result )
142+ Expect (err ).ToNot (HaveOccurred ())
143+ // In a replica cluster, PendingRestart should remain true
144+ // because pg_controldata values come from the external source
145+ // primary, not from this cluster
146+ Expect (result .PendingRestart ).To (BeTrue ())
147+ Expect (result .PendingRestartForDecrease ).To (BeTrue ())
148+ Expect (mock .ExpectationsWereMet ()).To (Succeed ())
149+ },
150+ Entry ("designated primary" ,
151+ "cluster-replica-tls-1" , "cluster-replica-tls-1" ),
152+ Entry ("non-designated-primary standby" ,
153+ "cluster-replica-tls-2" , "cluster-replica-tls-1" ),
154+ )
155+ })
156+ })
157+
35158var _ = Describe ("probes" , func () {
36159 It ("fillWalStatus should properly handle errors" , func () {
37160 instance := & Instance {}
0 commit comments