@@ -2040,6 +2040,132 @@ def test_inc_update_composite_updated_expected_version(
20402040 # Control CV, no changes
20412041 assert comp .version == '1.0'
20422042
2043+ def test_ccv_no_double_update_on_incremental_with_propagate_all_composites (
2044+ self ,
2045+ target_sat ,
2046+ module_org ,
2047+ module_product ,
2048+ ):
2049+ """CCV with auto-publish and 'Always update to latest' updates once (to 1.1) on
2050+ incremental update with --propagate-all-composites, not twice (no spurious 2.0).
2051+ Composite Content Views must not auto-publish on child CV minor version updates
2052+ when propagate-all-composites is set; only the incremental 1.1 is created.
2053+ Auto-publish still works for child major version updates (e.g. CV 2.0 -> CCV 2.0).
2054+
2055+ :id: c7572e4d-3079-486e-93c9-fb0b183a4e08
2056+
2057+ :steps:
2058+ 1. Create and sync a product with a repo containing missing errata
2059+ (e.g. needed_errata / yum_6).
2060+ 2. Add repo to a Content View and publish it (CV Version 1.0).
2061+ 3. Add this content view to a Composite Content View; set component to
2062+ 'Always update to latest version'; set CCV to auto-publish.
2063+ 4. Manually publish the Composite Content View (CCV Version 1.0).
2064+ 5. Run incremental update on the CV with --propagate-all-composites:
2065+ hammer content-view version incremental-update
2066+ --content-view-version-id <cvv-id> --errata-ids <erratum-id>
2067+ --propagate-all-composites true
2068+ 6. Assert: new CV version 1.1 and new CCV version 1.1 exist; no CCV 2.0.
2069+ 7. Manually publish a new major version of the content view (2.0).
2070+ 8. Assert: Composite Content View auto-published to 2.0.
2071+
2072+ :expectedresults:
2073+ - After step 5, only CV 1.1 and CCV 1.1 exist (no CCV 2.0).
2074+ - After step 7, CCV auto-publishes to 2.0.
2075+
2076+ :verifies: SAT-34620
2077+
2078+ :customerscenario: true
2079+ """
2080+ # Step 1: repo with missing errata (needed_errata / yum_6)
2081+ repo = target_sat .api .Repository (
2082+ product = module_product ,
2083+ url = settings .repos .yum_6 .url ,
2084+ ).create ()
2085+ repo .sync ()
2086+ repo = repo .read ()
2087+ errata_id = settings .repos .yum_6 .errata [0 ]
2088+
2089+ # Step 2: CV with repo, publish 1.0
2090+ cv = target_sat .api .ContentView (
2091+ organization = module_org ,
2092+ repository = [repo ],
2093+ auto_publish = False ,
2094+ ).create ()
2095+ cv .publish ()
2096+ cv = cv .read ()
2097+ cvv_1_0 = cv .version [0 ].read ()
2098+ assert cvv_1_0 .version == '1.0'
2099+
2100+ # Step 3 & 4: CCV with CV as component (latest=True), auto_publish=True; publish CCV 1.0
2101+ ccv = target_sat .api .ContentView (
2102+ organization = module_org ,
2103+ composite = True ,
2104+ auto_publish = True ,
2105+ component = [cvv_1_0 ],
2106+ ).create ()
2107+ ccv = ccv .read ()
2108+ for comp in ccv .content_view_component :
2109+ comp = comp .read ()
2110+ comp .latest = True
2111+ comp .update (['latest' ])
2112+ ccv .publish ()
2113+ ccv = ccv .read ()
2114+ assert len (ccv .version ) == 1
2115+ assert ccv .version [0 ].read ().version == '1.0'
2116+
2117+ # Step 5: incremental update with propagate_all_composites
2118+ target_sat .api .ContentViewVersion ().incremental_update (
2119+ data = {
2120+ 'content_view_version_environments' : [
2121+ {
2122+ 'content_view_version_id' : cvv_1_0 .id ,
2123+ 'environment_ids' : [module_org .library .id ],
2124+ }
2125+ ],
2126+ 'add_content' : {'errata_ids' : [errata_id ]},
2127+ 'propagate_all_composites' : True ,
2128+ }
2129+ )
2130+
2131+ # Step 6: CV 1.1 and CCV 1.1 only; no CCV 2.0
2132+ cv = cv .read ()
2133+ ccv = ccv .read ()
2134+ assert set ([v .read ().version for v in cv .version ]) == {'1.0' , '1.1' }, (
2135+ f'Expected CV versions 1.0 and 1.1, got { set ([v .read ().version for v in cv .version ])} '
2136+ )
2137+ assert set ([v .read ().version for v in ccv .version ]) == {'1.0' , '1.1' }, (
2138+ f'Expected CCV versions 1.0 and 1.1, got { set ([v .read ().version for v in ccv .version ])} '
2139+ )
2140+ # Step 7: new major version of CV (add content and publish 2.0)
2141+ extra_repo = target_sat .api .Repository (
2142+ product = module_product ,
2143+ url = settings .repos .yum_1 .url ,
2144+ ).create ()
2145+ extra_repo .sync ()
2146+ cv .repository .append (extra_repo .read ())
2147+ cv .update (['repository' ])
2148+ cv = cv .read ()
2149+ cv .publish ()
2150+ # Wait for CV 2.0 publish and CCV 2.0 auto-publish tasks to complete
2151+ target_sat .wait_for_tasks (
2152+ search_query = (
2153+ f'label = Actions::Katello::ContentView::Publish and organization_id = { module_org .id } '
2154+ ),
2155+ search_rate = 10 ,
2156+ max_tries = 18 ,
2157+ )
2158+ cv = cv .read ()
2159+ cv_version_after = sorted ([v .read ().version for v in cv .version ])
2160+ assert '2.0' in cv_version_after
2161+
2162+ # Step 8: CCV auto-published to 2.0
2163+ ccv = ccv .read ()
2164+ ccv_versions_after = sorted ([v .read ().version for v in ccv .version ])
2165+ assert '2.0' in ccv_versions_after , (
2166+ f'Auto-publish should create CCV 2.0 when CV 2.0 is published. Got { ccv_versions_after } '
2167+ )
2168+
20432169
20442170class TestContentViewUpdate :
20452171 """Tests for updating content views."""
0 commit comments