|
1 | 1 | package transferfiles |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "context" |
| 5 | + "encoding/json" |
| 6 | + "net/http" |
4 | 7 | "testing" |
5 | 8 |
|
6 | 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 | + commonTests "github.com/jfrog/jfrog-cli-core/v2/common/tests" |
7 | 12 | servicesUtils "github.com/jfrog/jfrog-client-go/artifactory/services/utils" |
8 | 13 | "github.com/stretchr/testify/assert" |
9 | 14 | ) |
@@ -72,3 +77,171 @@ func TestGenerateDockerManifestAqlQuery(t *testing.T) { |
72 | 77 | }) |
73 | 78 | } |
74 | 79 | } |
| 80 | + |
| 81 | +// TestGetNonDockerTimeFrameFilesDiffWithPatterns tests that getNonDockerTimeFrameFilesDiff uses pattern filtering when patterns are set |
| 82 | +func TestGetNonDockerTimeFrameFilesDiffWithPatterns(t *testing.T) { |
| 83 | + stateManager, cleanUp := state.InitStateTest(t) |
| 84 | + defer cleanUp() |
| 85 | + |
| 86 | + aqlCalled := false |
| 87 | + receivedQuery := "" |
| 88 | + |
| 89 | + mockAqlResults := servicesUtils.AqlSearchResult{ |
| 90 | + Results: []servicesUtils.ResultItem{ |
| 91 | + {Repo: "test-repo", Path: "org/company/projectA", Name: "file1.jar", Size: 100, Type: "file"}, |
| 92 | + }, |
| 93 | + } |
| 94 | + |
| 95 | + testServer, serverDetails, _ := commonTests.CreateRtRestsMockServer(t, func(w http.ResponseWriter, r *http.Request) { |
| 96 | + if r.RequestURI == "/api/search/aql" { |
| 97 | + aqlCalled = true |
| 98 | + // Read the query body |
| 99 | + buf := make([]byte, 1024) |
| 100 | + n, _ := r.Body.Read(buf) |
| 101 | + receivedQuery = string(buf[:n]) |
| 102 | + |
| 103 | + w.WriteHeader(http.StatusOK) |
| 104 | + response, _ := json.Marshal(mockAqlResults) |
| 105 | + _, _ = w.Write(response) |
| 106 | + } |
| 107 | + }) |
| 108 | + defer testServer.Close() |
| 109 | + |
| 110 | + assert.NoError(t, stateManager.SetRepoState("test-repo", 0, 0, false, true)) |
| 111 | + |
| 112 | + phase := &filesDiffPhase{ |
| 113 | + phaseBase: phaseBase{ |
| 114 | + context: context.Background(), |
| 115 | + stateManager: stateManager, |
| 116 | + repoKey: "test-repo", |
| 117 | + srcRtDetails: serverDetails, |
| 118 | + includeFilesPatterns: []string{"org/company/*"}, |
| 119 | + }, |
| 120 | + } |
| 121 | + |
| 122 | + // Call getNonDockerTimeFrameFilesDiff with patterns |
| 123 | + result, err := phase.getNonDockerTimeFrameFilesDiff("2024-01-01T00:00:00Z", "2024-01-02T00:00:00Z", 0) |
| 124 | + assert.NoError(t, err) |
| 125 | + assert.True(t, aqlCalled, "AQL should be called") |
| 126 | + assert.Len(t, result.Results, 1) |
| 127 | + |
| 128 | + // Verify the query contains pattern filtering |
| 129 | + assert.Contains(t, receivedQuery, "$or", "Query should contain pattern $or condition") |
| 130 | + assert.Contains(t, receivedQuery, "org/company", "Query should contain the pattern") |
| 131 | +} |
| 132 | + |
| 133 | +// TestGetNonDockerTimeFrameFilesDiffWithoutPatterns tests that getNonDockerTimeFrameFilesDiff uses default query when no patterns |
| 134 | +func TestGetNonDockerTimeFrameFilesDiffWithoutPatterns(t *testing.T) { |
| 135 | + stateManager, cleanUp := state.InitStateTest(t) |
| 136 | + defer cleanUp() |
| 137 | + |
| 138 | + aqlCalled := false |
| 139 | + receivedQuery := "" |
| 140 | + |
| 141 | + mockAqlResults := servicesUtils.AqlSearchResult{ |
| 142 | + Results: []servicesUtils.ResultItem{ |
| 143 | + {Repo: "test-repo", Path: "any/path", Name: "file1.jar", Size: 100, Type: "file"}, |
| 144 | + }, |
| 145 | + } |
| 146 | + |
| 147 | + testServer, serverDetails, _ := commonTests.CreateRtRestsMockServer(t, func(w http.ResponseWriter, r *http.Request) { |
| 148 | + if r.RequestURI == "/api/search/aql" { |
| 149 | + aqlCalled = true |
| 150 | + buf := make([]byte, 1024) |
| 151 | + n, _ := r.Body.Read(buf) |
| 152 | + receivedQuery = string(buf[:n]) |
| 153 | + |
| 154 | + w.WriteHeader(http.StatusOK) |
| 155 | + response, _ := json.Marshal(mockAqlResults) |
| 156 | + _, _ = w.Write(response) |
| 157 | + } |
| 158 | + }) |
| 159 | + defer testServer.Close() |
| 160 | + |
| 161 | + assert.NoError(t, stateManager.SetRepoState("test-repo", 0, 0, false, true)) |
| 162 | + |
| 163 | + phase := &filesDiffPhase{ |
| 164 | + phaseBase: phaseBase{ |
| 165 | + context: context.Background(), |
| 166 | + stateManager: stateManager, |
| 167 | + repoKey: "test-repo", |
| 168 | + srcRtDetails: serverDetails, |
| 169 | + includeFilesPatterns: []string{}, // No patterns |
| 170 | + }, |
| 171 | + } |
| 172 | + |
| 173 | + // Call getNonDockerTimeFrameFilesDiff without patterns |
| 174 | + result, err := phase.getNonDockerTimeFrameFilesDiff("2024-01-01T00:00:00Z", "2024-01-02T00:00:00Z", 0) |
| 175 | + assert.NoError(t, err) |
| 176 | + assert.True(t, aqlCalled, "AQL should be called") |
| 177 | + assert.Len(t, result.Results, 1) |
| 178 | + |
| 179 | + // Verify the query does NOT contain pattern filtering $or |
| 180 | + assert.NotContains(t, receivedQuery, `"$or":[{"path"`, "Query should not contain pattern $or condition when no patterns set") |
| 181 | +} |
| 182 | + |
| 183 | +// TestGetDockerTimeFrameFilesDiffWithPatterns tests that getDockerTimeFrameFilesDiff uses pattern filtering when patterns are set |
| 184 | +func TestGetDockerTimeFrameFilesDiffWithPatterns(t *testing.T) { |
| 185 | + stateManager, cleanUp := state.InitStateTest(t) |
| 186 | + defer cleanUp() |
| 187 | + |
| 188 | + aqlCallCount := 0 |
| 189 | + firstQuery := "" |
| 190 | + |
| 191 | + // First call returns manifest files, second call returns dir content |
| 192 | + testServer, serverDetails, _ := commonTests.CreateRtRestsMockServer(t, func(w http.ResponseWriter, r *http.Request) { |
| 193 | + if r.RequestURI == "/api/search/aql" { |
| 194 | + aqlCallCount++ |
| 195 | + buf := make([]byte, 2048) |
| 196 | + n, _ := r.Body.Read(buf) |
| 197 | + query := string(buf[:n]) |
| 198 | + |
| 199 | + if aqlCallCount == 1 { |
| 200 | + // First query - capture for assertion |
| 201 | + firstQuery = query |
| 202 | + // Return manifest file |
| 203 | + mockAqlResults := servicesUtils.AqlSearchResult{ |
| 204 | + Results: []servicesUtils.ResultItem{ |
| 205 | + {Repo: "docker-repo", Path: "myapp/1.0", Name: "manifest.json", Size: 100, Type: "file"}, |
| 206 | + }, |
| 207 | + } |
| 208 | + w.WriteHeader(http.StatusOK) |
| 209 | + response, _ := json.Marshal(mockAqlResults) |
| 210 | + _, _ = w.Write(response) |
| 211 | + } else { |
| 212 | + // Second query - return dir content |
| 213 | + mockAqlResults := servicesUtils.AqlSearchResult{ |
| 214 | + Results: []servicesUtils.ResultItem{ |
| 215 | + {Repo: "docker-repo", Path: "myapp/1.0", Name: "layer1.tar", Size: 1000, Type: "file"}, |
| 216 | + }, |
| 217 | + } |
| 218 | + w.WriteHeader(http.StatusOK) |
| 219 | + response, _ := json.Marshal(mockAqlResults) |
| 220 | + _, _ = w.Write(response) |
| 221 | + } |
| 222 | + } |
| 223 | + }) |
| 224 | + defer testServer.Close() |
| 225 | + |
| 226 | + assert.NoError(t, stateManager.SetRepoState("docker-repo", 0, 0, false, true)) |
| 227 | + |
| 228 | + phase := &filesDiffPhase{ |
| 229 | + phaseBase: phaseBase{ |
| 230 | + context: context.Background(), |
| 231 | + stateManager: stateManager, |
| 232 | + repoKey: "docker-repo", |
| 233 | + srcRtDetails: serverDetails, |
| 234 | + includeFilesPatterns: []string{"myapp/*"}, |
| 235 | + }, |
| 236 | + } |
| 237 | + |
| 238 | + // Call getDockerTimeFrameFilesDiff with patterns |
| 239 | + result, err := phase.getDockerTimeFrameFilesDiff("2024-01-01T00:00:00Z", "2024-01-02T00:00:00Z", 0) |
| 240 | + assert.NoError(t, err) |
| 241 | + assert.Equal(t, 2, aqlCallCount, "Two AQL calls should be made (manifest + dir content)") |
| 242 | + assert.Len(t, result.Results, 1) |
| 243 | + |
| 244 | + // Verify the FIRST query contains pattern filtering and docker manifest names |
| 245 | + assert.Contains(t, firstQuery, "myapp", "First query should contain the pattern") |
| 246 | + assert.Contains(t, firstQuery, "manifest.json", "First query should contain manifest.json") |
| 247 | +} |
0 commit comments