@@ -6,8 +6,13 @@ package component_test
66import (
77 "testing"
88
9+ "github.com/microsoft/azure-linux-dev-tools/internal/app/azldev"
910 componentcmds "github.com/microsoft/azure-linux-dev-tools/internal/app/azldev/cmds/component"
11+ "github.com/microsoft/azure-linux-dev-tools/internal/app/azldev/core/components"
1012 "github.com/microsoft/azure-linux-dev-tools/internal/app/azldev/core/testutils"
13+ "github.com/microsoft/azure-linux-dev-tools/internal/projectconfig"
14+ "github.com/microsoft/azure-linux-dev-tools/internal/utils/fileperms"
15+ "github.com/microsoft/azure-linux-dev-tools/internal/utils/fileutils"
1116 "github.com/stretchr/testify/assert"
1217 "github.com/stretchr/testify/require"
1318)
@@ -95,3 +100,213 @@ func TestValidateBuildOptions_NoOverlapWithDifferentPaths(t *testing.T) {
95100 assert .Contains (t , err .Error (), "createrepo_c" )
96101 assert .NotContains (t , err .Error (), "appears in both" )
97102}
103+
104+ func TestPlaceRPMsByChannel_EmptyChannelStaysInPlace (t * testing.T ) {
105+ t .Parallel ()
106+
107+ testEnv := testutils .NewTestEnv (t )
108+
109+ const (
110+ rpmsDir = "/output/rpms"
111+ rpmPath = "/output/rpms/curl-8.0-1.rpm"
112+ )
113+
114+ require .NoError (t , fileutils .WriteFile (testEnv .TestFS , rpmPath , []byte ("rpm" ), fileperms .PrivateFile ))
115+
116+ rpmResults := []componentcmds.RPMResult {
117+ {Path : rpmPath , PackageName : "curl" , Channel : "" },
118+ }
119+
120+ require .NoError (t , componentcmds .PlaceRPMsByChannel (testEnv .Env , rpmResults , rpmsDir ))
121+
122+ // File stays at its original path; RPMResult.Path is unchanged.
123+ assert .Equal (t , rpmPath , rpmResults [0 ].Path )
124+ _ , err := testEnv .TestFS .Stat (rpmPath )
125+ assert .NoError (t , err , "original path should still exist" )
126+ }
127+
128+ func TestPlaceRPMsByChannel_NoneChannelStaysInPlace (t * testing.T ) {
129+ t .Parallel ()
130+
131+ testEnv := testutils .NewTestEnv (t )
132+
133+ const (
134+ rpmsDir = "/output/rpms"
135+ rpmPath = "/output/rpms/debuginfo-8.0-1.rpm"
136+ )
137+
138+ require .NoError (t , fileutils .WriteFile (testEnv .TestFS , rpmPath , []byte ("rpm" ), fileperms .PrivateFile ))
139+
140+ rpmResults := []componentcmds.RPMResult {
141+ {Path : rpmPath , PackageName : "debuginfo" , Channel : "none" },
142+ }
143+
144+ require .NoError (t , componentcmds .PlaceRPMsByChannel (testEnv .Env , rpmResults , rpmsDir ))
145+
146+ assert .Equal (t , rpmPath , rpmResults [0 ].Path )
147+ _ , err := testEnv .TestFS .Stat (rpmPath )
148+ assert .NoError (t , err , "original path should still exist" )
149+ }
150+
151+ func TestPlaceRPMsByChannel_NamedChannelMovesFile (t * testing.T ) {
152+ t .Parallel ()
153+
154+ testEnv := testutils .NewTestEnv (t )
155+
156+ const (
157+ rpmsDir = "/output/rpms"
158+ rpmPath = "/output/rpms/curl-8.0-1.rpm"
159+ expectedPath = "/output/rpms/base/curl-8.0-1.rpm"
160+ )
161+
162+ require .NoError (t , fileutils .WriteFile (testEnv .TestFS , rpmPath , []byte ("rpm" ), fileperms .PrivateFile ))
163+
164+ rpmResults := []componentcmds.RPMResult {
165+ {Path : rpmPath , PackageName : "curl" , Channel : "base" },
166+ }
167+
168+ require .NoError (t , componentcmds .PlaceRPMsByChannel (testEnv .Env , rpmResults , rpmsDir ))
169+
170+ // RPMResult.Path must be updated to the new location.
171+ assert .Equal (t , expectedPath , rpmResults [0 ].Path )
172+
173+ // File must exist at the channel subdirectory.
174+ _ , err := testEnv .TestFS .Stat (expectedPath )
175+ require .NoError (t , err , "file should exist at channel subdirectory" )
176+
177+ // File must no longer exist at the original location.
178+ _ , err = testEnv .TestFS .Stat (rpmPath )
179+ assert .Error (t , err , "file should have been moved away from the original path" )
180+ }
181+
182+ func TestPlaceRPMsByChannel_MultipleRPMsDifferentChannels (t * testing.T ) {
183+ t .Parallel ()
184+
185+ testEnv := testutils .NewTestEnv (t )
186+
187+ const rpmsDir = "/output/rpms"
188+
189+ type rpmInput struct {
190+ path string
191+ channel string
192+ }
193+
194+ inputs := []rpmInput {
195+ {"/output/rpms/curl-8.0-1.rpm" , "base" },
196+ {"/output/rpms/curl-devel-8.0-1.rpm" , "devel" },
197+ {"/output/rpms/curl-debuginfo-8.0-1.rpm" , "none" },
198+ {"/output/rpms/curl-static-8.0-1.rpm" , "" },
199+ }
200+
201+ rpmResults := make ([]componentcmds.RPMResult , 0 , len (inputs ))
202+
203+ for _ , in := range inputs {
204+ require .NoError (t , fileutils .WriteFile (testEnv .TestFS , in .path , []byte ("rpm" ), fileperms .PrivateFile ))
205+
206+ rpmResults = append (rpmResults , componentcmds.RPMResult {
207+ Path : in .path , PackageName : "curl" , Channel : in .channel ,
208+ })
209+ }
210+
211+ require .NoError (t , componentcmds .PlaceRPMsByChannel (testEnv .Env , rpmResults , rpmsDir ))
212+
213+ for _ , result := range rpmResults {
214+ switch result .Channel {
215+ case "base" :
216+ assert .Equal (t , "/output/rpms/base/curl-8.0-1.rpm" , result .Path )
217+ case "devel" :
218+ assert .Equal (t , "/output/rpms/devel/curl-devel-8.0-1.rpm" , result .Path )
219+ case "none" :
220+ assert .Equal (t , "/output/rpms/curl-debuginfo-8.0-1.rpm" , result .Path )
221+ case "" :
222+ assert .Equal (t , "/output/rpms/curl-static-8.0-1.rpm" , result .Path )
223+ }
224+
225+ _ , statErr := testEnv .TestFS .Stat (result .Path )
226+ assert .NoError (t , statErr , "RPM should exist at its final resolved path" )
227+ }
228+ }
229+
230+ func TestPlaceRPMsByChannel_MultipleRPMsSameChannel (t * testing.T ) {
231+ t .Parallel ()
232+
233+ testEnv := testutils .NewTestEnv (t )
234+
235+ const rpmsDir = "/output/rpms"
236+
237+ paths := []string {
238+ "/output/rpms/curl-8.0-1.rpm" ,
239+ "/output/rpms/libcurl-8.0-1.rpm" ,
240+ }
241+
242+ rpmResults := make ([]componentcmds.RPMResult , 0 , len (paths ))
243+
244+ for _ , path := range paths {
245+ require .NoError (t , fileutils .WriteFile (testEnv .TestFS , path , []byte ("rpm" ), fileperms .PrivateFile ))
246+
247+ rpmResults = append (rpmResults , componentcmds.RPMResult {
248+ Path : path , PackageName : "curl" , Channel : "base" ,
249+ })
250+ }
251+
252+ require .NoError (t , componentcmds .PlaceRPMsByChannel (testEnv .Env , rpmResults , rpmsDir ))
253+
254+ assert .Equal (t , "/output/rpms/base/curl-8.0-1.rpm" , rpmResults [0 ].Path )
255+ assert .Equal (t , "/output/rpms/base/libcurl-8.0-1.rpm" , rpmResults [1 ].Path )
256+
257+ for _ , result := range rpmResults {
258+ _ , err := testEnv .TestFS .Stat (result .Path )
259+ assert .NoError (t , err , "both RPMs should exist in the shared channel subdirectory" )
260+ }
261+ }
262+
263+ func TestPlaceRPMsByChannel_EmptyInput (t * testing.T ) {
264+ t .Parallel ()
265+
266+ testEnv := testutils .NewTestEnv (t )
267+
268+ err := componentcmds .PlaceRPMsByChannel (testEnv .Env , nil , "/output/rpms" )
269+ assert .NoError (t , err )
270+ }
271+
272+ func makeEnvWithDirs (t * testing.T , workDir , outputDir string ) * azldev.Env {
273+ t .Helper ()
274+
275+ base := testutils .NewTestEnv (t )
276+
277+ cfg := projectconfig .NewProjectConfig ()
278+ cfg .Project .WorkDir = workDir
279+ cfg .Project .OutputDir = outputDir
280+
281+ options := azldev .NewEnvOptions ()
282+ options .DryRunnable = base .DryRunnable
283+ options .EventListener = base .EventListener
284+ options .Interfaces = base .TestInterfaces
285+ options .Config = & cfg
286+
287+ return azldev .NewEnv (t .Context (), options )
288+ }
289+
290+ func TestBuildComponents_NoWorkDir (t * testing.T ) {
291+ t .Parallel ()
292+
293+ env := makeEnvWithDirs (t , "" , "/output" )
294+ comps := components .NewComponentSet ()
295+
296+ _ , err := componentcmds .BuildComponents (env , comps , & componentcmds.ComponentBuildOptions {})
297+
298+ require .Error (t , err )
299+ assert .Contains (t , err .Error (), "work dir" )
300+ }
301+
302+ func TestBuildComponents_NoOutputDir (t * testing.T ) {
303+ t .Parallel ()
304+
305+ env := makeEnvWithDirs (t , "/work" , "" )
306+ comps := components .NewComponentSet ()
307+
308+ _ , err := componentcmds .BuildComponents (env , comps , & componentcmds.ComponentBuildOptions {})
309+
310+ require .Error (t , err )
311+ assert .Contains (t , err .Error (), "output dir" )
312+ }
0 commit comments