@@ -59,152 +59,133 @@ This is a test agent for integration testing.
5959 let _ = fs:: remove_dir_all ( & temp_dir) ;
6060}
6161
62- /// Test that verifies the expected structure of the compiled YAML output
63- #[ test]
64- fn test_compiled_yaml_structure ( ) {
65- // This test reads a pre-compiled YAML and verifies its structure
66- // Since we need the actual compilation to happen, we'll verify the template structure
67-
68- let template_path = PathBuf :: from ( env ! ( "CARGO_MANIFEST_DIR" ) )
69- . join ( "src" )
70- . join ( "data" )
71- . join ( "base.yml" ) ;
72-
73- assert ! ( template_path. exists( ) , "Base template should exist" ) ;
74-
75- let template_content =
76- fs:: read_to_string ( & template_path) . expect ( "Should be able to read base template" ) ;
77-
78- // Verify template contains expected markers
79- assert ! (
80- template_content. contains( "{{ repositories }}" ) ,
81- "Template should contain repositories marker"
82- ) ;
83- assert ! (
84- template_content. contains( "{{ schedule }}" ) ,
85- "Template should contain schedule marker"
86- ) ;
87- assert ! (
88- template_content. contains( "{{ checkout_self }}" ) ,
89- "Template should contain checkout_self marker"
90- ) ;
91- assert ! (
92- template_content. contains( "{{ checkout_repositories }}" ) ,
93- "Template should contain checkout marker"
94- ) ;
95- assert ! (
96- template_content. contains( "{{ allowed_domains }}" ) ,
97- "Template should contain allowed_domains marker"
98- ) ;
99- assert ! (
100- template_content. contains( "{{ source_path }}" ) ,
101- "Template should contain source_path marker"
102- ) ;
103- assert ! (
104- template_content. contains( "{{ agent_name }}" ) ,
105- "Template should contain agent_name marker"
106- ) ;
107- assert ! (
108- template_content. contains( "{{ engine_run }}" ) ,
109- "Template should contain engine_run marker"
110- ) ;
111- assert ! (
112- template_content. contains( "{{ compiler_version }}" ) ,
113- "Template should contain compiler_version marker"
114- ) ;
115- assert ! (
116- template_content. contains( "{{ integrity_check }}" ) ,
117- "Template should contain integrity_check marker"
118- ) ;
119-
120- // Verify template doesn't accidentally use ${{ }} where {{ }} should be used
121- // (The ${{ }} syntax is for Azure DevOps pipeline expressions and should be preserved)
122- let marker_count = template_content. matches ( "{{ " ) . count ( ) ;
62+ /// Asserts that all required `{{ marker }}` placeholders are present in the template.
63+ fn assert_required_markers ( content : & str ) {
64+ let required = [
65+ "{{ repositories }}" ,
66+ "{{ schedule }}" ,
67+ "{{ checkout_self }}" ,
68+ "{{ checkout_repositories }}" ,
69+ "{{ allowed_domains }}" ,
70+ "{{ source_path }}" ,
71+ "{{ agent_name }}" ,
72+ "{{ engine_run }}" ,
73+ "{{ compiler_version }}" ,
74+ "{{ integrity_check }}" ,
75+ "{{ firewall_version }}" ,
76+ "{{ mcpg_config }}" ,
77+ "{{ mcpg_version }}" ,
78+ ] ;
79+ for marker in & required {
80+ assert ! (
81+ content. contains( marker) ,
82+ "Template should contain marker: {marker}"
83+ ) ;
84+ }
85+ // Sanity-check that at least 6 replacement markers exist in total.
86+ // (${{ }} is valid ADO pipeline syntax and must be preserved.)
87+ let marker_count = content. matches ( "{{ " ) . count ( ) ;
12388 assert ! (
12489 marker_count >= 6 ,
12590 "Template should have at least 6 replacement markers"
12691 ) ;
92+ }
12793
128- // Verify that {{ pool }} marker is used for all jobs, not hardcoded pool names
129- // This ensures consistency across Agent, Detection, and Execution jobs.
130- let pool_marker_count = template_content. matches ( "name: {{ pool }}" ) . count ( ) ;
94+ /// Asserts that the pool configuration uses the `{{ pool }}` marker everywhere
95+ /// and that no hardcoded pool name leaks into the template.
96+ fn assert_pool_config ( content : & str ) {
97+ // Must appear once per job: Agent, Detection, Execution.
98+ let pool_marker_count = content. matches ( "name: {{ pool }}" ) . count ( ) ;
13199 assert_eq ! (
132100 pool_marker_count, 3 ,
133101 "Template should use '{{ pool }}' marker exactly three times (once for each job)"
134102 ) ;
135-
136- // Verify that the default pool name is NOT hardcoded in the template
137- // The default should only exist in the compiler's Rust code, not the template
138103 assert ! (
139- !template_content . contains( "name: AZS-1ES-L-MMS-ubuntu-22.04" ) ,
104+ !content . contains( "name: AZS-1ES-L-MMS-ubuntu-22.04" ) ,
140105 "Template should not contain hardcoded pool name 'AZS-1ES-L-MMS-ubuntu-22.04'"
141106 ) ;
107+ }
142108
143- // Verify that the ado-aw compiler is downloaded from GitHub Releases, not ADO pipeline artifacts
109+ /// Asserts that the `ado-aw` compiler binary is fetched from GitHub Releases
110+ /// with a correct, targeted checksum verification.
111+ fn assert_compiler_download ( content : & str ) {
144112 assert ! (
145- !template_content . contains( "pipeline: 2437" ) ,
113+ !content . contains( "pipeline: 2437" ) ,
146114 "Template should not reference ADO pipeline 2437 for the compiler"
147115 ) ;
148116 assert ! (
149- template_content . contains( "github.com/githubnext/ado-aw/releases" ) ,
117+ content . contains( "github.com/githubnext/ado-aw/releases" ) ,
150118 "Template should download the compiler from GitHub Releases"
151119 ) ;
120+ // --ignore-missing silently passes when the binary is absent from checksums.txt.
152121 assert ! (
153- !template_content . contains( "sha256sum -c checksums.txt --ignore-missing" ) ,
154- "Template should not use --ignore-missing which silently passes when binary is missing from checksums "
122+ !content . contains( "sha256sum -c checksums.txt --ignore-missing" ) ,
123+ "Template should not use --ignore-missing in checksum verification "
155124 ) ;
156125 assert ! (
157- template_content . contains( r#"grep "ado-aw-linux-x64" checksums.txt | sha256sum -c -"# ) ,
126+ content . contains( r#"grep "ado-aw-linux-x64" checksums.txt | sha256sum -c -"# ) ,
158127 "Template should verify ado-aw checksum using targeted grep to ensure binary entry exists"
159128 ) ;
160129 assert ! (
161- !template_content . contains( "grep -q" ) ,
162- "Checksum verification should not pipe through grep"
130+ !content . contains( "grep -q" ) ,
131+ "Checksum verification should not pipe through grep -q "
163132 ) ;
133+ }
164134
165- // Verify AWF (Agentic Workflow Firewall) is downloaded from GitHub Releases, not ADO pipeline artifacts
135+ /// Asserts that the AWF binary is fetched from GitHub Releases, not ADO
136+ /// pipeline artifacts, and that no legacy artifact tasks remain.
137+ fn assert_awf_download ( content : & str ) {
166138 assert ! (
167- !template_content . contains( "pipeline: 2450" ) ,
139+ !content . contains( "pipeline: 2450" ) ,
168140 "Template should not reference ADO pipeline 2450 for the firewall"
169141 ) ;
170142 assert ! (
171- !template_content . contains( "DownloadPipelineArtifact" ) ,
143+ !content . contains( "DownloadPipelineArtifact" ) ,
172144 "Template should not use DownloadPipelineArtifact task"
173145 ) ;
174146 assert ! (
175- template_content . contains( "github.com/github/gh-aw-firewall/releases" ) ,
147+ content . contains( "github.com/github/gh-aw-firewall/releases" ) ,
176148 "Template should download AWF from GitHub Releases"
177149 ) ;
178- assert ! (
179- template_content. contains( "{{ firewall_version }}" ) ,
180- "Template should contain firewall_version marker"
181- ) ;
150+ }
182151
183- // Verify MCPG integration
184- assert ! (
185- template_content. contains( "{{ mcpg_config }}" ) ,
186- "Template should contain mcpg_config marker"
187- ) ;
188- assert ! (
189- template_content. contains( "{{ mcpg_version }}" ) ,
190- "Template should contain mcpg_version marker"
191- ) ;
152+ /// Asserts that MCPG is integrated correctly and that no legacy mcp-firewall
153+ /// artefacts remain in the template.
154+ fn assert_mcpg_integration ( content : & str ) {
192155 assert ! (
193- template_content . contains( "--enable-host-access" ) ,
156+ content . contains( "--enable-host-access" ) ,
194157 "Template should include --enable-host-access for MCPG"
195158 ) ;
196-
197- // Verify no legacy mcp-firewall references in template
198159 assert ! (
199- !template_content . contains( "mcp-firewall-config" ) ,
160+ !content . contains( "mcp-firewall-config" ) ,
200161 "Template should not reference legacy mcp-firewall config"
201162 ) ;
202163 assert ! (
203- !template_content . contains( "MCP_FIREWALL_EOF" ) ,
164+ !content . contains( "MCP_FIREWALL_EOF" ) ,
204165 "Template should not contain legacy firewall heredoc"
205166 ) ;
206167}
207168
169+ /// Test that verifies the expected structure of the compiled YAML output
170+ #[ test]
171+ fn test_compiled_yaml_structure ( ) {
172+ let template_path = PathBuf :: from ( env ! ( "CARGO_MANIFEST_DIR" ) )
173+ . join ( "src" )
174+ . join ( "data" )
175+ . join ( "base.yml" ) ;
176+
177+ assert ! ( template_path. exists( ) , "Base template should exist" ) ;
178+
179+ let content =
180+ fs:: read_to_string ( & template_path) . expect ( "Should be able to read base template" ) ;
181+
182+ assert_required_markers ( & content) ;
183+ assert_pool_config ( & content) ;
184+ assert_compiler_download ( & content) ;
185+ assert_awf_download ( & content) ;
186+ assert_mcpg_integration ( & content) ;
187+ }
188+
208189/// Test that the example file is valid and can be parsed
209190#[ test]
210191fn test_example_file_structure ( ) {
0 commit comments