github.com/jfrog/jfrog-cli-core/v2@v2.52.0/artifactory/utils/storageinfo_test.go (about)

     1  package utils
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"net/http"
     7  	"net/http/httptest"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/jfrog/jfrog-cli-core/v2/utils/config"
    12  	clientUtils "github.com/jfrog/jfrog-client-go/artifactory/services/utils"
    13  	"github.com/stretchr/testify/assert"
    14  )
    15  
    16  func TestCalculateStorageInfo(t *testing.T) {
    17  	calculated := false
    18  	// Prepare mock server
    19  	testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    20  		if r.RequestURI == "/api/storageinfo/calculate" {
    21  			// Response for CalculateStorageInfo
    22  			w.WriteHeader(http.StatusAccepted)
    23  			calculated = true
    24  		}
    25  	}))
    26  	defer testServer.Close()
    27  
    28  	// Create storage info manager
    29  	storageInfoManager, err := NewStorageInfoManager(context.Background(), &config.ServerDetails{ArtifactoryUrl: testServer.URL + "/"})
    30  	assert.NoError(t, err)
    31  
    32  	// Calculate and assert storage info
    33  	assert.NoError(t, storageInfoManager.CalculateStorageInfo())
    34  	assert.True(t, calculated)
    35  }
    36  
    37  func TestGetStorageInfo(t *testing.T) {
    38  	// Prepare mock server
    39  	testServer, storageInfoManager := mockGetStorageInfoAndInitManager(t, []clientUtils.RepositorySummary{{RepoKey: "repo-1"}})
    40  	defer testServer.Close()
    41  
    42  	// Get and assert storage info
    43  	storageInfo, err := storageInfoManager.GetStorageInfo()
    44  	assert.NoError(t, err)
    45  	assert.NotNil(t, storageInfo)
    46  	assert.Equal(t, "repo-1", storageInfo.RepositoriesSummaryList[0].RepoKey)
    47  }
    48  
    49  func TestGetSourceRepoSummary(t *testing.T) {
    50  	// Prepare mock server
    51  	testServer, storageInfoManager := mockGetStorageInfoAndInitManager(t, []clientUtils.RepositorySummary{{RepoKey: "repo-1"}, {RepoKey: "repo-2"}})
    52  	defer testServer.Close()
    53  
    54  	// Get repo summary of repo-1
    55  	repoSummary, err := storageInfoManager.GetRepoSummary("repo-1")
    56  	assert.NoError(t, err)
    57  	assert.Equal(t, "repo-1", repoSummary.RepoKey)
    58  
    59  	// Get repo summary of non-existed repo
    60  	_, err = storageInfoManager.GetRepoSummary("not-existed")
    61  	assert.ErrorContains(t, err, "could not find repository 'not-existed' in the repositories summary")
    62  }
    63  
    64  func TestConvertStorageSizeStringToBytes(t *testing.T) {
    65  	convertStorageSizeStringToBytesCases := []struct {
    66  		name                         string
    67  		size                         string
    68  		errorExpected                bool
    69  		expectedSizeBeforeConversion float64
    70  	}{
    71  		{"bytes", "2.22 bytes", false, 2.22},
    72  		{"KB", "3.333 KB", false, 3.333 * float64(clientUtils.SizeKib)},
    73  		{"KB with comma", "1,004.64 KB", false, 1004.64 * float64(clientUtils.SizeKib)},
    74  		{"MB", "4.4444 MB", false, 4.4444 * float64(clientUtils.SizeMiB)},
    75  		{"GB", "5.55555 GB", false, 5.55555 * float64(clientUtils.SizeGiB)},
    76  		{"TB", "6.666666 TB", false, 6.666666 * float64(clientUtils.SizeTiB)},
    77  		{"int", "7 KB", false, 7 * float64(clientUtils.SizeKib)},
    78  		{"size missing", "8", true, -1},
    79  		{"unexpected size", "8 kb", true, -1},
    80  		{"too many separators", "8 K B", true, -1},
    81  	}
    82  	for _, testCase := range convertStorageSizeStringToBytesCases {
    83  		t.Run(testCase.name, func(t *testing.T) {
    84  			assertConvertedStorageSize(t, testCase.size, testCase.errorExpected, testCase.expectedSizeBeforeConversion)
    85  		})
    86  	}
    87  }
    88  
    89  func assertConvertedStorageSize(t *testing.T, size string, errorExpected bool, expectedSizeBeforeConversion float64) {
    90  	converted, err := convertStorageSizeStringToBytes(size)
    91  	if errorExpected {
    92  		assert.Error(t, err)
    93  		return
    94  	}
    95  	assert.NoError(t, err)
    96  	assert.Equal(t, int64(expectedSizeBeforeConversion), converted)
    97  }
    98  
    99  func TestGetReposTotalSize(t *testing.T) {
   100  	getRepoSummaryPollingInterval = 10 * time.Millisecond
   101  	getRepoSummaryPollingTimeout = 30 * time.Millisecond
   102  
   103  	repositoriesSummaryList := []clientUtils.RepositorySummary{
   104  		{RepoKey: "repo-1", UsedSpaceInBytes: "12345", FilesCount: "3"},
   105  		{RepoKey: "repo-2", UsedSpace: "678 bytes", FilesCount: "4"},
   106  	}
   107  	// Prepare mock server.
   108  	firstRequest := true
   109  	testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   110  		// In order to test the polling, on the first request we return only one repo, and on the second both of them.
   111  		// If the polling does not work properly, we should see a wrong total returned.
   112  		if firstRequest {
   113  			firstRequest = false
   114  			getStorageInfoResponse(t, w, r, repositoriesSummaryList[0:1])
   115  		} else {
   116  			getStorageInfoResponse(t, w, r, repositoriesSummaryList)
   117  		}
   118  	}))
   119  	defer testServer.Close()
   120  
   121  	// Create storage info manager
   122  	storageInfoManager, err := NewStorageInfoManager(context.Background(), &config.ServerDetails{ArtifactoryUrl: testServer.URL + "/"})
   123  	assert.NoError(t, err)
   124  
   125  	// Get the total size of the two repos.
   126  	totalSize, totalFiles, err := storageInfoManager.GetReposTotalSizeAndFiles("repo-1", "repo-2")
   127  	assert.NoError(t, err)
   128  	assert.Equal(t, int64(13023), totalSize)
   129  	assert.Equal(t, int64(7), totalFiles)
   130  
   131  	// Assert error is returned due to the missing repository.
   132  	_, _, err = storageInfoManager.GetReposTotalSizeAndFiles("repo-1", "repo-2", "repo-3")
   133  	assert.EqualError(t, err, storageInfoRepoMissingError)
   134  }
   135  
   136  func mockGetStorageInfoAndInitManager(t *testing.T, repositoriesSummaryList []clientUtils.RepositorySummary) (*httptest.Server, *StorageInfoManager) {
   137  	getRepoSummaryPollingInterval = 10 * time.Millisecond
   138  	getRepoSummaryPollingTimeout = 30 * time.Millisecond
   139  
   140  	// Prepare mock server
   141  	testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   142  		getStorageInfoResponse(t, w, r, repositoriesSummaryList)
   143  	}))
   144  
   145  	// Create storage info manager
   146  	storageInfoManager, err := NewStorageInfoManager(context.Background(), &config.ServerDetails{ArtifactoryUrl: testServer.URL + "/"})
   147  	assert.NoError(t, err)
   148  	return testServer, storageInfoManager
   149  }
   150  
   151  func getStorageInfoResponse(t *testing.T, w http.ResponseWriter, r *http.Request, repositoriesSummaryList []clientUtils.RepositorySummary) {
   152  	if r.RequestURI == "/api/storageinfo" {
   153  		// Response for CalculateStorageInfo
   154  		w.WriteHeader(http.StatusOK)
   155  		response := &clientUtils.StorageInfo{RepositoriesSummaryList: repositoriesSummaryList}
   156  		body, err := json.Marshal(response)
   157  		assert.NoError(t, err)
   158  		_, err = w.Write(body)
   159  		assert.NoError(t, err)
   160  	}
   161  }