@@ -265,4 +265,136 @@ public void CurrentVersionMatchAlsoSetsSpeculative()
265265 result . Current . Should ( ) . Be ( ContentSource . Current ) ;
266266 result . Speculative . Should ( ) . BeTrue ( ) ;
267267 }
268+
269+ [ Theory ]
270+ [ InlineData ( "9.0" , "9.0.0" ) ] // Matches anchored product version
271+ [ InlineData ( "9.1" , "9.0.0" ) ] // Greater than anchored product version
272+ [ InlineData ( "9.5" , "9.0.0" ) ] // Much greater than anchored product version
273+ public void VersionBranchSpeculativeBuildWhenGreaterThanOrEqualToAnchoredProductVersion ( string branch , string productVersion )
274+ {
275+ var repositories = new Dictionary < string , Repository >
276+ {
277+ [ "test-repo" ] = CreateRepository ( current : "main" , next : "main" , edge : "main" )
278+ } ;
279+ var config = CreateConfiguration ( repositories ) ;
280+ var versionParts = productVersion . Split ( '.' ) ;
281+ var product = CreateProduct ( new SemVersion ( int . Parse ( versionParts [ 0 ] , null ) , int . Parse ( versionParts [ 1 ] , null ) , int . Parse ( versionParts [ 2 ] , null ) ) ) ;
282+
283+ var result = config . Match ( LoggerFactory , "elastic/test-repo" , branch , product ) ;
284+
285+ result . Speculative . Should ( ) . BeTrue ( ) ;
286+ }
287+
288+ [ Theory ]
289+ [ InlineData ( "8.15" , "9.0.0" ) ] // Less than anchored product version
290+ [ InlineData ( "7.17" , "9.0.0" ) ] // Much less than anchored product version
291+ [ InlineData ( "8.0" , "9.1.5" ) ] // Less than anchored product version with patch
292+ public void VersionBranchNoSpeculativeBuildWhenLessThanAnchoredProductVersionAndNotPreviousMinor ( string branch , string productVersion )
293+ {
294+ var repositories = new Dictionary < string , Repository >
295+ {
296+ [ "test-repo" ] = CreateRepository ( current : "main" , next : "main" , edge : "main" )
297+ } ;
298+ var config = CreateConfiguration ( repositories ) ;
299+ var versionParts = productVersion . Split ( '.' ) ;
300+ var product = CreateProduct ( new SemVersion ( int . Parse ( versionParts [ 0 ] , null ) , int . Parse ( versionParts [ 1 ] , null ) , int . Parse ( versionParts [ 2 ] , null ) ) ) ;
301+
302+ var result = config . Match ( LoggerFactory , "elastic/test-repo" , branch , product ) ;
303+
304+ result . Speculative . Should ( ) . BeFalse ( ) ;
305+ }
306+
307+ [ Theory ]
308+ [ InlineData ( "9.1" , "9.2.0" ) ] // Previous minor version
309+ [ InlineData ( "8.14" , "8.15.1" ) ] // Previous minor version with patch
310+ [ InlineData ( "10.0" , "10.1.0" ) ] // Previous minor version at major boundary
311+ public void VersionBranchSpeculativeBuildWhenMatchesPreviousMinorVersion ( string branch , string productVersion )
312+ {
313+ var repositories = new Dictionary < string , Repository >
314+ {
315+ [ "test-repo" ] = CreateRepository ( current : "main" , next : "main" , edge : "main" )
316+ } ;
317+ var config = CreateConfiguration ( repositories ) ;
318+ var versionParts = productVersion . Split ( '.' ) ;
319+ var product = CreateProduct ( new SemVersion ( int . Parse ( versionParts [ 0 ] , null ) , int . Parse ( versionParts [ 1 ] , null ) , int . Parse ( versionParts [ 2 ] , null ) ) ) ;
320+
321+ var result = config . Match ( LoggerFactory , "elastic/test-repo" , branch , product ) ;
322+
323+ result . Speculative . Should ( ) . BeTrue ( ) ;
324+ }
325+
326+ [ Fact ]
327+ public void VersionBranchNoSpeculativeBuildWhenProductVersioningSystemIsNull ( )
328+ {
329+ var repositories = new Dictionary < string , Repository >
330+ {
331+ [ "test-repo" ] = CreateRepository ( current : "main" , next : "main" , edge : "main" )
332+ } ;
333+ var config = CreateConfiguration ( repositories ) ;
334+ var product = new Product
335+ {
336+ Id = "test-product" ,
337+ DisplayName = "Test Product" ,
338+ VersioningSystem = null // No versioning system
339+ } ;
340+
341+ var result = config . Match ( LoggerFactory , "elastic/test-repo" , "9.0" , product ) ;
342+
343+ result . Speculative . Should ( ) . BeFalse ( ) ;
344+ }
345+
346+ [ Fact ]
347+ public void VersionBranchNoSpeculativeBuildWhenProductIsNull ( )
348+ {
349+ var repositories = new Dictionary < string , Repository >
350+ {
351+ [ "test-repo" ] = CreateRepository ( current : "main" , next : "main" , edge : "main" )
352+ } ;
353+ var config = CreateConfiguration ( repositories ) ;
354+
355+ var result = config . Match ( LoggerFactory , "elastic/test-repo" , "9.0" , null ) ;
356+
357+ result . Speculative . Should ( ) . BeFalse ( ) ;
358+ }
359+
360+ [ Theory ]
361+ [ InlineData ( "9.0" , "9.0.15" ) ] // Anchored version equals major.minor.0
362+ [ InlineData ( "9.0" , "9.0.0" ) ] // Anchored version equals major.minor.0
363+ [ InlineData ( "9.0" , "9.0.1" ) ] // Anchored version equals major.minor.0
364+ public void VersionBranchAnchorsProductVersionToMinorZero ( string branch , string productVersion )
365+ {
366+ var repositories = new Dictionary < string , Repository >
367+ {
368+ [ "test-repo" ] = CreateRepository ( current : "main" , next : "main" , edge : "main" )
369+ } ;
370+ var config = CreateConfiguration ( repositories ) ;
371+ var versionParts = productVersion . Split ( '.' ) ;
372+ var product = CreateProduct ( new SemVersion ( int . Parse ( versionParts [ 0 ] , null ) , int . Parse ( versionParts [ 1 ] , null ) , int . Parse ( versionParts [ 2 ] , null ) ) ) ;
373+
374+ var result = config . Match ( LoggerFactory , "elastic/test-repo" , branch , product ) ;
375+
376+ // Should match because branch 9.0 >= anchored product version 9.0.0
377+ result . Speculative . Should ( ) . BeTrue ( ) ;
378+ }
379+
380+ [ Theory ]
381+ [ InlineData ( "8.0" , "8.1.0" ) ] // Previous minor when current is 8.1
382+ [ InlineData ( "7.17" , "8.0.0" ) ] // Previous minor when current is 8.0 (floor at 0)
383+ public void VersionBranchPreviousMinorCalculationHandlesEdgeCases ( string branch , string productVersion )
384+ {
385+ var repositories = new Dictionary < string , Repository >
386+ {
387+ [ "test-repo" ] = CreateRepository ( current : "main" , next : "main" , edge : "main" )
388+ } ;
389+ var config = CreateConfiguration ( repositories ) ;
390+ var versionParts = productVersion . Split ( '.' ) ;
391+ var product = CreateProduct ( new SemVersion ( int . Parse ( versionParts [ 0 ] , null ) , int . Parse ( versionParts [ 1 ] , null ) , int . Parse ( versionParts [ 2 ] , null ) ) ) ;
392+
393+ var result = config . Match ( LoggerFactory , "elastic/test-repo" , branch , product ) ;
394+
395+ // 8.0 should match previous minor of 8.1 (which is 8.0)
396+ // 7.17 should NOT match previous minor of 8.0 (which is Math.Max(0-1, 0) = 8.0, not 7.17)
397+ var expectedSpeculative = branch == "8.0" && productVersion == "8.1.0" ;
398+ result . Speculative . Should ( ) . Be ( expectedSpeculative ) ;
399+ }
268400}
0 commit comments