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  }