Coverage for ivatar/test_robohash.py: 100%
117 statements
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-24 23:06 +0000
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-24 23:06 +0000
1"""
2Tests for robohash optimization functionality
3"""
5import time
6import hashlib
7from io import BytesIO
9from django.test import TestCase
10from PIL import Image
12from robohash import Robohash
13from ivatar.robohash_optimized import OptimizedRobohash, create_optimized_robohash
14from ivatar.utils import generate_random_email
17class RobohashOptimizationTestCase(TestCase):
18 """Test cases for robohash optimization"""
20 def setUp(self):
21 """Set up test data"""
22 self.test_emails = [generate_random_email() for _ in range(5)]
23 self.test_digests = [
24 hashlib.md5(email.encode()).hexdigest() for email in self.test_emails
25 ]
26 self.test_digests.extend(
27 [
28 "5d41402abc4b2a76b9719d911017c592",
29 "098f6bcd4621d373cade4e832627b4f6",
30 ]
31 )
33 def test_optimized_robohash_functionality(self):
34 """Test that optimized robohash functionality works correctly"""
35 digest = self.test_digests[0]
36 optimized = OptimizedRobohash(digest)
37 optimized.assemble_fast(roboset="any", sizex=256, sizey=256)
39 self.assertIsNotNone(optimized.img)
40 self.assertEqual(optimized.img.size, (256, 256))
41 self.assertIn(optimized.img.mode, ["RGBA", "RGB"])
43 data = BytesIO()
44 optimized.img.save(data, format="png")
45 self.assertGreater(len(data.getvalue()), 1000)
47 def test_identical_results(self):
48 """Test that optimized robohash returns identical results"""
49 digest = self.test_digests[0]
51 original = Robohash(digest)
52 original.assemble(roboset="any", sizex=256, sizey=256)
53 orig_data = BytesIO()
54 original.img.save(orig_data, format="png")
55 orig_bytes = orig_data.getvalue()
57 optimized = OptimizedRobohash(digest)
58 optimized.assemble_fast(roboset="any", sizex=256, sizey=256)
59 opt_data = BytesIO()
60 optimized.img.save(opt_data, format="png")
61 opt_bytes = opt_data.getvalue()
63 self.assertEqual(orig_bytes, opt_bytes, "Images should be identical")
65 def test_performance_improvement(self):
66 """Test that optimized robohash shows performance characteristics"""
67 digest = self.test_digests[0]
69 start_time = time.time()
70 original = Robohash(digest)
71 original.assemble(roboset="any", sizex=256, sizey=256)
72 original_time = (time.time() - start_time) * 1000
74 start_time = time.time()
75 optimized = OptimizedRobohash(digest)
76 optimized.assemble_fast(roboset="any", sizex=256, sizey=256)
77 optimized_time = (time.time() - start_time) * 1000
79 self.assertGreater(original_time, 0, "Original should take some time")
80 self.assertGreater(optimized_time, 0, "Optimized should take some time")
82 def test_integration_function(self):
83 """Test the create_optimized_robohash integration function"""
84 digest = self.test_digests[0]
85 data = create_optimized_robohash(digest, 256, "any")
87 self.assertIsInstance(data, BytesIO)
88 png_bytes = data.getvalue()
89 self.assertGreater(len(png_bytes), 1000)
91 img = Image.open(BytesIO(png_bytes))
92 self.assertEqual(img.size, (256, 256))
93 self.assertEqual(img.format, "PNG")
95 def test_cache_initialization(self):
96 """Test that directory cache is initialized correctly"""
97 digest = self.test_digests[0]
98 OptimizedRobohash(digest) # Initialize to trigger cache setup
100 self.assertTrue(OptimizedRobohash._cache_initialized)
101 self.assertIsInstance(OptimizedRobohash._directory_cache, dict)
103 def test_multiple_random_emails_identical_results(self):
104 """Test pixel-perfect identical results with multiple random email addresses"""
105 # Test with multiple random email addresses
106 for i, digest in enumerate(self.test_digests[:3]):
107 with self.subTest(email_index=i, digest=digest[:8]):
108 # Test with different configurations
109 test_cases = [
110 {"roboset": "any", "size": 128},
111 {"roboset": "set1", "size": 256},
112 {"roboset": "set2", "size": 64},
113 ]
115 for case in test_cases:
116 with self.subTest(case=case):
117 # Generate original
118 original = Robohash(digest)
119 original.assemble(
120 roboset=case["roboset"],
121 sizex=case["size"],
122 sizey=case["size"],
123 )
124 orig_data = BytesIO()
125 original.img.save(orig_data, format="png")
126 orig_bytes = orig_data.getvalue()
128 # Generate optimized
129 optimized = OptimizedRobohash(digest)
130 optimized.assemble_fast(
131 roboset=case["roboset"],
132 sizex=case["size"],
133 sizey=case["size"],
134 )
135 opt_data = BytesIO()
136 optimized.img.save(opt_data, format="png")
137 opt_bytes = opt_data.getvalue()
139 # Verify pixel-perfect identical
140 self.assertEqual(
141 orig_bytes,
142 opt_bytes,
143 f"Images not pixel-perfect identical for email {i}, "
144 f"digest {digest[:8]}..., {case['roboset']}, {case['size']}x{case['size']}",
145 )
147 def test_performance_improvement_multiple_cases(self):
148 """Test that optimized version is consistently faster across multiple cases"""
149 performance_results = []
151 # Test with multiple digests and configurations
152 test_cases = [
153 {"digest": self.test_digests[0], "roboset": "any", "size": 256},
154 {"digest": self.test_digests[1], "roboset": "set1", "size": 128},
155 {"digest": self.test_digests[2], "roboset": "set2", "size": 256},
156 ]
158 for case in test_cases:
159 # Measure original
160 start_time = time.time()
161 original = Robohash(case["digest"])
162 original.assemble(
163 roboset=case["roboset"], sizex=case["size"], sizey=case["size"]
164 )
165 original_time = (time.time() - start_time) * 1000
167 # Measure optimized
168 start_time = time.time()
169 optimized = OptimizedRobohash(case["digest"])
170 optimized.assemble_fast(
171 roboset=case["roboset"], sizex=case["size"], sizey=case["size"]
172 )
173 optimized_time = (time.time() - start_time) * 1000
175 performance_results.append(
176 {
177 "original": original_time,
178 "optimized": optimized_time,
179 "improvement": (
180 original_time / optimized_time if optimized_time > 0 else 0
181 ),
182 }
183 )
185 # Verify all cases show reasonable performance
186 for i, result in enumerate(performance_results):
187 with self.subTest(case_index=i):
188 self.assertGreater(
189 result["original"], 0, "Original should take measurable time"
190 )
191 self.assertGreater(
192 result["optimized"], 0, "Optimized should take measurable time"
193 )
194 # Allow for test environment variance - just ensure both complete successfully
195 self.assertLess(
196 result["optimized"],
197 10000,
198 "Optimized should complete in reasonable time",
199 )
201 def test_random_email_generation_and_processing(self):
202 """Test robohash with freshly generated random emails"""
203 # Generate fresh random emails for this test
204 fresh_emails = [generate_random_email() for _ in range(5)]
205 fresh_digests = [
206 hashlib.md5(email.encode()).hexdigest() for email in fresh_emails
207 ]
209 for i, (email, digest) in enumerate(zip(fresh_emails, fresh_digests)):
210 with self.subTest(email=email, digest=digest[:8]):
211 # Test that both original and optimized can process this email
212 original = Robohash(digest)
213 original.assemble(roboset="any", sizex=128, sizey=128)
215 optimized = OptimizedRobohash(digest)
216 optimized.assemble_fast(roboset="any", sizex=128, sizey=128)
218 # Verify both produce valid images
219 self.assertIsNotNone(original.img)
220 self.assertIsNotNone(optimized.img)
221 self.assertEqual(original.img.size, (128, 128))
222 self.assertEqual(optimized.img.size, (128, 128))
224 # Verify they produce identical results
225 orig_data = BytesIO()
226 original.img.save(orig_data, format="png")
227 orig_bytes = orig_data.getvalue()
229 opt_data = BytesIO()
230 optimized.img.save(opt_data, format="png")
231 opt_bytes = opt_data.getvalue()
233 self.assertEqual(
234 orig_bytes,
235 opt_bytes,
236 f"Random email {email} (digest {digest[:8]}...) produced different images",
237 )