@@ -2,6 +2,13 @@ package datadog.smoketest
22
33import spock.lang.Shared
44
5+ import java.nio.file.FileSystems
6+ import java.nio.file.Path
7+ import java.nio.file.StandardWatchEventKinds
8+ import java.nio.file.WatchEvent
9+ import java.nio.file.WatchKey
10+ import java.nio.file.WatchService
11+ import java.util.concurrent.TimeUnit
512import java.util.zip.ZipEntry
613import java.util.zip.ZipInputStream
714
@@ -17,9 +24,7 @@ import java.util.zip.ZipInputStream
1724class TracerFlareSmokeTest extends AbstractSmokeTest {
1825
1926 // Time in seconds after which flare is triggered
20- private static final int FLARE_TRIGGER_SECONDS = 10
21- // Additional buffer time to ensure flare is written to disk
22- private static final int FLARE_WRITE_BUFFER_SECONDS = 5
27+ private static final int FLARE_TRIGGER_SECONDS = 15
2328 // Number of processes to run in parallel for testing
2429 private static final int NUMBER_OF_PROCESSES = 2
2530
@@ -118,14 +123,22 @@ class TracerFlareSmokeTest extends AbstractSmokeTest {
118123 " profiling_template_override.jfp" // Only if template override is configured
119124 ] as Set<String >
120125
121- def "tracer generates flare with profiling enabled (default )" () {
122- given:
123- // Wait for flare to be generated (triggered after FLARE_TRIGGER_SECONDS + buffer time)
124- Thread.sleep((FLARE_TRIGGER_SECONDS + FLARE_WRITE_BUFFER_SECONDS) * 1000)
126+ // Flare file naming pattern constants
127+ private static final String FLARE_FILE_PREFIX = " dd-java-flare-"
128+ private static final String FLARE_FILE_EXTENSION = " .zip"
129+
130+ /**
131+ * Checks if a filename matches the expected flare file pattern
132+ */
133+ private static boolean isFlareFile (String fileName ) {
134+ fileName. startsWith(FLARE_FILE_PREFIX ) && fileName. endsWith(FLARE_FILE_EXTENSION )
135+ }
125136
137+ def "tracer generates flare with profiling enabled (default )" () {
126138 when:
127- // Find the generated flare file from process 0
128- def flareFile = findFlareFile(flareDirs[0])
139+ // Wait for flare file to be created using filesystem watcher
140+ // The flare is triggered after FLARE_TRIGGER_SECONDS, plus some write time
141+ def flareFile = waitForFlareFile(flareDirs[0])
129142 def zipContents = extractZipContents(flareFile)
130143
131144 then:
@@ -143,9 +156,9 @@ class TracerFlareSmokeTest extends AbstractSmokeTest {
143156
144157 def " tracer generates flare with profiling disabled" () {
145158 when:
146- // Find the generated flare file from process 1
147- // The flare should already be generated from the wait in the first test
148- def flareFile = findFlareFile (flareDirs[1])
159+ // Wait for flare file to be created independently for process 1
160+ // Each test should be independent and not rely on timing from other tests
161+ def flareFile = waitForFlareFile (flareDirs[1])
149162 def zipContents = extractZipContents(flareFile)
150163
151164 then:
@@ -163,14 +176,6 @@ class TracerFlareSmokeTest extends AbstractSmokeTest {
163176 validateNoUnexpectedFiles(zipContents, CORE_FILES + OPTIONAL_FILES)
164177 }
165178
166- private static File findFlareFile(File flareDir) {
167- def flareFiles = flareDir.listFiles({ File dir, String name ->
168- name.startsWith(" dd- java- flare- " ) && name.endsWith(" . zip" )
169- } as FilenameFilter)
170- assert flareFiles.size() == 1 : " Expected exactly one flare file, found : ${flareFiles. size()}"
171- flareFiles.first()
172- }
173-
174179 private static void validateNoUnexpectedFiles(Set<String> zipContents, Set<String> expectedFiles) {
175180 def unexpectedFiles = zipContents - expectedFiles
176181 assert !unexpectedFiles : " Found unexpected files in flare : ${unexpectedFiles}"
@@ -193,4 +198,79 @@ class TracerFlareSmokeTest extends AbstractSmokeTest {
193198
194199 fileNames
195200 }
201+
202+ /**
203+ * Waits for a flare file to be created in the specified directory using filesystem watching.
204+ *
205+ * @param flareDir The directory to watch for flare files
206+ * @param timeoutSeconds Maximum time to wait for the file
207+ * @return The created flare file
208+ * @throws AssertionError if no flare file is created within the timeout
209+ */
210+ private static File waitForFlareFile(File flareDir, int timeoutSeconds = FLARE_TRIGGER_SECONDS + 5) {
211+ Path dirPath = flareDir.toPath()
212+ WatchService watchService = FileSystems.getDefault().newWatchService()
213+
214+ try {
215+ def existingFile = findFlareFileIfExists(flareDir)
216+ if (existingFile) {
217+ return existingFile
218+ }
219+
220+ dirPath.register(watchService, StandardWatchEventKinds.ENTRY_CREATE)
221+ long deadlineMillis = System.currentTimeMillis() + (timeoutSeconds * 1000)
222+
223+ while (System.currentTimeMillis() < deadlineMillis) {
224+ long remainingMillis = deadlineMillis - System.currentTimeMillis()
225+ if (remainingMillis <= 0) {
226+ break
227+ }
228+
229+ WatchKey key = watchService.poll(remainingMillis, TimeUnit.MILLISECONDS)
230+ if (key == null) {
231+ existingFile = findFlareFileIfExists(flareDir)
232+ if (existingFile) {
233+ return existingFile
234+ }
235+ break
236+ }
237+
238+ for (WatchEvent<?> event : key.pollEvents()) {
239+ WatchEvent<Path> pathEvent = (WatchEvent<Path>) event
240+ Path fileName = pathEvent.context()
241+
242+ if (isFlareFile(fileName.toString())) {
243+ return new File(flareDir, fileName.toString())
244+ }
245+ }
246+
247+ boolean valid = key.reset()
248+ if (!valid) {
249+ throw new AssertionError(" Watch directory ${flareDir} is no longer accessible" )
250+ }
251+ }
252+
253+ existingFile = findFlareFileIfExists(flareDir)
254+ if (existingFile) {
255+ return existingFile
256+ }
257+
258+ throw new AssertionError(" No flare file created in ${flareDir} within ${timeoutSeconds} seconds" )
259+
260+ } finally {
261+ watchService.close()
262+ }
263+ }
264+
265+ /**
266+ * Attempts to find an existing flare file in the directory.
267+ * Returns null if no flare file exists.
268+ */
269+ private static File findFlareFileIfExists(File flareDir) {
270+ def flareFiles = flareDir.listFiles({ File dir, String name ->
271+ isFlareFile(name)
272+ } as FilenameFilter)
273+
274+ return flareFiles?.size() > 0 ? flareFiles.first() : null
275+ }
196276}
0 commit comments