1 package integration_test
2
3 import (
4 "bytes"
5 "encoding/json"
6 "encoding/xml"
7 "flag"
8 "fmt"
9 "os"
10 "os/exec"
11 "path/filepath"
12 "runtime"
13
14 . "github.com/onsi/ginkgo/v2"
15 "github.com/onsi/ginkgo/v2/reporters"
16 "github.com/onsi/ginkgo/v2/types"
17 . "github.com/onsi/gomega"
18 "github.com/onsi/gomega/format"
19 "github.com/onsi/gomega/gexec"
20
21 "testing"
22 "time"
23 )
24
25 var pathToGinkgo string
26 var DEBUG bool
27 var fm FixtureManager
28
29 func init() {
30 flag.BoolVar(&DEBUG, "debug", false, "keep assets around after test run")
31 }
32
33 func TestIntegration(t *testing.T) {
34 SetDefaultEventuallyTimeout(30 * time.Second)
35 format.TruncatedDiff = false
36 RegisterFailHandler(Fail)
37 RunSpecs(t, "Integration Suite", Label("integration"))
38 }
39
40 var _ = SynchronizedBeforeSuite(func() []byte {
41 DeferCleanup(gexec.CleanupBuildArtifacts)
42 pathToGinkgo, err := gexec.Build("../ginkgo")
43 Ω(err).ShouldNot(HaveOccurred())
44 return []byte(pathToGinkgo)
45 }, func(computedPathToGinkgo []byte) {
46 pathToGinkgo = string(computedPathToGinkgo)
47 })
48
49 var _ = BeforeEach(OncePerOrdered, func() {
50 fm = NewFixtureManager(fmt.Sprintf("tmp_%d", GinkgoParallelProcess()))
51 })
52
53 var _ = AfterEach(OncePerOrdered, func() {
54 if DEBUG {
55 return
56 }
57 suiteConfig, _ := GinkgoConfiguration()
58 if CurrentSpecReport().Failed() && suiteConfig.FailFast {
59 return
60 }
61 fm.Cleanup()
62 })
63
64 type FixtureManager struct {
65 TmpDir string
66 }
67
68 func NewFixtureManager(tmpDir string) FixtureManager {
69 err := os.MkdirAll(tmpDir, 0700)
70 Ω(err).ShouldNot(HaveOccurred())
71 return FixtureManager{
72 TmpDir: tmpDir,
73 }
74 }
75
76 func (f FixtureManager) Cleanup() {
77 Ω(os.RemoveAll(f.TmpDir)).Should(Succeed())
78 }
79
80 func (f FixtureManager) MountFixture(fixture string, subPackage ...string) {
81 src := filepath.Join("_fixtures", fixture+"_fixture")
82 dst := filepath.Join(f.TmpDir, fixture)
83
84 if len(subPackage) > 0 {
85 src = filepath.Join(src, subPackage[0])
86 dst = filepath.Join(dst, subPackage[0])
87 }
88
89 f.copyAndRewrite(src, dst)
90 }
91
92 func (f FixtureManager) MkEmpty(pkg string) {
93 ExpectWithOffset(1, os.MkdirAll(f.PathTo(pkg), 0700)).Should(Succeed())
94 }
95
96 func (f FixtureManager) copyAndRewrite(src string, dst string) {
97 Expect(os.MkdirAll(dst, 0777)).To(Succeed())
98
99 files, err := os.ReadDir(src)
100 Expect(err).NotTo(HaveOccurred())
101
102 for _, file := range files {
103 srcPath := filepath.Join(src, file.Name())
104 dstPath := filepath.Join(dst, file.Name())
105 if file.IsDir() {
106 f.copyAndRewrite(srcPath, dstPath)
107 continue
108 }
109
110 srcContent, err := os.ReadFile(srcPath)
111 Ω(err).ShouldNot(HaveOccurred())
112
113 srcContent = bytes.ReplaceAll(srcContent, []byte("github.com/onsi/ginkgo/v2/integration/_fixtures"), []byte(f.PackageRoot()))
114 srcContent = bytes.ReplaceAll(srcContent, []byte("_fixture"), []byte(""))
115 Ω(os.WriteFile(dstPath, srcContent, 0666)).Should(Succeed())
116 }
117 }
118
119 func (f FixtureManager) AbsPathTo(pkg string, target ...string) string {
120 path, err := filepath.Abs(f.PathTo(pkg, target...))
121 ExpectWithOffset(1, err).NotTo(HaveOccurred())
122 return path
123 }
124
125 func (f FixtureManager) PathTo(pkg string, target ...string) string {
126 if len(target) == 0 {
127 return filepath.Join(f.TmpDir, pkg)
128 }
129 components := append([]string{f.TmpDir, pkg}, target...)
130 return filepath.Join(components...)
131 }
132
133 func (f FixtureManager) PathToFixtureFile(pkg string, target string) string {
134 return filepath.Join("_fixtures", pkg+"_fixture", target)
135 }
136
137 func (f FixtureManager) WriteFile(pkg string, target string, content string) {
138 dst := f.PathTo(pkg, target)
139 err := os.WriteFile(dst, []byte(content), 0666)
140 Ω(err).ShouldNot(HaveOccurred())
141 }
142
143 func (f FixtureManager) AppendToFile(pkg string, target string, content string) {
144 current := f.ContentOf(pkg, target)
145 f.WriteFile(pkg, target, current+content)
146 }
147
148 func (f FixtureManager) ContentOf(pkg string, target string) string {
149 content, err := os.ReadFile(f.PathTo(pkg, target))
150 ExpectWithOffset(1, err).NotTo(HaveOccurred())
151 return string(content)
152 }
153
154 func (f FixtureManager) ListDir(pkg string, target ...string) []string {
155 path := f.PathTo(pkg, target...)
156 files, err := os.ReadDir(path)
157 ExpectWithOffset(1, err).NotTo(HaveOccurred())
158 out := []string{}
159 for _, f := range files {
160 out = append(out, f.Name())
161 }
162 return out
163 }
164
165 func (f FixtureManager) LoadJSONReports(pkg string, target string) []types.Report {
166 data := []byte(f.ContentOf(pkg, target))
167 reports := []types.Report{}
168 ExpectWithOffset(1, json.Unmarshal(data, &reports)).Should(Succeed())
169 return reports
170 }
171
172 func (f FixtureManager) LoadJUnitReport(pkg string, target string) reporters.JUnitTestSuites {
173 data := []byte(f.ContentOf(pkg, target))
174 reports := reporters.JUnitTestSuites{}
175 ExpectWithOffset(1, xml.Unmarshal(data, &reports)).Should(Succeed())
176 return reports
177 }
178
179 func (f FixtureManager) ContentOfFixture(pkg string, target string) string {
180 content, err := os.ReadFile(f.PathToFixtureFile(pkg, target))
181 ExpectWithOffset(1, err).NotTo(HaveOccurred())
182 return string(content)
183 }
184
185 func (f FixtureManager) RemoveFile(pkg string, target string) {
186 Expect(os.RemoveAll(f.PathTo(pkg, target))).To(Succeed())
187 }
188
189 func (f FixtureManager) PackageRoot() string {
190 return "github.com/onsi/ginkgo/v2/integration/" + f.TmpDir
191 }
192
193 func (f FixtureManager) PackageNameFor(target string) string {
194 return f.PackageRoot() + "/" + target
195 }
196
197 func sameFile(filePath, otherFilePath string) bool {
198 content, readErr := os.ReadFile(filePath)
199 Expect(readErr).NotTo(HaveOccurred())
200 otherContent, readErr := os.ReadFile(otherFilePath)
201 Expect(readErr).NotTo(HaveOccurred())
202 Expect(string(content)).To(Equal(string(otherContent)))
203 return true
204 }
205
206 func sameFolder(sourcePath, destinationPath string) bool {
207 files, err := os.ReadDir(sourcePath)
208 Expect(err).NotTo(HaveOccurred())
209 for _, f := range files {
210 srcPath := filepath.Join(sourcePath, f.Name())
211 dstPath := filepath.Join(destinationPath, f.Name())
212 if f.IsDir() {
213 sameFolder(srcPath, dstPath)
214 continue
215 }
216 Expect(sameFile(srcPath, dstPath)).To(BeTrue())
217 }
218 return true
219 }
220
221 func ginkgoCommand(dir string, args ...string) *exec.Cmd {
222 cmd := exec.Command(pathToGinkgo, args...)
223 cmd.Dir = dir
224
225 return cmd
226 }
227
228 func startGinkgo(dir string, args ...string) *gexec.Session {
229 cmd := ginkgoCommand(dir, args...)
230 session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter)
231 Ω(err).ShouldNot(HaveOccurred())
232 return session
233 }
234
235 func raceDetectorSupported() bool {
236
237 switch runtime.GOOS {
238 case "linux":
239 return runtime.GOARCH == "amd64" || runtime.GOARCH == "ppc64le" || runtime.GOARCH == "arm64"
240 case "darwin":
241 return runtime.GOARCH == "amd64" || runtime.GOARCH == "arm64"
242 case "freebsd", "netbsd", "windows":
243 return runtime.GOARCH == "amd64"
244 default:
245 return false
246 }
247 }
248
View as plain text