github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/internal/healthz/ready_test.go (about) 1 package healthz_test 2 3 import ( 4 "context" 5 "net/http" 6 "net/http/httptest" 7 "testing" 8 9 "github.com/kyma-incubator/compass/components/director/pkg/persistence" 10 persistautomock "github.com/kyma-incubator/compass/components/director/pkg/persistence/automock" 11 12 "github.com/pkg/errors" 13 14 "github.com/kyma-incubator/compass/components/director/internal/healthz" 15 "github.com/kyma-incubator/compass/components/director/internal/healthz/automock" 16 "github.com/stretchr/testify/require" 17 ) 18 19 var ( 20 cfg = healthz.ReadyConfig{ 21 SchemaMigrationVersion: "XXXXXXXXXXXXXX", 22 } 23 ) 24 25 func TestNewReadinessHandler(t *testing.T) { 26 t.Run("success", func(t *testing.T) { 27 ctx := context.TODO() 28 tx := &persistautomock.PersistenceTx{} 29 tx.On("Commit").Once().Return(nil) 30 31 ctxWithTransaction := persistence.SaveToContext(ctx, tx) 32 transactioner := &persistautomock.Transactioner{} 33 transactioner.On("Begin").Once().Return(tx, nil) 34 transactioner.On("RollbackUnlessCommitted", ctx, tx).Once().Return(false) 35 transactioner.On("PingContext", ctx).Once().Return(nil) 36 defer transactioner.AssertExpectations(t) 37 38 repository := &automock.Repository{} 39 repository.On("GetVersion", ctxWithTransaction).Once().Return("XXXXXXXXXXXXXX", false, nil) 40 defer repository.AssertExpectations(t) 41 42 ready := healthz.NewReady(transactioner, cfg, repository) 43 44 // THEN 45 AssertHandlerStatusCodeForReadiness(t, ready, 200, "") 46 }) 47 48 t.Run("success when cached result", func(t *testing.T) { 49 ctx := context.TODO() 50 tx := &persistautomock.PersistenceTx{} 51 tx.On("Commit").Once().Return(nil) 52 53 ctxWithTransaction := persistence.SaveToContext(ctx, tx) 54 transactioner := &persistautomock.Transactioner{} 55 transactioner.On("Begin").Once().Return(tx, nil) 56 transactioner.On("RollbackUnlessCommitted", ctx, tx).Once().Return(false) 57 transactioner.On("PingContext", ctx).Twice().Return(nil) 58 defer transactioner.AssertExpectations(t) 59 60 repository := &automock.Repository{} 61 repository.On("GetVersion", ctxWithTransaction).Once().Return("XXXXXXXXXXXXXX", false, nil) 62 defer repository.AssertExpectations(t) 63 64 ready := healthz.NewReady(transactioner, cfg, repository) 65 66 // THEN 67 AssertHandlerStatusCodeForReadiness(t, ready, 200, "") 68 AssertHandlerStatusCodeForReadiness(t, ready, 200, "") 69 }) 70 71 t.Run("fail when ping fails", func(t *testing.T) { 72 ctx := context.TODO() 73 tx := &persistautomock.PersistenceTx{} 74 tx.On("Commit").Once().Return(nil) 75 76 ctxWithTransaction := persistence.SaveToContext(ctx, tx) 77 transactioner := &persistautomock.Transactioner{} 78 transactioner.On("Begin").Once().Return(tx, nil) 79 transactioner.On("RollbackUnlessCommitted", ctx, tx).Once().Return(true) 80 transactioner.On("PingContext", ctx).Once().Return(errors.New("Ping failure")) 81 defer transactioner.AssertExpectations(t) 82 83 repository := &automock.Repository{} 84 repository.On("GetVersion", ctxWithTransaction).Once().Return("XXXXXXXXXXXXXX", false, nil) 85 defer repository.AssertExpectations(t) 86 87 ready := healthz.NewReady(transactioner, cfg, repository) 88 89 // THEN 90 AssertHandlerStatusCodeForReadiness(t, ready, 500, "") 91 }) 92 93 t.Run("fail when schema compatibility check fails", func(t *testing.T) { 94 ctx := context.TODO() 95 tx := &persistautomock.PersistenceTx{} 96 tx.On("Commit").Once().Return(nil) 97 98 ctxWithTransaction := persistence.SaveToContext(ctx, tx) 99 transactioner := &persistautomock.Transactioner{} 100 transactioner.On("Begin").Once().Return(tx, nil) 101 transactioner.On("RollbackUnlessCommitted", ctx, tx).Once().Return(true) 102 103 repository := &automock.Repository{} 104 repository.On("GetVersion", ctxWithTransaction).Once().Return("YYYYYYYYYYYYY", false, nil) 105 defer repository.AssertExpectations(t) 106 107 ready := healthz.NewReady(transactioner, cfg, repository) 108 109 // THEN 110 AssertHandlerStatusCodeForReadiness(t, ready, 500, "") 111 }) 112 113 t.Run("fail when schema dirty flag is set", func(t *testing.T) { 114 ctx := context.TODO() 115 tx := &persistautomock.PersistenceTx{} 116 tx.On("Commit").Once().Return(nil) 117 118 ctxWithTransaction := persistence.SaveToContext(ctx, tx) 119 transactioner := &persistautomock.Transactioner{} 120 transactioner.On("Begin").Once().Return(tx, nil) 121 transactioner.On("RollbackUnlessCommitted", ctx, tx).Once().Return(true) 122 123 repository := &automock.Repository{} 124 repository.On("GetVersion", ctxWithTransaction).Once().Return("XXXXXXXXXXXXXX", true, nil) 125 defer repository.AssertExpectations(t) 126 127 ready := healthz.NewReady(transactioner, cfg, repository) 128 129 // THEN 130 AssertHandlerStatusCodeForReadiness(t, ready, 500, "") 131 }) 132 133 t.Run("fail when error is received while getting schema version from database", func(t *testing.T) { 134 ctx := context.TODO() 135 tx := &persistautomock.PersistenceTx{} 136 tx.On("Commit").Once().Return(nil) 137 138 ctxWithTransaction := persistence.SaveToContext(ctx, tx) 139 transactioner := &persistautomock.Transactioner{} 140 transactioner.On("Begin").Once().Return(tx, nil) 141 transactioner.On("RollbackUnlessCommitted", ctx, tx).Once().Return(true) 142 143 repository := &automock.Repository{} 144 repository.On("GetVersion", ctxWithTransaction).Once().Return("", false, errors.New("db error")) 145 defer repository.AssertExpectations(t) 146 147 ready := healthz.NewReady(transactioner, cfg, repository) 148 149 // THEN 150 AssertHandlerStatusCodeForReadiness(t, ready, 500, "") 151 }) 152 153 t.Run("fail while opening transaction", func(t *testing.T) { 154 ctx := context.TODO() 155 tx := &persistautomock.PersistenceTx{} 156 157 transactioner := &persistautomock.Transactioner{} 158 transactioner.On("Begin").Once().Return(nil, errors.New("error while opening transaction")) 159 transactioner.On("RollbackUnlessCommitted", ctx, tx).Once().Return(true) 160 161 repository := &automock.Repository{} 162 163 ready := healthz.NewReady(transactioner, cfg, repository) 164 165 // THEN 166 AssertHandlerStatusCodeForReadiness(t, ready, 500, "") 167 }) 168 169 t.Run("fail while committing", func(t *testing.T) { 170 ctx := context.TODO() 171 tx := &persistautomock.PersistenceTx{} 172 tx.On("Commit").Once().Return(errors.New("commit error")) 173 174 transactioner := &persistautomock.Transactioner{} 175 transactioner.On("Begin").Once().Return(nil, errors.New("error while opening transaction")) 176 transactioner.On("RollbackUnlessCommitted", ctx, tx).Once().Return(true) 177 178 repository := &automock.Repository{} 179 180 ready := healthz.NewReady(transactioner, cfg, repository) 181 182 // THEN 183 AssertHandlerStatusCodeForReadiness(t, ready, 500, "") 184 }) 185 } 186 187 func AssertHandlerStatusCodeForReadiness(t *testing.T, r *healthz.Ready, expectedCode int, expectedBody string) { 188 req, err := http.NewRequest("GET", "/readyz", nil) 189 require.NoError(t, err) 190 191 rr := httptest.NewRecorder() 192 handler := http.HandlerFunc(healthz.NewReadinessHandler(r)) 193 // WHEN 194 handler.ServeHTTP(rr, req) 195 // THEN 196 require.Equal(t, expectedCode, rr.Code) 197 require.Equal(t, expectedBody, rr.Body.String()) 198 }