Show More
@@ -53,116 +53,6 b' class TestMigration(object):' | |||||
53 | assert 1 == 1 |
|
53 | assert 1 == 1 | |
54 |
|
54 | |||
55 |
|
55 | |||
56 | class TestAPIReports_0_4_Validation(object): |
|
|||
57 | @pytest.mark.parametrize('dummy_json', ['', {}, [], None]) |
|
|||
58 | def test_no_payload(self, dummy_json): |
|
|||
59 | import colander |
|
|||
60 | from appenlight.validators import ReportListSchema_0_4 |
|
|||
61 | utcnow = datetime.utcnow() |
|
|||
62 | schema = ReportListSchema_0_4().bind(utcnow=utcnow) |
|
|||
63 | with pytest.raises(colander.Invalid): |
|
|||
64 | schema.deserialize(dummy_json) |
|
|||
65 |
|
||||
66 | def test_minimal_payload(self, report_04_schema): |
|
|||
67 | dummy_json = [{}] |
|
|||
68 | import colander |
|
|||
69 | from appenlight.validators import ReportListSchema_0_4 |
|
|||
70 | utcnow = datetime.utcnow() |
|
|||
71 | schema = ReportListSchema_0_4().bind(utcnow=utcnow) |
|
|||
72 | with pytest.raises(colander.Invalid): |
|
|||
73 | schema.deserialize(dummy_json) |
|
|||
74 |
|
||||
75 | def test_minimal_payload(self): |
|
|||
76 | from appenlight.validators import ReportListSchema_0_4 |
|
|||
77 | dummy_json = [{'report_details': [{}]}] |
|
|||
78 | utcnow = datetime.utcnow() |
|
|||
79 | schema = ReportListSchema_0_4().bind(utcnow=utcnow) |
|
|||
80 | deserialized = schema.deserialize(dummy_json) |
|
|||
81 |
|
||||
82 | expected_deserialization = [ |
|
|||
83 | {'error_type': '', |
|
|||
84 | 'language': 'unknown', |
|
|||
85 | 'report_details': [ |
|
|||
86 | {'username': '', |
|
|||
87 | 'traceback': None, |
|
|||
88 | 'extra': None, |
|
|||
89 | 'frameinfo': None, |
|
|||
90 | 'url': '', |
|
|||
91 | 'ip': None, |
|
|||
92 | 'start_time': utcnow, |
|
|||
93 | 'group_string': None, |
|
|||
94 | 'request': {}, |
|
|||
95 | 'request_stats': None, |
|
|||
96 | 'end_time': None, |
|
|||
97 | 'request_id': '', |
|
|||
98 | 'message': '', |
|
|||
99 | 'slow_calls': [], |
|
|||
100 | 'user_agent': ''}], |
|
|||
101 | 'server': 'unknown', |
|
|||
102 | 'occurences': 1, |
|
|||
103 | 'priority': 5, |
|
|||
104 | 'view_name': '', |
|
|||
105 | 'client': 'unknown', |
|
|||
106 | 'http_status': 200, |
|
|||
107 | 'error': '', |
|
|||
108 | 'tags': None} |
|
|||
109 | ] |
|
|||
110 | assert deserialized == expected_deserialization |
|
|||
111 |
|
||||
112 | def test_full_payload(self): |
|
|||
113 | import appenlight.tests.payload_examples as payload_examples |
|
|||
114 | from appenlight.validators import ReportListSchema_0_4 |
|
|||
115 | utcnow = datetime.utcnow() |
|
|||
116 | schema = ReportListSchema_0_4().bind(utcnow=utcnow) |
|
|||
117 | PYTHON_PAYLOAD = copy.deepcopy(payload_examples.PYTHON_PAYLOAD_0_4) |
|
|||
118 | utcnow = datetime.utcnow() |
|
|||
119 | PYTHON_PAYLOAD["tags"] = [("foo", 1), ("action", "test"), ("baz", 1.1), |
|
|||
120 | ("date", |
|
|||
121 | utcnow.strftime('%Y-%m-%dT%H:%M:%S.0'))] |
|
|||
122 | dummy_json = [PYTHON_PAYLOAD] |
|
|||
123 |
|
||||
124 | deserialized = schema.deserialize(dummy_json) |
|
|||
125 | assert deserialized[0]['error'] == PYTHON_PAYLOAD['error'] |
|
|||
126 | assert deserialized[0]['language'] == PYTHON_PAYLOAD['language'] |
|
|||
127 | assert deserialized[0]['server'] == PYTHON_PAYLOAD['server'] |
|
|||
128 | assert deserialized[0]['priority'] == PYTHON_PAYLOAD['priority'] |
|
|||
129 | assert deserialized[0]['view_name'] == PYTHON_PAYLOAD['view_name'] |
|
|||
130 | assert deserialized[0]['client'] == PYTHON_PAYLOAD['client'] |
|
|||
131 | assert deserialized[0]['http_status'] == PYTHON_PAYLOAD['http_status'] |
|
|||
132 | assert deserialized[0]['error'] == PYTHON_PAYLOAD['error'] |
|
|||
133 | assert deserialized[0]['occurences'] == PYTHON_PAYLOAD['occurences'] |
|
|||
134 | first_detail = deserialized[0]['report_details'][0] |
|
|||
135 | payload_detail = PYTHON_PAYLOAD['report_details'][0] |
|
|||
136 | assert first_detail['username'] == payload_detail['username'] |
|
|||
137 | assert first_detail['traceback'] == payload_detail['traceback'] |
|
|||
138 | assert first_detail['url'] == payload_detail['url'] |
|
|||
139 | assert first_detail['ip'] == payload_detail['ip'] |
|
|||
140 | assert first_detail['start_time'].strftime('%Y-%m-%dT%H:%M:%S.0') == \ |
|
|||
141 | payload_detail['start_time'] |
|
|||
142 | assert first_detail['ip'] == payload_detail['ip'] |
|
|||
143 | assert first_detail['group_string'] is None |
|
|||
144 | assert first_detail['request_stats'] == payload_detail['request_stats'] |
|
|||
145 | assert first_detail['end_time'].strftime('%Y-%m-%dT%H:%M:%S.0') == \ |
|
|||
146 | payload_detail['end_time'] |
|
|||
147 | assert first_detail['request_id'] == payload_detail['request_id'] |
|
|||
148 | assert first_detail['message'] == payload_detail['message'] |
|
|||
149 | assert first_detail['user_agent'] == payload_detail['user_agent'] |
|
|||
150 | slow_call = first_detail['slow_calls'][0] |
|
|||
151 | expected_slow_call = payload_detail['slow_calls'][0] |
|
|||
152 | assert slow_call['start'].strftime('%Y-%m-%dT%H:%M:%S.0') == \ |
|
|||
153 | expected_slow_call['start'] |
|
|||
154 | assert slow_call['end'].strftime('%Y-%m-%dT%H:%M:%S.0') == \ |
|
|||
155 | expected_slow_call['end'] |
|
|||
156 | assert slow_call['statement'] == expected_slow_call['statement'] |
|
|||
157 | assert slow_call['parameters'] == expected_slow_call['parameters'] |
|
|||
158 | assert slow_call['type'] == expected_slow_call['type'] |
|
|||
159 | assert slow_call['subtype'] == expected_slow_call['subtype'] |
|
|||
160 | assert slow_call['location'] == '' |
|
|||
161 | assert deserialized[0]['tags'] == [ |
|
|||
162 | ('foo', 1), ('action', 'test'), |
|
|||
163 | ('baz', 1.1), ('date', utcnow.strftime('%Y-%m-%dT%H:%M:%S.0'))] |
|
|||
164 |
|
||||
165 |
|
||||
166 | class TestSentryProto_7(object): |
|
56 | class TestSentryProto_7(object): | |
167 | def test_log_payload(self): |
|
57 | def test_log_payload(self): | |
168 | import appenlight.tests.payload_examples as payload_examples |
|
58 | import appenlight.tests.payload_examples as payload_examples | |
@@ -461,11 +351,11 b' class TestAPIGeneralMetricsValidation(object):' | |||||
461 | general_metrics_schema.deserialize(dummy_json) |
|
351 | general_metrics_schema.deserialize(dummy_json) | |
462 |
|
352 | |||
463 | def test_minimal_payload(self, general_metrics_schema): |
|
353 | def test_minimal_payload(self, general_metrics_schema): | |
464 | dummy_json = [{}] |
|
354 | dummy_json = [{'tags': [['counter_a', 15.5], ['counter_b', 63]]}] | |
465 | deserialized = general_metrics_schema.deserialize(dummy_json)[0] |
|
355 | deserialized = general_metrics_schema.deserialize(dummy_json)[0] | |
466 | expected = {'namespace': '', |
|
356 | expected = {'namespace': '', | |
467 | 'server_name': 'unknown', |
|
357 | 'server_name': 'unknown', | |
468 |
'tags': |
|
358 | 'tags': [('counter_a', 15.5), ('counter_b', 63)], | |
469 | 'timestamp': datetime.utcnow()} |
|
359 | 'timestamp': datetime.utcnow()} | |
470 | assert deserialized['namespace'] == expected['namespace'] |
|
360 | assert deserialized['namespace'] == expected['namespace'] | |
471 | assert deserialized['server_name'] == expected['server_name'] |
|
361 | assert deserialized['server_name'] == expected['server_name'] |
@@ -192,17 +192,20 b' class SlowCallSchema(colander.MappingSchema):' | |||||
192 |
|
192 | |||
193 | def limited_date(node, value): |
|
193 | def limited_date(node, value): | |
194 | """ checks to make sure that the value is not older/newer than 2h """ |
|
194 | """ checks to make sure that the value is not older/newer than 2h """ | |
195 | hours = 2 |
|
195 | past_hours = 72 | |
196 | min_time = datetime.datetime.utcnow() - datetime.timedelta(hours=72) |
|
196 | future_hours = 2 | |
197 |
m |
|
197 | min_time = datetime.datetime.utcnow() - datetime.timedelta( | |
|
198 | hours=past_hours) | |||
|
199 | max_time = datetime.datetime.utcnow() + datetime.timedelta( | |||
|
200 | hours=future_hours) | |||
198 | if min_time > value: |
|
201 | if min_time > value: | |
199 |
msg = '%r is older from current UTC time by ' + str(hours) |
|
202 | msg = '%r is older from current UTC time by ' + str(past_hours) | |
200 | msg += ' Ask administrator to enable permanent logging for ' \ |
|
203 | msg += ' hours. Ask administrator to enable permanent logging for ' \ | |
201 | 'your application to store logs with dates in past.' |
|
204 | 'your application to store logs with dates in past.' | |
202 | raise colander.Invalid(node, msg % value) |
|
205 | raise colander.Invalid(node, msg % value) | |
203 | if max_time < value: |
|
206 | if max_time < value: | |
204 |
msg = '%r is newer from current UTC time by ' + str(hours) |
|
207 | msg = '%r is newer from current UTC time by ' + str(future_hours) | |
205 | msg += ' Ask administrator to enable permanent logging for ' \ |
|
208 | msg += ' hours. Ask administrator to enable permanent logging for ' \ | |
206 | 'your application to store logs with dates in future.' |
|
209 | 'your application to store logs with dates in future.' | |
207 | raise colander.Invalid(node, msg % value) |
|
210 | raise colander.Invalid(node, msg % value) | |
208 |
|
211 | |||
@@ -311,20 +314,13 b' class ReportDetailBaseSchema(colander.MappingSchema):' | |||||
311 | extra = ExtraSchemaList() |
|
314 | extra = ExtraSchemaList() | |
312 |
|
315 | |||
313 |
|
316 | |||
314 | class ReportDetailSchema_0_4(ReportDetailBaseSchema): |
|
|||
315 | frameinfo = FrameInfoListSchema(missing=None) |
|
|||
316 |
|
||||
317 |
|
||||
318 | class ReportDetailSchema_0_5(ReportDetailBaseSchema): |
|
317 | class ReportDetailSchema_0_5(ReportDetailBaseSchema): | |
319 | pass |
|
318 | pass | |
320 |
|
319 | |||
321 |
|
320 | |||
322 |
class ReportDetail |
|
321 | class ReportDetailSchemaPermissiveDate_0_5(ReportDetailSchema_0_5): | |
323 | """ |
|
322 | start_time = colander.SchemaNode(NonTZDate(), missing=deferred_utcnow) | |
324 | Validates format of list of reports |
|
323 | end_time = colander.SchemaNode(NonTZDate(), missing=None) | |
325 | """ |
|
|||
326 | report_detail = ReportDetailSchema_0_4() |
|
|||
327 | validator = colander.Length(1) |
|
|||
328 |
|
324 | |||
329 |
|
325 | |||
330 | class ReportSchemaBase(colander.MappingSchema): |
|
326 | class ReportSchemaBase(colander.MappingSchema): | |
@@ -364,6 +360,11 b' class ReportSchema_0_5(ReportSchemaBase, ReportDetailSchema_0_5):' | |||||
364 | pass |
|
360 | pass | |
365 |
|
361 | |||
366 |
|
362 | |||
|
363 | class ReportSchemaPermissiveDate_0_5(ReportSchemaBase, | |||
|
364 | ReportDetailSchemaPermissiveDate_0_5): | |||
|
365 | pass | |||
|
366 | ||||
|
367 | ||||
367 | class ReportListSchema_0_5(colander.SequenceSchema): |
|
368 | class ReportListSchema_0_5(colander.SequenceSchema): | |
368 | """ |
|
369 | """ | |
369 | Validates format of list of report groups |
|
370 | Validates format of list of report groups | |
@@ -372,6 +373,14 b' class ReportListSchema_0_5(colander.SequenceSchema):' | |||||
372 | validator = colander.Length(1) |
|
373 | validator = colander.Length(1) | |
373 |
|
374 | |||
374 |
|
375 | |||
|
376 | class ReportListPermissiveDateSchema_0_5(colander.SequenceSchema): | |||
|
377 | """ | |||
|
378 | Validates format of list of report groups | |||
|
379 | """ | |||
|
380 | report = ReportSchemaPermissiveDate_0_5() | |||
|
381 | validator = colander.Length(1) | |||
|
382 | ||||
|
383 | ||||
375 | class LogSchema(colander.MappingSchema): |
|
384 | class LogSchema(colander.MappingSchema): | |
376 | """ |
|
385 | """ | |
377 | Validates format if individual log entry |
|
386 | Validates format if individual log entry |
@@ -405,7 +405,12 b' def sentry_compat(request):' | |||||
405 | event, event_type = parse_sentry_event(json_body) |
|
405 | event, event_type = parse_sentry_event(json_body) | |
406 |
|
406 | |||
407 | if event_type == ParsedSentryEventType.LOG: |
|
407 | if event_type == ParsedSentryEventType.LOG: | |
408 | schema = LogSchema().bind(utcnow=datetime.datetime.utcnow()) |
|
408 | if application.allow_permanent_storage: | |
|
409 | schema = LogSchemaPermanent().bind( | |||
|
410 | utcnow=datetime.datetime.utcnow()) | |||
|
411 | else: | |||
|
412 | schema = LogSchema().bind( | |||
|
413 | utcnow=datetime.datetime.utcnow()) | |||
409 | deserialized_logs = schema.deserialize(event) |
|
414 | deserialized_logs = schema.deserialize(event) | |
410 | non_pkey_logs = [deserialized_logs] |
|
415 | non_pkey_logs = [deserialized_logs] | |
411 | log.debug('%s non-pkey logs received: %s' % (application, |
|
416 | log.debug('%s non-pkey logs received: %s' % (application, |
General Comments 0
You need to be logged in to leave comments.
Login now