23
23
import datetime
24
24
import os
25
25
import random
26
- import sys
27
26
import time
28
27
import uuid
29
- from unittest .mock import patch
30
28
31
29
import pytest
32
30
@@ -39,23 +37,21 @@ def setup_and_teardown(self):
39
37
"""Setup and teardown for each test."""
40
38
# Import plugin to apply patches (patches are applied at module level)
41
39
import codeflash .verification .pytest_plugin # noqa: F401
42
-
40
+
43
41
# Note: Original functions are already patched by the time we get here
44
42
# This is expected behavior since patches are applied at module import
45
-
46
- yield
47
-
43
+
48
44
# Note: In practice, these patches should remain for the entire test session
49
45
50
46
def test_time_time_deterministic (self ):
51
47
"""Test that time.time() returns a fixed deterministic value."""
52
48
expected_timestamp = 1609459200.0 # 2021-01-01 00:00:00 UTC
53
-
49
+
54
50
# Call multiple times and verify consistent results
55
51
result1 = time .time ()
56
52
result2 = time .time ()
57
53
result3 = time .time ()
58
-
54
+
59
55
assert result1 == expected_timestamp
60
56
assert result2 == expected_timestamp
61
57
assert result3 == expected_timestamp
@@ -67,21 +63,21 @@ def test_perf_counter_incremental(self):
67
63
result1 = time .perf_counter ()
68
64
result2 = time .perf_counter ()
69
65
result3 = time .perf_counter ()
70
-
66
+
71
67
# Verify they're different and incrementing by approximately 0.001
72
68
assert result1 < result2 < result3
73
69
assert abs ((result2 - result1 ) - 0.001 ) < 1e-6 # Use reasonable epsilon for float comparison
74
70
assert abs ((result3 - result2 ) - 0.001 ) < 1e-6
75
71
76
72
def test_uuid4_deterministic (self ):
77
73
"""Test that uuid.uuid4() returns a fixed deterministic UUID."""
78
- expected_uuid = uuid .UUID (' 12345678-1234-5678-9abc-123456789012' )
79
-
74
+ expected_uuid = uuid .UUID (" 12345678-1234-5678-9abc-123456789012" )
75
+
80
76
# Call multiple times and verify consistent results
81
77
result1 = uuid .uuid4 ()
82
78
result2 = uuid .uuid4 ()
83
79
result3 = uuid .uuid4 ()
84
-
80
+
85
81
assert result1 == expected_uuid
86
82
assert result2 == expected_uuid
87
83
assert result3 == expected_uuid
@@ -90,13 +86,13 @@ def test_uuid4_deterministic(self):
90
86
91
87
def test_uuid1_deterministic (self ):
92
88
"""Test that uuid.uuid1() returns a fixed deterministic UUID."""
93
- expected_uuid = uuid .UUID (' 12345678-1234-5678-9abc-123456789012' )
94
-
89
+ expected_uuid = uuid .UUID (" 12345678-1234-5678-9abc-123456789012" )
90
+
95
91
# Call multiple times with different parameters
96
92
result1 = uuid .uuid1 ()
97
93
result2 = uuid .uuid1 (node = 123456 )
98
94
result3 = uuid .uuid1 (clock_seq = 789 )
99
-
95
+
100
96
assert result1 == expected_uuid
101
97
assert result2 == expected_uuid
102
98
assert result3 == expected_uuid
@@ -105,12 +101,12 @@ def test_uuid1_deterministic(self):
105
101
def test_random_random_deterministic (self ):
106
102
"""Test that random.random() returns a fixed deterministic value."""
107
103
expected_value = 0.123456789
108
-
104
+
109
105
# Call multiple times and verify consistent results
110
106
result1 = random .random ()
111
107
result2 = random .random ()
112
108
result3 = random .random ()
113
-
109
+
114
110
assert result1 == expected_value
115
111
assert result2 == expected_value
116
112
assert result3 == expected_value
@@ -120,25 +116,25 @@ def test_random_seed_deterministic(self):
120
116
"""Test that random module is seeded deterministically."""
121
117
# The plugin should have already seeded with 42
122
118
# Test other random functions for consistency
123
-
119
+
124
120
# Note: random.random() is patched to always return the same value
125
121
# So we test that the random module behaves deterministically
126
122
# by testing that random.seed() affects other functions consistently
127
-
123
+
128
124
# First, test that our patched random.random always returns the same value
129
125
assert random .random () == 0.123456789
130
126
assert random .random () == 0.123456789
131
-
127
+
132
128
# Test that seeding affects other random functions consistently
133
129
random .seed (42 )
134
130
result1_int = random .randint (1 , 100 )
135
131
result1_choice = random .choice ([1 , 2 , 3 , 4 , 5 ])
136
-
132
+
137
133
# Re-seed and get same results
138
134
random .seed (42 )
139
135
result2_int = random .randint (1 , 100 )
140
136
result2_choice = random .choice ([1 , 2 , 3 , 4 , 5 ])
141
-
137
+
142
138
assert result1_int == result2_int
143
139
assert result1_choice == result2_choice
144
140
@@ -148,9 +144,9 @@ def test_os_urandom_deterministic(self):
148
144
for n in [1 , 8 , 16 , 32 ]:
149
145
result1 = os .urandom (n )
150
146
result2 = os .urandom (n )
151
-
147
+
152
148
# Should return fixed bytes (0x42 repeated)
153
- expected = b' \x42 ' * n
149
+ expected = b" \x42 " * n
154
150
assert result1 == expected
155
151
assert result2 == expected
156
152
assert len (result1 ) == n
@@ -160,17 +156,17 @@ def test_numpy_seeding(self):
160
156
"""Test that numpy.random is seeded if available."""
161
157
try :
162
158
import numpy as np
163
-
159
+
164
160
# Generate some random numbers
165
161
result1 = np .random .random (5 )
166
-
162
+
167
163
# Re-seed and generate again
168
164
np .random .seed (42 )
169
165
result2 = np .random .random (5 )
170
-
166
+
171
167
# Should be deterministic due to seeding
172
168
assert np .array_equal (result1 , result2 )
173
-
169
+
174
170
except ImportError :
175
171
# numpy not available, test should pass
176
172
pytest .skip ("NumPy not available" )
@@ -184,28 +180,28 @@ def test_performance_characteristics_maintained(self):
184
180
uuid .uuid4 ()
185
181
random .random ()
186
182
end = time .perf_counter ()
187
-
183
+
188
184
# Should complete quickly (less than 1 second for 1000 calls)
189
185
duration = end - start
190
186
assert duration < 1.0 , f"Performance degraded: { duration } s for 1000 calls"
191
187
192
188
def test_builtins_datetime_mocks_stored (self ):
193
189
"""Test that datetime mock functions are stored in builtins."""
194
190
import builtins
195
-
191
+
196
192
# Verify that the mock functions are stored
197
- assert hasattr (builtins , ' _original_datetime_now' )
198
- assert hasattr (builtins , ' _original_datetime_utcnow' )
199
- assert hasattr (builtins , ' _mock_datetime_now' )
200
- assert hasattr (builtins , ' _mock_datetime_utcnow' )
201
-
193
+ assert hasattr (builtins , " _original_datetime_now" )
194
+ assert hasattr (builtins , " _original_datetime_utcnow" )
195
+ assert hasattr (builtins , " _mock_datetime_now" )
196
+ assert hasattr (builtins , " _mock_datetime_utcnow" )
197
+
202
198
# Test that the mock functions work
203
199
mock_now = builtins ._mock_datetime_now
204
200
mock_utcnow = builtins ._mock_datetime_utcnow
205
-
201
+
206
202
result1 = mock_now ()
207
203
result2 = mock_utcnow ()
208
-
204
+
209
205
expected_dt = datetime .datetime (2021 , 1 , 1 , 0 , 0 , 0 , tzinfo = datetime .timezone .utc )
210
206
assert result1 == expected_dt
211
207
assert result2 == expected_dt
@@ -217,7 +213,7 @@ def test_consistency_across_multiple_calls(self):
217
213
initial_uuid = uuid .uuid4 ()
218
214
initial_random = random .random ()
219
215
initial_urandom = os .urandom (8 )
220
-
216
+
221
217
# Call functions many times (but not perf_counter since it increments)
222
218
for _ in range (5 ):
223
219
assert time .time () == initial_time
@@ -229,10 +225,10 @@ def test_perf_counter_state_management(self):
229
225
"""Test that perf_counter maintains its own internal state correctly."""
230
226
# Get a baseline
231
227
base = time .perf_counter ()
232
-
228
+
233
229
# Call several times and verify incrementing
234
230
results = [time .perf_counter () for _ in range (5 )]
235
-
231
+
236
232
# Each call should increment by approximately 0.001
237
233
for i , result in enumerate (results ):
238
234
expected = base + ((i + 1 ) * 0.001 )
@@ -242,38 +238,39 @@ def test_different_uuid_functions_same_result(self):
242
238
"""Test that both uuid4 and uuid1 return the same deterministic UUID."""
243
239
uuid4_result = uuid .uuid4 ()
244
240
uuid1_result = uuid .uuid1 ()
245
-
241
+
246
242
# Both should return the same fixed UUID
247
243
assert uuid4_result == uuid1_result
248
- assert str (uuid4_result ) == ' 12345678-1234-5678-9abc-123456789012'
244
+ assert str (uuid4_result ) == " 12345678-1234-5678-9abc-123456789012"
249
245
250
246
def test_patches_applied_at_module_level (self ):
251
247
"""Test that patches are applied when the module is imported."""
252
248
# Test that functions return expected deterministic values
253
249
# (This indirectly confirms they are patched)
254
250
assert time .time () == 1609459200.0
255
- assert uuid .uuid4 () == uuid .UUID (' 12345678-1234-5678-9abc-123456789012' )
251
+ assert uuid .uuid4 () == uuid .UUID (" 12345678-1234-5678-9abc-123456789012" )
256
252
assert random .random () == 0.123456789
257
-
253
+
258
254
# Test that function names indicate they are mock functions
259
- assert ' mock' in time .time .__name__
260
- assert ' mock' in uuid .uuid4 .__name__
261
- assert ' mock' in random .random .__name__
255
+ assert " mock" in time .time .__name__
256
+ assert " mock" in uuid .uuid4 .__name__
257
+ assert " mock" in random .random .__name__
262
258
263
259
def test_edge_cases (self ):
264
260
"""Test edge cases and boundary conditions."""
265
261
# Test uuid functions with edge case parameters
266
- assert uuid .uuid1 (node = 0 ) == uuid .UUID (' 12345678-1234-5678-9abc-123456789012' )
267
- assert uuid .uuid1 (clock_seq = 0 ) == uuid .UUID (' 12345678-1234-5678-9abc-123456789012' )
268
-
262
+ assert uuid .uuid1 (node = 0 ) == uuid .UUID (" 12345678-1234-5678-9abc-123456789012" )
263
+ assert uuid .uuid1 (clock_seq = 0 ) == uuid .UUID (" 12345678-1234-5678-9abc-123456789012" )
264
+
269
265
# Test urandom with edge cases
270
- assert os .urandom (0 ) == b''
271
- assert os .urandom (1 ) == b' \x42 '
272
-
266
+ assert os .urandom (0 ) == b""
267
+ assert os .urandom (1 ) == b" \x42 "
268
+
273
269
# Test datetime mock with timezone
274
270
import builtins
271
+
275
272
mock_now = builtins ._mock_datetime_now
276
-
273
+
277
274
# Test with different timezone
278
275
utc_tz = datetime .timezone .utc
279
276
result_with_tz = mock_now (utc_tz )
@@ -284,45 +281,41 @@ def test_integration_with_actual_optimization_scenario(self):
284
281
"""Test the patching in a scenario similar to actual optimization."""
285
282
# Simulate what happens during optimization - multiple function calls
286
283
# that would normally produce different results but should now be deterministic
287
-
284
+
288
285
class MockOptimizedFunction :
289
286
"""Mock function that uses various sources of randomness."""
290
-
287
+
291
288
def __init__ (self ):
292
289
self .id = uuid .uuid4 ()
293
290
self .created_at = time .time ()
294
291
self .random_factor = random .random ()
295
292
self .random_bytes = os .urandom (4 )
296
-
293
+
297
294
def execute (self ):
298
295
execution_time = time .perf_counter ()
299
296
random_choice = random .randint (1 , 100 )
300
297
return {
301
- 'id' : self .id ,
302
- ' created_at' : self .created_at ,
303
- ' execution_time' : execution_time ,
304
- ' random_factor' : self .random_factor ,
305
- ' random_choice' : random_choice ,
306
- ' random_bytes' : self .random_bytes
298
+ "id" : self .id ,
299
+ " created_at" : self .created_at ,
300
+ " execution_time" : execution_time ,
301
+ " random_factor" : self .random_factor ,
302
+ " random_choice" : random_choice ,
303
+ " random_bytes" : self .random_bytes ,
307
304
}
308
-
305
+
309
306
# Create two instances and execute them
310
307
func1 = MockOptimizedFunction ()
311
308
func2 = MockOptimizedFunction ()
312
-
309
+
313
310
result1 = func1 .execute ()
314
311
result2 = func2 .execute ()
315
-
316
- # All values should be identical due to deterministic patching
317
- assert result1 ['id' ] == result2 ['id' ]
318
- assert result1 ['created_at' ] == result2 ['created_at' ]
319
- assert result1 ['random_factor' ] == result2 ['random_factor' ]
320
- assert result1 ['random_bytes' ] == result2 ['random_bytes' ]
321
-
322
- # Only execution_time should be different (incremental)
323
- assert result1 ['execution_time' ] != result2 ['execution_time' ]
324
- assert result2 ['execution_time' ] > result1 ['execution_time' ]
325
312
313
+ # All values should be identical due to deterministic patching
314
+ assert result1 ["id" ] == result2 ["id" ]
315
+ assert result1 ["created_at" ] == result2 ["created_at" ]
316
+ assert result1 ["random_factor" ] == result2 ["random_factor" ]
317
+ assert result1 ["random_bytes" ] == result2 ["random_bytes" ]
326
318
327
- if __name__ == '__main__' :
328
- pytest .main ([__file__ , '-v' ])
319
+ # Only execution_time should be different (incremental)
320
+ assert result1 ["execution_time" ] != result2 ["execution_time" ]
321
+ assert result2 ["execution_time" ] > result1 ["execution_time" ]
0 commit comments