github.com/jfrog/jfrog-cli-core/v2@v2.51.0/artifactory/commands/transferfiles/status_test.go (about)

     1  package transferfiles
     2  
     3  import (
     4  	"bytes"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/jfrog/build-info-go/utils"
     9  	"github.com/jfrog/jfrog-cli-core/v2/artifactory/commands/transferfiles/api"
    10  	"github.com/jfrog/jfrog-cli-core/v2/artifactory/commands/transferfiles/state"
    11  	"github.com/jfrog/jfrog-cli-core/v2/utils/coreutils"
    12  	"github.com/jfrog/jfrog-cli-core/v2/utils/tests"
    13  	"github.com/jfrog/jfrog-client-go/utils/log"
    14  	"github.com/stretchr/testify/assert"
    15  )
    16  
    17  const (
    18  	repo1Key = "repo1"
    19  	repo2Key = "repo2"
    20  )
    21  
    22  func initStatusTest(t *testing.T) (*bytes.Buffer, func()) {
    23  	cleanUpJfrogHome, err := tests.SetJfrogHome()
    24  	assert.NoError(t, err)
    25  
    26  	// Create transfer directory
    27  	transferDir, err := coreutils.GetJfrogTransferDir()
    28  	assert.NoError(t, err)
    29  	err = utils.CreateDirIfNotExist(transferDir)
    30  	assert.NoError(t, err)
    31  
    32  	// Redirect log to buffer
    33  	buffer, _, previousLog := tests.RedirectLogOutputToBuffer()
    34  
    35  	undoSaveInterval := state.SetAutoSaveState()
    36  	return buffer, func() {
    37  		undoSaveInterval()
    38  		log.SetLogger(previousLog)
    39  		cleanUpJfrogHome()
    40  	}
    41  }
    42  
    43  func TestShowStatusNotRunning(t *testing.T) {
    44  	buffer, cleanUp := initStatusTest(t)
    45  	defer cleanUp()
    46  
    47  	// Run show status and check output
    48  	assert.NoError(t, ShowStatus())
    49  	assert.Contains(t, buffer.String(), "Status: Not running")
    50  }
    51  
    52  func TestShowStatus(t *testing.T) {
    53  	buffer, cleanUp := initStatusTest(t)
    54  	defer cleanUp()
    55  
    56  	// Create state manager and persist to file system
    57  	createStateManager(t, api.Phase1, false, false)
    58  
    59  	// Run show status and check output
    60  	assert.NoError(t, ShowStatus())
    61  	results := buffer.String()
    62  
    63  	// Check overall status
    64  	assert.Contains(t, results, "Overall Transfer Status")
    65  	assert.Contains(t, results, "Status:\t\t\tRunning")
    66  	assert.Contains(t, results, "Running for:\t\t\tLess than a minute")
    67  	assert.Contains(t, results, "Storage:			4.9 KiB / 10.9 KiB (45.0%)")
    68  	assert.Contains(t, results, "Repositories:		15 / 1111 (1.4%)")
    69  	assert.Contains(t, results, "Working threads:		16")
    70  	assert.Contains(t, results, "Transfer speed:		0.011 MB/s")
    71  	assert.Contains(t, results, "Estimated time remaining:	Not available yet")
    72  	assert.Contains(t, results, "Transfer failures:		223 (In Phase 3 and in subsequent executions, we'll retry transferring the failed files)")
    73  
    74  	// Check repository status
    75  	assert.Contains(t, results, "Current Repository Status")
    76  	assert.Contains(t, results, "Name:			repo1")
    77  	assert.Contains(t, results, "Phase:			Transferring all files in the repository (1/3)")
    78  	assert.Contains(t, results, "Visited folders:		15")
    79  	assert.Contains(t, results, "Delayed files:		20 (Files to be transferred last, after all other files)")
    80  	assert.Contains(t, results, "Storage:			4.9 KiB / 9.8 KiB (50.0%)")
    81  	assert.Contains(t, results, "Files:			500 / 10000 (5.0%)")
    82  }
    83  
    84  func TestShowStatusDiffPhase(t *testing.T) {
    85  	buffer, cleanUp := initStatusTest(t)
    86  	defer cleanUp()
    87  
    88  	// Create state manager and persist to file system
    89  	createStateManager(t, api.Phase2, false, false)
    90  
    91  	// Run show status and check output
    92  	assert.NoError(t, ShowStatus())
    93  	results := buffer.String()
    94  
    95  	// Check overall status
    96  	assert.Contains(t, results, "Overall Transfer Status")
    97  	assert.Contains(t, results, "Status:\t\t\tRunning")
    98  	assert.Contains(t, results, "Running for:		")
    99  	assert.Contains(t, results, "Storage:			4.9 KiB / 10.9 KiB (45.0%)")
   100  	assert.Contains(t, results, "Repositories:		15 / 1111 (1.4%)")
   101  	assert.Contains(t, results, "Working threads:		16")
   102  	assert.Contains(t, results, "Transfer speed:		0.011 MB/s")
   103  	assert.Contains(t, results, "Estimated time remaining:	Not available yet")
   104  	assert.Contains(t, results, "Transfer failures:		223 (In Phase 3 and in subsequent executions, we'll retry transferring the failed files)")
   105  
   106  	// Check repository status
   107  	assert.Contains(t, results, "Current Repository Status")
   108  	assert.Contains(t, results, "Name:			repo1")
   109  	assert.Contains(t, results, "Phase:			Transferring newly created and modified files (2/3)")
   110  	assert.Contains(t, results, "Delayed files:		20 (Files to be transferred last, after all other files)")
   111  	assert.NotContains(t, results, "Visited folders")
   112  	assert.NotContains(t, results, "Storage:			4.9 KiB / 9.8 KiB (50.0%)")
   113  	assert.NotContains(t, results, "Files:			500 / 10000 (5.0%)")
   114  }
   115  
   116  func TestShowBuildInfoRepo(t *testing.T) {
   117  	buffer, cleanUp := initStatusTest(t)
   118  	defer cleanUp()
   119  
   120  	// Create state manager and persist to file system
   121  	createStateManager(t, api.Phase3, true, false)
   122  
   123  	// Run show status and check output
   124  	assert.NoError(t, ShowStatus())
   125  	results := buffer.String()
   126  
   127  	// Check overall status
   128  	assert.Contains(t, results, "Overall Transfer Status")
   129  	assert.Contains(t, results, "Status:\t\t\tRunning")
   130  	assert.Contains(t, results, "Running for:		")
   131  	assert.Contains(t, results, "Storage:			4.9 KiB / 10.9 KiB (45.0%)")
   132  	assert.Contains(t, results, "Repositories:		15 / 1111 (1.4%)")
   133  	assert.Contains(t, results, "Working threads:		16")
   134  	assert.Contains(t, results, "Transfer speed:		0.011 MB/s")
   135  	assert.Contains(t, results, "Estimated time remaining:	Not available yet")
   136  	assert.Contains(t, results, "Transfer failures:		223")
   137  
   138  	// Check repository status
   139  	assert.Contains(t, results, "Current Repository Status")
   140  	assert.Contains(t, results, "Name:			repo1")
   141  	assert.Contains(t, results, "Phase:			Retrying transfer failures and transfer delayed files (3/3)")
   142  	assert.Contains(t, results, "Delayed files:		20 (Files to be transferred last, after all other files)")
   143  	assert.Contains(t, results, "Storage:			4.9 KiB / 9.8 KiB (50.0%)")
   144  	assert.Contains(t, results, "Files:			500 / 10000 (5.0%)")
   145  	assert.NotContains(t, results, "Visited folders")
   146  }
   147  
   148  func TestShowStaleChunks(t *testing.T) {
   149  	buffer, cleanUp := initStatusTest(t)
   150  	defer cleanUp()
   151  
   152  	// Create state manager and persist to file system
   153  	createStateManager(t, api.Phase1, false, true)
   154  
   155  	// Run show status and check output
   156  	assert.NoError(t, ShowStatus())
   157  	results := buffer.String()
   158  
   159  	// Check stale chunks
   160  	assert.Contains(t, results, "File Chunks in Transit for More than 30 Minutes")
   161  	assert.Contains(t, results, "Node ID:\tnode-id-1")
   162  	assert.Contains(t, results, "Sent:\t")
   163  	assert.Contains(t, results, "(31 minutes)")
   164  	assert.Contains(t, results, "a/b/c")
   165  	assert.Contains(t, results, "d/e/f")
   166  }
   167  
   168  // Create state manager and persist in the file system.
   169  // t     - The testing object
   170  // phase - Phase ID
   171  func createStateManager(t *testing.T, phase int, buildInfoRepo bool, staleChunks bool) {
   172  	stateManager, err := state.NewTransferStateManager(false)
   173  	assert.NoError(t, err)
   174  	assert.NoError(t, stateManager.TryLockTransferStateManager())
   175  	assert.NoError(t, stateManager.SetRepoState(repo1Key, 10000, 10000, buildInfoRepo, false))
   176  
   177  	stateManager.CurrentRepoKey = repo1Key
   178  	stateManager.CurrentRepoPhase = phase
   179  	stateManager.OverallTransfer.TotalSizeBytes = 11111
   180  	stateManager.TotalRepositories.TotalUnits = 1111
   181  	stateManager.TotalRepositories.TransferredUnits = 15
   182  	stateManager.CurrentTotalTransferredBytes = 15
   183  	stateManager.WorkingThreads = 16
   184  	stateManager.VisitedFolders = 15
   185  	stateManager.DelayedFiles = 20
   186  	stateManager.TransferFailures = 223
   187  
   188  	stateManager.LastSpeeds = []float64{12}
   189  	stateManager.LastSpeedsSum = 12
   190  	stateManager.SpeedsAverage = 12
   191  
   192  	if staleChunks {
   193  		stateManager.StaleChunks = append(stateManager.StaleChunks, state.StaleChunks{
   194  			NodeID: staleChunksNodeIdOne,
   195  			Chunks: []state.StaleChunk{
   196  				{
   197  					ChunkID: staleChunksChunkId,
   198  					Sent:    time.Now().Add(-time.Minute * 31).Unix(),
   199  					Files:   []string{"a/b/c", "d/e/f"},
   200  				},
   201  			},
   202  		})
   203  	}
   204  
   205  	// Increment transferred size and files. This action also persists the run status.
   206  	assert.NoError(t, stateManager.IncTransferredSizeAndFilesPhase1(500, 5000))
   207  
   208  	// Save transfer state.
   209  	assert.NoError(t, stateManager.SaveStateAndSnapshots())
   210  }
   211  
   212  func TestSizeToString(t *testing.T) {
   213  	testCases := []struct {
   214  		sizeInBytes int64
   215  		expected    string
   216  	}{
   217  		{0, "0.0 KiB"},
   218  		{10, "0.0 KiB"},
   219  		{100, "0.1 KiB"},
   220  		{1000, "1.0 KiB"},
   221  		{1024, "1.0 KiB"},
   222  		{1025, "1.0 KiB"},
   223  		{4000, "3.9 KiB"},
   224  		{4096, "4.0 KiB"},
   225  		{1000000, "976.6 KiB"},
   226  		{1048576, "1.0 MiB"},
   227  		{1073741824, "1.0 GiB"},
   228  		{1073741824, "1.0 GiB"},
   229  		{1099511627776, "1.0 TiB"},
   230  		{1125899906842624, "1.0 PiB"},
   231  		{1125899906842624, "1.0 PiB"},
   232  		{1.152921504606847e18, "1.0 EiB"},
   233  	}
   234  	for _, testCase := range testCases {
   235  		assert.Equal(t, sizeToString(testCase.sizeInBytes), testCase.expected)
   236  	}
   237  }