Skip to content

Commit 481e835

Browse files
committed
feat: implement build tests
1 parent c0d4987 commit 481e835

File tree

3 files changed

+297
-46
lines changed

3 files changed

+297
-46
lines changed

build.go

Lines changed: 73 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -40,69 +40,97 @@ func Build(
4040
) packit.BuildFunc {
4141
return func(context packit.BuildContext) (packit.BuildResult, error) {
4242
planEntries := filtered(context.Plan.Entries, pipinstall.SitePackages)
43+
layers := []packit.Layer{}
4344

4445
for _, entry := range planEntries {
4546
logger.Title("Handling %s", entry.Name)
4647

4748
switch entry.Name {
4849
case pipinstall.Manager:
49-
pipParameters := buildParameters[pipinstall.Manager].(pipinstall.PipBuildParameters)
50-
pipResult, err := pipinstall.Build(
51-
pipParameters.InstallProcess,
52-
pipParameters.SitePackagesProcess,
53-
commonBuildParameters,
54-
)(context)
55-
56-
if err != nil {
57-
return packit.BuildResult{}, err
50+
if parameters, ok := buildParameters[pipinstall.Manager]; ok {
51+
pipParameters := parameters.(pipinstall.PipBuildParameters)
52+
pipResult, err := pipinstall.Build(
53+
pipParameters.InstallProcess,
54+
pipParameters.SitePackagesProcess,
55+
commonBuildParameters,
56+
)(context)
57+
58+
if err != nil {
59+
return packit.BuildResult{}, err
60+
}
61+
62+
layers = append(layers, pipResult.Layers...)
63+
// return pipResult, err
64+
} else {
65+
return packit.BuildResult{}, packit.Fail.WithMessage("missing plan for: %s", entry.Name)
5866
}
5967

60-
return pipResult, err
6168
case pipenvinstall.Manager:
62-
pipenvParameters := buildParameters[pipenvinstall.Manager].(pipenvinstall.PipEnvBuildParameters)
63-
pipEnvResult, err := pipenvinstall.Build(
64-
pipenvParameters.InstallProcess,
65-
pipenvParameters.SiteProcess,
66-
pipenvParameters.VenvDirLocator,
67-
commonBuildParameters,
68-
)(context)
69-
70-
if err != nil {
71-
return packit.BuildResult{}, err
69+
if parameters, ok := buildParameters[pipenvinstall.Manager]; ok {
70+
pipenvParameters := parameters.(pipenvinstall.PipEnvBuildParameters)
71+
pipEnvResult, err := pipenvinstall.Build(
72+
pipenvParameters.InstallProcess,
73+
pipenvParameters.SiteProcess,
74+
pipenvParameters.VenvDirLocator,
75+
commonBuildParameters,
76+
)(context)
77+
78+
if err != nil {
79+
return packit.BuildResult{}, err
80+
}
81+
82+
layers = append(layers, pipEnvResult.Layers...)
83+
// return pipEnvResult, err
84+
} else {
85+
return packit.BuildResult{}, packit.Fail.WithMessage("missing plan for: %s", entry.Name)
7286
}
73-
74-
return pipEnvResult, err
7587
case conda.CondaEnvPlanEntry:
76-
condaParameters := buildParameters[conda.CondaEnvPlanEntry].(conda.CondaBuildParameters)
77-
condaResult, err := conda.Build(
78-
condaParameters.Runner,
79-
commonBuildParameters,
80-
)(context)
81-
82-
if err != nil {
83-
return packit.BuildResult{}, err
88+
if parameters, ok := buildParameters[conda.CondaEnvPlanEntry]; ok {
89+
condaParameters := parameters.(conda.CondaBuildParameters)
90+
condaResult, err := conda.Build(
91+
condaParameters.Runner,
92+
commonBuildParameters,
93+
)(context)
94+
95+
if err != nil {
96+
return packit.BuildResult{}, err
97+
}
98+
99+
layers = append(layers, condaResult.Layers...)
100+
// return condaResult, err
101+
} else {
102+
return packit.BuildResult{}, packit.Fail.WithMessage("missing plan for: %s", entry.Name)
84103
}
85-
86-
return condaResult, err
87104
case poetryinstall.PoetryVenv:
88-
poetryParameters := buildParameters[poetryinstall.PoetryVenv].(poetryinstall.PoetryEnvBuildParameters)
89-
poetryResult, err := poetryinstall.Build(
90-
poetryParameters.EntryResolver,
91-
poetryParameters.InstallProcess,
92-
poetryParameters.PythonPathLookupProcess,
93-
commonBuildParameters,
94-
)(context)
95-
96-
if err != nil {
97-
return packit.BuildResult{}, err
105+
if parameters, ok := buildParameters[poetryinstall.PoetryVenv]; ok {
106+
poetryParameters := parameters.(poetryinstall.PoetryEnvBuildParameters)
107+
poetryResult, err := poetryinstall.Build(
108+
poetryParameters.EntryResolver,
109+
poetryParameters.InstallProcess,
110+
poetryParameters.PythonPathLookupProcess,
111+
commonBuildParameters,
112+
)(context)
113+
114+
if err != nil {
115+
return packit.BuildResult{}, err
116+
}
117+
118+
layers = append(layers, poetryResult.Layers...)
119+
// return poetryResult, err
120+
} else {
121+
return packit.BuildResult{}, packit.Fail.WithMessage("missing plan for: %s", entry.Name)
98122
}
99-
100-
return poetryResult, err
101123
default:
102124
return packit.BuildResult{}, packit.Fail.WithMessage("unknown plan: %s", entry.Name)
103125
}
104126
}
105127

106-
return packit.BuildResult{}, packit.Fail.WithMessage("empty plan should not happen")
128+
if len(layers) == 0 {
129+
return packit.BuildResult{}, packit.Fail.WithMessage("empty plan should not happen")
130+
}
131+
132+
return packit.BuildResult{
133+
Layers: layers,
134+
}, nil
107135
}
108136
}

build_test.go

Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
// SPDX-FileCopyrightText: © 2025 Idiap Research Institute <[email protected]>
2+
// SPDX-FileContributor: Samuel Gaist <[email protected]>
3+
//
4+
// SPDX-License-Identifier: Apache-2.0
5+
6+
package pythonpackagers_test
7+
8+
import (
9+
"bytes"
10+
// "os"
11+
// "path/filepath"
12+
"testing"
13+
14+
"github.com/paketo-buildpacks/packit/v2"
15+
"github.com/paketo-buildpacks/packit/v2/chronos"
16+
"github.com/paketo-buildpacks/packit/v2/sbom"
17+
"github.com/paketo-buildpacks/packit/v2/scribe"
18+
19+
pythonpackagers "github.com/paketo-buildpacks/python-packagers"
20+
pkgcommon "github.com/paketo-buildpacks/python-packagers/pkg/common"
21+
conda "github.com/paketo-buildpacks/python-packagers/pkg/conda"
22+
condafakes "github.com/paketo-buildpacks/python-packagers/pkg/conda/fakes"
23+
pipinstall "github.com/paketo-buildpacks/python-packagers/pkg/pip"
24+
pipfakes "github.com/paketo-buildpacks/python-packagers/pkg/pip/fakes"
25+
pipenvinstall "github.com/paketo-buildpacks/python-packagers/pkg/pipenv"
26+
pipenvfakes "github.com/paketo-buildpacks/python-packagers/pkg/pipenv/fakes"
27+
poetryinstall "github.com/paketo-buildpacks/python-packagers/pkg/poetry"
28+
poetryfakes "github.com/paketo-buildpacks/python-packagers/pkg/poetry/fakes"
29+
30+
"github.com/sclevine/spec"
31+
32+
. "github.com/onsi/gomega"
33+
)
34+
35+
func testBuild(t *testing.T, context spec.G, it spec.S) {
36+
var (
37+
Expect = NewWithT(t).Expect
38+
39+
layersDir string
40+
workingDir string
41+
cnbDir string
42+
43+
buffer *bytes.Buffer
44+
logger scribe.Emitter
45+
build packit.BuildFunc
46+
buildContext packit.BuildContext
47+
48+
// common
49+
sbomGenerator *pipfakes.SBOMGenerator
50+
51+
// conda
52+
runner *condafakes.Runner
53+
54+
// pip
55+
pipInstallProcess *pipfakes.InstallProcess
56+
pipSitePackagesProcess *pipfakes.SitePackagesProcess
57+
58+
// pipenv
59+
pipenvInstallProcess *pipenvfakes.InstallProcess
60+
pipenvSitePackagesProcess *pipenvfakes.SitePackagesProcess
61+
pipenvVenvDirLocator *pipenvfakes.VenvDirLocator
62+
63+
// poetry
64+
poetryEntryResolver *poetryfakes.EntryResolver
65+
poetryInstallProcess *poetryfakes.InstallProcess
66+
poetryPythonPathProcess *poetryfakes.PythonPathLookupProcess
67+
68+
buildParameters pkgcommon.CommonBuildParameters
69+
70+
plans []packit.BuildpackPlan
71+
)
72+
73+
it.Before(func() {
74+
layersDir = t.TempDir()
75+
workingDir = t.TempDir()
76+
cnbDir = t.TempDir()
77+
78+
buffer = bytes.NewBuffer(nil)
79+
logger = scribe.NewEmitter(buffer)
80+
81+
sbomGenerator = &pipfakes.SBOMGenerator{}
82+
sbomGenerator.GenerateCall.Returns.SBOM = sbom.SBOM{}
83+
84+
// conda
85+
runner = &condafakes.Runner{}
86+
runner.ShouldRunCall.Returns.Bool = true
87+
runner.ShouldRunCall.Returns.String = "some-sha"
88+
89+
// pip
90+
pipInstallProcess = &pipfakes.InstallProcess{}
91+
pipSitePackagesProcess = &pipfakes.SitePackagesProcess{}
92+
pipSitePackagesProcess.ExecuteCall.Returns.SitePackagesPath = "some-site-packages-path"
93+
94+
// pipenv
95+
pipenvInstallProcess = &pipenvfakes.InstallProcess{}
96+
pipenvSitePackagesProcess = &pipenvfakes.SitePackagesProcess{}
97+
pipenvSitePackagesProcess.ExecuteCall.Returns.SitePackagesPath = "some-site-packages-path"
98+
pipenvVenvDirLocator = &pipenvfakes.VenvDirLocator{}
99+
pipenvVenvDirLocator.LocateVenvDirCall.Returns.VenvDir = "some-venv-dir"
100+
101+
// poetry
102+
poetryEntryResolver = &poetryfakes.EntryResolver{}
103+
poetryInstallProcess = &poetryfakes.InstallProcess{}
104+
poetryInstallProcess.ExecuteCall.Returns.String = "some-venv-dir"
105+
poetryPythonPathProcess = &poetryfakes.PythonPathLookupProcess{}
106+
poetryPythonPathProcess.ExecuteCall.Returns.String = "some-python-path"
107+
108+
buildParameters = pkgcommon.CommonBuildParameters{
109+
SbomGenerator: pkgcommon.Generator{},
110+
Clock: chronos.DefaultClock,
111+
Logger: logger,
112+
}
113+
114+
packagerParameters := map[string]pythonpackagers.PackagerParameters{
115+
conda.CondaEnvPlanEntry: conda.CondaBuildParameters{
116+
Runner: runner,
117+
},
118+
pipinstall.Manager: pipinstall.PipBuildParameters{
119+
InstallProcess: pipInstallProcess,
120+
SitePackagesProcess: pipSitePackagesProcess,
121+
},
122+
pipenvinstall.Manager: pipenvinstall.PipEnvBuildParameters{
123+
InstallProcess: pipenvInstallProcess,
124+
SiteProcess: pipenvSitePackagesProcess,
125+
VenvDirLocator: pipenvVenvDirLocator,
126+
},
127+
poetryinstall.PoetryVenv: poetryinstall.PoetryEnvBuildParameters{
128+
EntryResolver: poetryEntryResolver,
129+
InstallProcess: poetryInstallProcess,
130+
PythonPathLookupProcess: poetryPythonPathProcess,
131+
},
132+
}
133+
134+
build = pythonpackagers.Build(logger, buildParameters, packagerParameters)
135+
136+
buildContext = packit.BuildContext{
137+
BuildpackInfo: packit.BuildpackInfo{
138+
Name: "Some Buildpack",
139+
Version: "some-version",
140+
SBOMFormats: []string{sbom.CycloneDXFormat, sbom.SPDXFormat},
141+
},
142+
WorkingDir: workingDir,
143+
CNBPath: cnbDir,
144+
// Plan: shall be filled within each test
145+
Platform: packit.Platform{Path: "some-platform-path"},
146+
Layers: packit.Layers{Path: layersDir},
147+
Stack: "some-stack",
148+
}
149+
150+
plans = []packit.BuildpackPlan{
151+
packit.BuildpackPlan{
152+
Entries: []packit.BuildpackPlanEntry{
153+
{
154+
Name: conda.CondaEnvPlanEntry,
155+
},
156+
{
157+
Name: pipinstall.Manager,
158+
},
159+
{
160+
Name: pipenvinstall.Manager,
161+
},
162+
{
163+
Name: poetryinstall.PoetryVenv,
164+
},
165+
},
166+
},
167+
packit.BuildpackPlan{
168+
Entries: []packit.BuildpackPlanEntry{
169+
{
170+
Name: conda.CondaEnvPlanEntry,
171+
},
172+
{
173+
Name: pipinstall.Manager,
174+
},
175+
{
176+
Name: pipenvinstall.Manager,
177+
},
178+
},
179+
},
180+
packit.BuildpackPlan{
181+
Entries: []packit.BuildpackPlanEntry{
182+
{
183+
Name: conda.CondaEnvPlanEntry,
184+
},
185+
{
186+
Name: pipinstall.Manager,
187+
},
188+
},
189+
},
190+
packit.BuildpackPlan{
191+
Entries: []packit.BuildpackPlanEntry{
192+
{
193+
Name: conda.CondaEnvPlanEntry,
194+
},
195+
},
196+
},
197+
}
198+
})
199+
200+
it("runs the build process and returns expected layers", func() {
201+
for _, plan := range plans {
202+
buildContext.Plan = plan
203+
result, err := build(buildContext)
204+
Expect(err).NotTo(HaveOccurred())
205+
206+
layers := result.Layers
207+
Expect(layers).To(HaveLen(len(plan.Entries)))
208+
}
209+
})
210+
211+
it("fails if packager parameters is missing", func() {
212+
packagerParameters := map[string]pythonpackagers.PackagerParameters{}
213+
214+
build = pythonpackagers.Build(logger, buildParameters, packagerParameters)
215+
216+
for _, plan := range plans {
217+
buildContext.Plan = plan
218+
_, err := build(buildContext)
219+
Expect(err).To(HaveOccurred())
220+
}
221+
})
222+
223+
}

init_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@ import (
1515
func TestUnitPythonPackagers(t *testing.T) {
1616
suite := spec.New("python-packagers", spec.Report(report.Terminal{}), spec.Sequential())
1717
suite("Detect", testDetect)
18-
// suite("Build", testBuild)
18+
suite("Build", testBuild)
1919
suite.Run(t)
2020
}

0 commit comments

Comments
 (0)