github.com/kyma-project/kyma-environment-broker@v0.0.1/internal/orchestration/handlers/kyma_handler_test.go (about)

     1  package handlers
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"fmt"
     7  	"net/http"
     8  	"net/http/httptest"
     9  	"net/url"
    10  	"strconv"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/google/go-github/github"
    15  	"github.com/kyma-project/kyma-environment-broker/common/orchestration"
    16  	"github.com/kyma-project/kyma-environment-broker/internal"
    17  	"github.com/kyma-project/kyma-environment-broker/internal/process"
    18  	"github.com/kyma-project/kyma-environment-broker/internal/storage"
    19  	"github.com/stretchr/testify/assert"
    20  
    21  	"github.com/gorilla/mux"
    22  	"github.com/sirupsen/logrus"
    23  	"github.com/stretchr/testify/require"
    24  )
    25  
    26  func TestKymaHandler_AttachRoutes(t *testing.T) {
    27  	t.Run("upgrade", func(t *testing.T) {
    28  		// given
    29  		kHandler := fixKymaHandler(t)
    30  
    31  		params := orchestration.Parameters{
    32  			Targets: orchestration.TargetSpec{
    33  				Include: []orchestration.RuntimeTarget{
    34  					{
    35  						RuntimeID: "test",
    36  					},
    37  				},
    38  			},
    39  			Kubernetes: &orchestration.KubernetesParameters{
    40  				KubernetesVersion: "",
    41  			},
    42  			Kyma: &orchestration.KymaParameters{
    43  				Version: "",
    44  			},
    45  			Strategy: orchestration.StrategySpec{
    46  				Schedule: "now",
    47  			},
    48  		}
    49  		p, err := json.Marshal(&params)
    50  		require.NoError(t, err)
    51  
    52  		req, err := http.NewRequest("POST", "/upgrade/kyma", bytes.NewBuffer(p))
    53  		require.NoError(t, err)
    54  
    55  		rr := httptest.NewRecorder()
    56  		router := mux.NewRouter()
    57  		kHandler.AttachRoutes(router)
    58  
    59  		// when
    60  		router.ServeHTTP(rr, req)
    61  
    62  		// then
    63  		require.Equal(t, http.StatusAccepted, rr.Code)
    64  
    65  		var out orchestration.UpgradeResponse
    66  
    67  		err = json.Unmarshal(rr.Body.Bytes(), &out)
    68  		require.NoError(t, err)
    69  		assert.NotEmpty(t, out.OrchestrationID)
    70  	})
    71  }
    72  
    73  // Testing Kyma Version is disabled due to GitHub API RATE limits
    74  func TestKymaHandler_KymaVersion(t *testing.T) {
    75  	t.Run("kyma version validation", func(t *testing.T) {
    76  		// given
    77  		kHandler := fixKymaHandler(t)
    78  
    79  		// test semantic version
    80  		// Exists: 1.18.0
    81  		require.NoError(t, kHandler.ValidateKymaVersion("1.18.0"))
    82  
    83  		err := kHandler.ValidateKymaVersion("0.12.34")
    84  		require.NotNil(t, err)
    85  		require.Contains(t, err.Error(), "not found")
    86  
    87  		// test PR- version
    88  		// Exists: 10542
    89  		require.NoError(t, kHandler.ValidateKymaVersion("PR-10542"))
    90  
    91  		err = kHandler.ValidateKymaVersion("PR-0")
    92  		require.NotNil(t, err)
    93  		require.Contains(t, err.Error(), "not found")
    94  
    95  		// test <branch name>-<commit hash> version
    96  		// Exists: main-f5e6d75
    97  		require.NoError(t, kHandler.ValidateKymaVersion("main-f5e6d75"))
    98  
    99  		err = kHandler.ValidateKymaVersion("main-123456")
   100  		require.NotNil(t, err)
   101  		require.Contains(t, err.Error(), "not present on branch")
   102  
   103  		err = kHandler.ValidateKymaVersion("release-0.4-f5e6d75")
   104  		require.NotNil(t, err)
   105  		require.Contains(t, err.Error(), "not present on branch")
   106  	})
   107  }
   108  
   109  func fixKymaHandler(t *testing.T) *kymaHandler {
   110  	db := storage.NewMemoryStorage()
   111  	logs := logrus.New()
   112  	q := process.NewQueue(&testExecutor{}, logs)
   113  	kHandler := NewKymaHandler(db.Orchestrations(), q, logs)
   114  
   115  	// fix github client
   116  	mockServer := fixGithubServer(t)
   117  	baseUrl, _ := url.Parse(fmt.Sprintf("%s/", mockServer.URL))
   118  	kHandler.gitClient.BaseURL = baseUrl
   119  
   120  	return kHandler
   121  }
   122  
   123  func fixGithubServer(t *testing.T) *httptest.Server {
   124  	r := mux.NewRouter()
   125  
   126  	// initialize Git data
   127  	mock := mockServer{
   128  		T: t,
   129  		tags: map[string]bool{
   130  			"1.18.0": true,
   131  		},
   132  		pulls: map[int64]bool{
   133  			10542: true,
   134  		},
   135  		branchCommit: map[string]map[string]bool{
   136  			"main": map[string]bool{
   137  				"f5e6d75": true,
   138  			},
   139  		},
   140  	}
   141  
   142  	// set routes
   143  	r.HandleFunc(fmt.Sprintf("/repos/%s/%s/releases/tags/{tag}",
   144  		internal.GitKymaProject, internal.GitKymaRepo), mock.getTags).Methods(http.MethodGet)
   145  	r.HandleFunc(fmt.Sprintf("/repos/%s/%s/pulls/{pullId}",
   146  		internal.GitKymaProject, internal.GitKymaRepo), mock.getPulls).Methods(http.MethodGet)
   147  	r.HandleFunc(fmt.Sprintf("/repos/%v/%v/compare/{base}...{commit}",
   148  		internal.GitKymaProject, internal.GitKymaRepo), mock.getDiff).Methods(http.MethodGet)
   149  
   150  	return httptest.NewServer(r)
   151  }
   152  
   153  type mockServer struct {
   154  	T            *testing.T
   155  	tags         map[string]bool
   156  	pulls        map[int64]bool
   157  	branchCommit map[string]map[string]bool
   158  }
   159  
   160  func (s *mockServer) getTags(w http.ResponseWriter, r *http.Request) {
   161  	vars := mux.Vars(r)
   162  
   163  	tag := vars["tag"]
   164  	response := github.RepositoryRelease{}
   165  
   166  	// check if tag exists
   167  	_, exists := s.tags[tag]
   168  	if !exists {
   169  		w.WriteHeader(http.StatusNotFound)
   170  	} else {
   171  		response = github.RepositoryRelease{TagName: &tag}
   172  	}
   173  
   174  	responseObjAsBytes, _ := json.Marshal(response)
   175  	_, err := w.Write(responseObjAsBytes)
   176  	assert.NoError(s.T, err)
   177  }
   178  
   179  func (s *mockServer) getPulls(w http.ResponseWriter, r *http.Request) {
   180  	vars := mux.Vars(r)
   181  
   182  	pullId, _ := strconv.ParseInt(vars["pullId"], 10, 64)
   183  	response := github.PullRequest{}
   184  
   185  	// check if pull exists
   186  	_, exists := s.pulls[pullId]
   187  	if !exists {
   188  		w.WriteHeader(http.StatusNotFound)
   189  	} else {
   190  		response = github.PullRequest{ID: &pullId}
   191  	}
   192  
   193  	responseObjAsBytes, _ := json.Marshal(response)
   194  	_, err := w.Write(responseObjAsBytes)
   195  	assert.NoError(s.T, err)
   196  }
   197  
   198  func (s *mockServer) getDiff(w http.ResponseWriter, r *http.Request) {
   199  	vars := mux.Vars(r)
   200  
   201  	response := github.CommitsComparison{}
   202  
   203  	// check if branch exists
   204  	branch, commit := vars["base"], vars["commit"]
   205  	branchCommits, exists := s.branchCommit[branch]
   206  	if !exists {
   207  		w.WriteHeader(http.StatusNotFound)
   208  	}
   209  
   210  	// check if commit exists
   211  	_, exists = branchCommits[commit]
   212  	if !exists {
   213  		response.Commits = []github.RepositoryCommit{
   214  			{SHA: &commit},
   215  		}
   216  	}
   217  
   218  	responseObjAsBytes, _ := json.Marshal(response)
   219  	_, err := w.Write(responseObjAsBytes)
   220  	assert.NoError(s.T, err)
   221  }
   222  
   223  type testExecutor struct{}
   224  
   225  func (t *testExecutor) Execute(opID string) (time.Duration, error) {
   226  	return 0, nil
   227  }