github.com/jfrog/jfrog-cli-core/v2@v2.51.0/artifactory/commands/transferfiles/state/state_test.go (about) 1 package state 2 3 import ( 4 "testing" 5 "time" 6 7 "github.com/jfrog/jfrog-cli-core/v2/utils/reposnapshot" 8 "github.com/jfrog/jfrog-client-go/utils/io/fileutils" 9 "github.com/stretchr/testify/assert" 10 ) 11 12 func TestGetRepositoryState(t *testing.T) { 13 stateManager, cleanUp := InitStateTest(t) 14 defer cleanUp() 15 16 // Assert repo does not exist before it was created. 17 loadAndAssertRepo(t, repo1Key, false) 18 19 // Create new repos. 20 createAndAssertRepoState(t, stateManager, repo1Key) 21 createAndAssertRepoState(t, stateManager, repo2Key) 22 23 // Add data to current repo. 24 stateManager.CurrentRepo.FullTransfer.Started = "start" 25 stateManager.CurrentRepo.FullTransfer.Ended = "end" 26 assert.NoError(t, stateManager.persistTransferState(false)) 27 28 // Create new repo, and assert data on previous repo is loaded correctly. 29 createAndAssertRepoState(t, stateManager, repo3Key) 30 transferState := loadAndAssertRepo(t, repo2Key, true) 31 assert.Equal(t, "start", transferState.CurrentRepo.FullTransfer.Started) 32 assert.Equal(t, "end", transferState.CurrentRepo.FullTransfer.Ended) 33 } 34 35 func loadAndAssertRepo(t *testing.T, repoKey string, expectedToExist bool) *TransferState { 36 transferState, exists, err := LoadTransferState(repoKey, false) 37 assert.NoError(t, err) 38 assert.Equal(t, expectedToExist, exists) 39 if expectedToExist { 40 assert.Equal(t, repoKey, transferState.CurrentRepo.Name) 41 } 42 return &transferState 43 } 44 45 func createAndAssertRepoState(t *testing.T, stateManager *TransferStateManager, repoKey string) { 46 assert.NoError(t, stateManager.SetRepoState(repoKey, 0, 0, false, false)) 47 transferState := loadAndAssertRepo(t, repoKey, true) 48 assert.Empty(t, transferState.CurrentRepo.FullTransfer) 49 assert.Empty(t, transferState.CurrentRepo.Diffs) 50 } 51 52 func TestSaveAndLoadState(t *testing.T) { 53 stateManager, cleanUp := InitStateTest(t) 54 defer cleanUp() 55 stateManager.CurrentRepo = newRepositoryTransferState(repo4Key).CurrentRepo 56 57 assert.NoError(t, stateManager.persistTransferState(false)) 58 actualState, exists, err := LoadTransferState(repo4Key, false) 59 assert.NoError(t, err) 60 assert.True(t, exists) 61 assert.Equal(t, stateManager.TransferState, actualState) 62 63 // Persist the transfer state with a high version and assert loading yields an error. 64 stateManager.TransferState.Version = 1000 65 assert.NoError(t, stateManager.persistTransferState(false)) 66 _, _, err = LoadTransferState(repo4Key, false) 67 assert.ErrorContains(t, err, transferStateFileInvalidVersionErrorMsg) 68 } 69 70 func TestGetTransferStateAndSnapshotClean(t *testing.T) { 71 stateManager, cleanUp := InitStateTest(t) 72 defer cleanUp() 73 74 // Make the snapshot not auto save. 75 snapshotCleanUp := setAutoSaveSnapshot(1000) 76 defer snapshotCleanUp() 77 78 // Assert getting state before it was created returns clean state. 79 cleanTransferState, cleanRepoTransferSnapshot, err := getCleanStateAndSnapshot(repo1Key) 80 assert.NoError(t, err) 81 assertGetTransferStateAndSnapshot(t, false, cleanTransferState, cleanRepoTransferSnapshot, false) 82 83 // Create repo-state. 84 createAndAssertRepoState(t, stateManager, repo1Key) 85 // Assert getting clean state on reset. 86 assertGetTransferStateAndSnapshot(t, true, cleanTransferState, cleanRepoTransferSnapshot, false) 87 88 // Mark phase 1 as started. 89 assert.NoError(t, stateManager.SetRepoFullTransferStarted(time.Now())) 90 getRootAndAddSnapshotData(t, stateManager) 91 // Create only the snapshot file in snapshot dir (without repo state). Since the state file is missing in the snapshots dir the load should start clean. 92 assert.NoError(t, stateManager.repoTransferSnapshot.snapshotManager.PersistRepoSnapshot()) 93 snapshotPath, err := GetRepoSnapshotFilePath(repo1Key) 94 assert.NoError(t, err) 95 exists, err := fileutils.IsFileExists(snapshotPath, false) 96 assert.NoError(t, err) 97 assert.True(t, exists) 98 assertGetTransferStateAndSnapshot(t, false, cleanTransferState, cleanRepoTransferSnapshot, false) 99 } 100 101 // Set the snapshot's save-interval and return a cleanup function. 102 func setAutoSaveSnapshot(interval int) (cleanUp func()) { 103 previousSaveInterval := snapshotSaveIntervalMin 104 snapshotSaveIntervalMin = interval 105 return func() { 106 snapshotSaveIntervalMin = previousSaveInterval 107 } 108 } 109 110 // Testing two scenarios here: 111 // 1. loading (snapshot file and state) from existing snapshot 112 // 2. loading state of fully transferred repository (phase 1 completed) 113 func TestGetTransferStateAndSnapshotLoading(t *testing.T) { 114 stateManager, cleanUp := InitStateTest(t) 115 defer cleanUp() 116 117 // Create repo-state. 118 createAndAssertRepoState(t, stateManager, repo1Key) 119 120 // Add content to state and snapshot. 121 assert.NoError(t, stateManager.SetRepoFullTransferStarted(time.Now())) 122 assert.NoError(t, stateManager.IncTransferredSizeAndFilesPhase1(2, 3)) 123 _ = getRootAndAddSnapshotData(t, stateManager) 124 // Get state before saving. 125 originalState := stateManager.TransferState 126 assert.NoError(t, stateManager.SaveStateAndSnapshots()) 127 // Modify state again, and assert that the loaded state from snapshot was not modified and remained as saved. 128 assert.NoError(t, stateManager.IncTransferredSizeAndFilesPhase1(2, 3)) 129 assert.NotEqual(t, stateManager.TransferState.CurrentRepo, originalState.CurrentRepo) 130 assertGetTransferStateAndSnapshot(t, false, originalState, stateManager.repoTransferSnapshot, true) 131 132 // After repo fully transferred, expected to load state without snapshots. 133 assert.NoError(t, stateManager.SetRepoFullTransferCompleted()) 134 assertGetTransferStateAndSnapshot(t, false, stateManager.TransferState, nil, false) 135 } 136 137 func assertGetTransferStateAndSnapshot(t *testing.T, reset bool, expectedTransferState TransferState, 138 expectedRepoTransferSnapshot *RepoTransferSnapshot, expectedSnapshotLoaded bool) { 139 transferState, repoTransferSnapshot, err := getTransferStateAndSnapshot(repo1Key, reset) 140 assert.NoError(t, err) 141 assert.Equal(t, expectedTransferState.Version, transferState.Version) 142 assert.Equal(t, expectedTransferState.CurrentRepo, transferState.CurrentRepo) 143 144 // If one or both snapshots are nil, don't assert by field. 145 if expectedRepoTransferSnapshot == nil || repoTransferSnapshot == nil { 146 assert.Equal(t, expectedRepoTransferSnapshot, repoTransferSnapshot) 147 return 148 } 149 assert.Equal(t, expectedSnapshotLoaded, repoTransferSnapshot.loadedFromSnapshot) 150 } 151 152 func getRootAndAddSnapshotData(t *testing.T, stateManager *TransferStateManager) (root *reposnapshot.Node) { 153 root, err := stateManager.LookUpNode(".") 154 assert.NoError(t, err) 155 assert.NoError(t, root.IncrementFilesCount(10)) 156 assert.NoError(t, root.AddChildNode("child", nil)) 157 return 158 }