1+ import mock
2+
13from sentry_sdk import capture_message , start_transaction
24from sentry_sdk .integrations .redis import RedisIntegration
35
@@ -37,7 +39,6 @@ def test_redis_pipeline(sentry_init, capture_events, is_transaction):
3739
3840 connection = FakeStrictRedis ()
3941 with start_transaction ():
40-
4142 pipeline = connection .pipeline (transaction = is_transaction )
4243 pipeline .get ("foo" )
4344 pipeline .set ("bar" , 1 )
@@ -58,3 +59,166 @@ def test_redis_pipeline(sentry_init, capture_events, is_transaction):
5859 "redis.transaction" : is_transaction ,
5960 "redis.is_cluster" : False ,
6061 }
62+
63+
64+ def test_sensitive_data (sentry_init , capture_events ):
65+ # fakeredis does not support the AUTH command, so we need to mock it
66+ with mock .patch (
67+ "sentry_sdk.integrations.redis._COMMANDS_INCLUDING_SENSITIVE_DATA" , ["get" ]
68+ ):
69+ sentry_init (
70+ integrations = [RedisIntegration ()],
71+ traces_sample_rate = 1.0 ,
72+ send_default_pii = True ,
73+ )
74+ events = capture_events ()
75+
76+ connection = FakeStrictRedis ()
77+ with start_transaction ():
78+ connection .get (
79+ "this is super secret"
80+ ) # because fakeredis does not support AUTH we use GET instead
81+
82+ (event ,) = events
83+ spans = event ["spans" ]
84+ assert spans [0 ]["op" ] == "db.redis"
85+ assert spans [0 ]["description" ] == "GET [Filtered]"
86+
87+
88+ def test_pii_data_redacted (sentry_init , capture_events ):
89+ sentry_init (
90+ integrations = [RedisIntegration ()],
91+ traces_sample_rate = 1.0 ,
92+ )
93+ events = capture_events ()
94+
95+ connection = FakeStrictRedis ()
96+ with start_transaction ():
97+ connection .set ("somekey1" , "my secret string1" )
98+ connection .set ("somekey2" , "my secret string2" )
99+ connection .get ("somekey2" )
100+ connection .delete ("somekey1" , "somekey2" )
101+
102+ (event ,) = events
103+ spans = event ["spans" ]
104+ assert spans [0 ]["op" ] == "db.redis"
105+ assert spans [0 ]["description" ] == "SET 'somekey1' [Filtered]"
106+ assert spans [1 ]["description" ] == "SET 'somekey2' [Filtered]"
107+ assert spans [2 ]["description" ] == "GET 'somekey2'"
108+ assert spans [3 ]["description" ] == "DEL 'somekey1' [Filtered]"
109+
110+
111+ def test_pii_data_sent (sentry_init , capture_events ):
112+ sentry_init (
113+ integrations = [RedisIntegration ()],
114+ traces_sample_rate = 1.0 ,
115+ send_default_pii = True ,
116+ )
117+ events = capture_events ()
118+
119+ connection = FakeStrictRedis ()
120+ with start_transaction ():
121+ connection .set ("somekey1" , "my secret string1" )
122+ connection .set ("somekey2" , "my secret string2" )
123+ connection .get ("somekey2" )
124+ connection .delete ("somekey1" , "somekey2" )
125+
126+ (event ,) = events
127+ spans = event ["spans" ]
128+ assert spans [0 ]["op" ] == "db.redis"
129+ assert spans [0 ]["description" ] == "SET 'somekey1' 'my secret string1'"
130+ assert spans [1 ]["description" ] == "SET 'somekey2' 'my secret string2'"
131+ assert spans [2 ]["description" ] == "GET 'somekey2'"
132+ assert spans [3 ]["description" ] == "DEL 'somekey1' 'somekey2'"
133+
134+
135+ def test_data_truncation (sentry_init , capture_events ):
136+ sentry_init (
137+ integrations = [RedisIntegration ()],
138+ traces_sample_rate = 1.0 ,
139+ send_default_pii = True ,
140+ )
141+ events = capture_events ()
142+
143+ connection = FakeStrictRedis ()
144+ with start_transaction ():
145+ long_string = "a" * 100000
146+ connection .set ("somekey1" , long_string )
147+ short_string = "b" * 10
148+ connection .set ("somekey2" , short_string )
149+
150+ (event ,) = events
151+ spans = event ["spans" ]
152+ assert spans [0 ]["op" ] == "db.redis"
153+ assert spans [0 ]["description" ] == "SET 'somekey1' '%s..." % (
154+ long_string [: 1024 - len ("..." ) - len ("SET 'somekey1' '" )],
155+ )
156+ assert spans [1 ]["description" ] == "SET 'somekey2' '%s'" % (short_string ,)
157+
158+
159+ def test_data_truncation_custom (sentry_init , capture_events ):
160+ sentry_init (
161+ integrations = [RedisIntegration (max_data_size = 30 )],
162+ traces_sample_rate = 1.0 ,
163+ send_default_pii = True ,
164+ )
165+ events = capture_events ()
166+
167+ connection = FakeStrictRedis ()
168+ with start_transaction ():
169+ long_string = "a" * 100000
170+ connection .set ("somekey1" , long_string )
171+ short_string = "b" * 10
172+ connection .set ("somekey2" , short_string )
173+
174+ (event ,) = events
175+ spans = event ["spans" ]
176+ assert spans [0 ]["op" ] == "db.redis"
177+ assert spans [0 ]["description" ] == "SET 'somekey1' '%s..." % (
178+ long_string [: 30 - len ("..." ) - len ("SET 'somekey1' '" )],
179+ )
180+ assert spans [1 ]["description" ] == "SET 'somekey2' '%s'" % (short_string ,)
181+
182+
183+ def test_breadcrumbs (sentry_init , capture_events ):
184+
185+ sentry_init (
186+ integrations = [RedisIntegration (max_data_size = 30 )],
187+ send_default_pii = True ,
188+ )
189+ events = capture_events ()
190+
191+ connection = FakeStrictRedis ()
192+
193+ long_string = "a" * 100000
194+ connection .set ("somekey1" , long_string )
195+ short_string = "b" * 10
196+ connection .set ("somekey2" , short_string )
197+
198+ capture_message ("hi" )
199+
200+ (event ,) = events
201+ crumbs = event ["breadcrumbs" ]["values" ]
202+
203+ assert crumbs [0 ] == {
204+ "message" : "SET 'somekey1' 'aaaaaaaaaaa..." ,
205+ "type" : "redis" ,
206+ "category" : "redis" ,
207+ "data" : {
208+ "redis.is_cluster" : False ,
209+ "redis.command" : "SET" ,
210+ "redis.key" : "somekey1" ,
211+ },
212+ "timestamp" : crumbs [0 ]["timestamp" ],
213+ }
214+ assert crumbs [1 ] == {
215+ "message" : "SET 'somekey2' 'bbbbbbbbbb'" ,
216+ "type" : "redis" ,
217+ "category" : "redis" ,
218+ "data" : {
219+ "redis.is_cluster" : False ,
220+ "redis.command" : "SET" ,
221+ "redis.key" : "somekey2" ,
222+ },
223+ "timestamp" : crumbs [1 ]["timestamp" ],
224+ }
0 commit comments