• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#
2# This file is part of pyasn1-modules software.
3#
4# Created by Russ Housley
5# Copyright (c) 2019, Vigil Security, LLC
6# License: http://snmplabs.com/pyasn1/license.html
7#
8
9import sys
10
11from pyasn1.codec.der.decoder import decode as der_decode
12from pyasn1.codec.der.encoder import encode as der_encode
13
14from pyasn1_modules import pem
15from pyasn1_modules import rfc5652
16from pyasn1_modules import rfc8358
17
18try:
19    import unittest2 as unittest
20except ImportError:
21    import unittest
22
23
24class P7STestCase(unittest.TestCase):
25    pem_text_list = (
26"""\
27MIIJWgYJKoZIhvcNAQcCoIIJSzCCCUcCAQMxDTALBglghkgBZQMEAgEwDQYLKoZIhvcNAQkQ
28ARugggZ0MIIGcDCCBVigAwIBAgIRANa58hQvZ26svTWQaGtqo/YwDQYJKoZIhvcNAQELBQAw
29gZcxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcT
30B1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMT0wOwYDVQQDEzRDT01PRE8g
31UlNBIENsaWVudCBBdXRoZW50aWNhdGlvbiBhbmQgU2VjdXJlIEVtYWlsIENBMB4XDTE1MDIx
32MjAwMDAwMFoXDTIwMDIxMjIzNTk1OVowgZUxCzAJBgNVBAYTAlVTMREwDwYDVQQIEwhWaXJn
33aW5pYTEPMA0GA1UEBxMGUmVzdG9uMRMwEQYDVQQKEwpJRVRGIFRydXN0MRkwFwYDVQQLExBT
34ZWNyZXRhcmlhdCBXZXN0MQ0wCwYDVQQDEwRJRVRGMSMwIQYJKoZIhvcNAQkBFhRpZXRmLWFj
35dGlvbkBpZXRmLm9yZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMUkKtMPP1RA
36FU6sxMezYJKCt4rw30RDieB8/P67TMhA6j8Um4a2Xo+CP9Ce1oMri2bwaaQPYWB4ciEL32za
370NUE0B0iCjZZl36hon6wW6mJw1NGD/AFxnKWzhkSWG6BHMoeOAzu/ye8sHu4Jp5nazpGptK7
3830SjTS3JJFU9pHwQY6JlcmwVv0j2rsT3gj92Cbj5S+U5wCSE6+mZbCC+VPFeeI1kFITwyaIm
39uK9kSYHr15OXua/jrYNrHNRfqtexGKSgnUT96KkTh9TVvkMETB1WJS4WuEIP6GITvwVTp0lA
40qS3oNO4SM4tgFVdYqppcvZBg52kHY9y7IdR156c99zzZDBfWBduqjs/AXa0uol0EJd7qFLUs
41xEJ96XN3tPgR/Cwq18ec29pZQH6kO81Kato/RsQrj6A05TFx/J0MYE0R1MZqvIDUu55vlicb
42wT2lpXMiz1szKuvjTZRR9H/IgbKPNpt/kDUSgXLYwuKBm+nBoJXgybEyJ+A4arb60d9Uiusu
43UA8/h6s1rDMuTnIYMbIii4Y+KgevBWPawqk0xioilEMJ0RBaBVrDreuFlK8aYh+Jo2piruBA
44QnB9ZaPmEM1HPNArJxqL6XcUJTkFxNSksOATDFV5sEoBWYIe6qv2nV2r/HWDAEaa4WH2h3o/
45kASarXk3SxPXmfjOOr1XgpKjAgMBAAGjggG1MIIBsTAfBgNVHSMEGDAWgBSCr2yM+MX+lmF8
466B89K3FIXsSLwDAdBgNVHQ4EFgQU7Olc92Oy6nkCvpv6jCj6qN8YPtUwDgYDVR0PAQH/BAQD
47AgeAMAwGA1UdEwEB/wQCMAAwRgYDVR0gBD8wPTA7BgwrBgEEAbIxAQIBAwUwKzApBggrBgEF
48BQcCARYdaHR0cHM6Ly9zZWN1cmUuY29tb2RvLmNvbS9DUFMwWgYDVR0fBFMwUTBPoE2gS4ZJ
49aHR0cDovL2NybC5jb21vZG9jYS5jb20vQ09NT0RPUlNBQ2xpZW50QXV0aGVudGljYXRpb25h
50bmRTZWN1cmVFbWFpbENBLmNybDCBiwYIKwYBBQUHAQEEfzB9MFUGCCsGAQUFBzAChklodHRw
51Oi8vY3J0LmNvbW9kb2NhLmNvbS9DT01PRE9SU0FDbGllbnRBdXRoZW50aWNhdGlvbmFuZFNl
52Y3VyZUVtYWlsQ0EuY3J0MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21vZG9jYS5jb20w
53HwYDVR0RBBgwFoEUaWV0Zi1hY3Rpb25AaWV0Zi5vcmcwDQYJKoZIhvcNAQELBQADggEBAGPm
54QUKHxkEQ9vk69vIP68anHc8UsTv5powtLSXLqUw3rAoKAdoWkKjb7ZByHCuFiNk1BvTnhQPh
55LAZm5dI8dYWKp3zgWVxsCXOQv2K4XbaQpIk8KKdLycHWsOq2OD4xBdhfTQqDj9EidhxaLf4B
56bRUePOuWVvwNqHI6OQ9FbRllUsTsSH3XK7z9Ru/0Ub07uEzmWyrIpeFRLJUg9EqQj25pw8j7
57N9ym8ItpfEQvK4Nrzt9KnGwFDaNOUjYAvejig9iUNdOXEQKVzbq8fC25HrXPQisq8u2jrP38
58cRqzwgGHZ1bJrQa8+LPBfADZ4ZHeqlEe6IqZhS/wDSuDNCIZHtkxggKqMIICpgIBA4AU7Olc
5992Oy6nkCvpv6jCj6qN8YPtUwCwYJYIZIAWUDBAIBoGswGgYJKoZIhvcNAQkDMQ0GCyqGSIb3
60DQEJEAEbMBwGCSqGSIb3DQEJBTEPFw0xOTA2MDkxNjU3NTdaMC8GCSqGSIb3DQEJBDEiBCDx
61ACvH9u26K1BdX+IPp6vguUAtA9k0lp9JMNunvXTuQzANBgkqhkiG9w0BAQEFAASCAgBY8kFl
62SxQIvU4n6LaVoAV6ibHrlCqOp9KrUc9DmwXtDifsgoGfhDHb6i5k9BSHmerjTGF6mLlquPUV
63Z2EHSUuVpk8rX//ki6vngq91+f+ufrzEpvO6BLc2aO/zOat0W3U2hiq3zJSLMYMNZhX484Nq
649+ImsU0S5f32ZpEXH0lFINUaZFo0eRAOZywqNuY57stjWBxTI6MA00S0+eMuWlmkMy0C2LL9
65BQvWW01/ri2UDEprAiKo2sXLcScgHimEVYHuWsrnP+sJ3XVWRsWGRW2i5qIalu2ZGmmIU/vg
66bdBzQnAjCoS2xC5Kwv+cqtUiiyLI0nnuu1aKKi4hivmt1n+hSIWWgGNwTFn3S4+mYDDNSH0u
67ocOr0uDFVv/SH9QPQuGh9rpSz3cd3hlA4R63Rylm46Tt6DnXiovu0mDoos68UQjIAPXWj1ES
68Peeubp+wSbuqN8Rh+koZU+HK7YpsR2bB4hL0GIwMA9lQjGSCxPCt1ViRL6zAWECzQC1YgLyc
69+f1Fe8pkaWUbZz+18H/rJoKsXiNWH8yhfAyk+JGTxc4qxWJ/BuF0vzSyuVEffuxIHrOMZTpO
70+xfAaJVDqFjxT5yKj3dCfy6XSDZq39AeX/w26/WfH+0ALRiViAAaMHSldbawVR/W3isecDWF
71tlU4NSJMLi/tTohe0QN1fjOaFryAvw==
72""",
73"""\
74MIIJWgYJKoZIhvcNAQcCoIIJSzCCCUcCAQMxDTALBglghkgBZQMEAgEwDQYLKoZIhvcNAQkQ
75ARygggZ0MIIGcDCCBVigAwIBAgIRANa58hQvZ26svTWQaGtqo/YwDQYJKoZIhvcNAQELBQAw
76gZcxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcT
77B1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMT0wOwYDVQQDEzRDT01PRE8g
78UlNBIENsaWVudCBBdXRoZW50aWNhdGlvbiBhbmQgU2VjdXJlIEVtYWlsIENBMB4XDTE1MDIx
79MjAwMDAwMFoXDTIwMDIxMjIzNTk1OVowgZUxCzAJBgNVBAYTAlVTMREwDwYDVQQIEwhWaXJn
80aW5pYTEPMA0GA1UEBxMGUmVzdG9uMRMwEQYDVQQKEwpJRVRGIFRydXN0MRkwFwYDVQQLExBT
81ZWNyZXRhcmlhdCBXZXN0MQ0wCwYDVQQDEwRJRVRGMSMwIQYJKoZIhvcNAQkBFhRpZXRmLWFj
82dGlvbkBpZXRmLm9yZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMUkKtMPP1RA
83FU6sxMezYJKCt4rw30RDieB8/P67TMhA6j8Um4a2Xo+CP9Ce1oMri2bwaaQPYWB4ciEL32za
840NUE0B0iCjZZl36hon6wW6mJw1NGD/AFxnKWzhkSWG6BHMoeOAzu/ye8sHu4Jp5nazpGptK7
8530SjTS3JJFU9pHwQY6JlcmwVv0j2rsT3gj92Cbj5S+U5wCSE6+mZbCC+VPFeeI1kFITwyaIm
86uK9kSYHr15OXua/jrYNrHNRfqtexGKSgnUT96KkTh9TVvkMETB1WJS4WuEIP6GITvwVTp0lA
87qS3oNO4SM4tgFVdYqppcvZBg52kHY9y7IdR156c99zzZDBfWBduqjs/AXa0uol0EJd7qFLUs
88xEJ96XN3tPgR/Cwq18ec29pZQH6kO81Kato/RsQrj6A05TFx/J0MYE0R1MZqvIDUu55vlicb
89wT2lpXMiz1szKuvjTZRR9H/IgbKPNpt/kDUSgXLYwuKBm+nBoJXgybEyJ+A4arb60d9Uiusu
90UA8/h6s1rDMuTnIYMbIii4Y+KgevBWPawqk0xioilEMJ0RBaBVrDreuFlK8aYh+Jo2piruBA
91QnB9ZaPmEM1HPNArJxqL6XcUJTkFxNSksOATDFV5sEoBWYIe6qv2nV2r/HWDAEaa4WH2h3o/
92kASarXk3SxPXmfjOOr1XgpKjAgMBAAGjggG1MIIBsTAfBgNVHSMEGDAWgBSCr2yM+MX+lmF8
936B89K3FIXsSLwDAdBgNVHQ4EFgQU7Olc92Oy6nkCvpv6jCj6qN8YPtUwDgYDVR0PAQH/BAQD
94AgeAMAwGA1UdEwEB/wQCMAAwRgYDVR0gBD8wPTA7BgwrBgEEAbIxAQIBAwUwKzApBggrBgEF
95BQcCARYdaHR0cHM6Ly9zZWN1cmUuY29tb2RvLmNvbS9DUFMwWgYDVR0fBFMwUTBPoE2gS4ZJ
96aHR0cDovL2NybC5jb21vZG9jYS5jb20vQ09NT0RPUlNBQ2xpZW50QXV0aGVudGljYXRpb25h
97bmRTZWN1cmVFbWFpbENBLmNybDCBiwYIKwYBBQUHAQEEfzB9MFUGCCsGAQUFBzAChklodHRw
98Oi8vY3J0LmNvbW9kb2NhLmNvbS9DT01PRE9SU0FDbGllbnRBdXRoZW50aWNhdGlvbmFuZFNl
99Y3VyZUVtYWlsQ0EuY3J0MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21vZG9jYS5jb20w
100HwYDVR0RBBgwFoEUaWV0Zi1hY3Rpb25AaWV0Zi5vcmcwDQYJKoZIhvcNAQELBQADggEBAGPm
101QUKHxkEQ9vk69vIP68anHc8UsTv5powtLSXLqUw3rAoKAdoWkKjb7ZByHCuFiNk1BvTnhQPh
102LAZm5dI8dYWKp3zgWVxsCXOQv2K4XbaQpIk8KKdLycHWsOq2OD4xBdhfTQqDj9EidhxaLf4B
103bRUePOuWVvwNqHI6OQ9FbRllUsTsSH3XK7z9Ru/0Ub07uEzmWyrIpeFRLJUg9EqQj25pw8j7
104N9ym8ItpfEQvK4Nrzt9KnGwFDaNOUjYAvejig9iUNdOXEQKVzbq8fC25HrXPQisq8u2jrP38
105cRqzwgGHZ1bJrQa8+LPBfADZ4ZHeqlEe6IqZhS/wDSuDNCIZHtkxggKqMIICpgIBA4AU7Olc
10692Oy6nkCvpv6jCj6qN8YPtUwCwYJYIZIAWUDBAIBoGswGgYJKoZIhvcNAQkDMQ0GCyqGSIb3
107DQEJEAEcMBwGCSqGSIb3DQEJBTEPFw0xOTA2MDkxNjU3NTdaMC8GCSqGSIb3DQEJBDEiBCBg
108ifxBsUb2E8RicFvqZB+NJEs1FOG4hFFU1bPqV2UwGzANBgkqhkiG9w0BAQEFAASCAgCApFAS
1094+cYrnkMebrANXw7/TGn6Qx01p9fuOugQb6lcfE5CysIKGLJJogs0BXwHK4jTeJRdt/lutuz
110bACg1bakABxuCiLWMu3pKCKS94qAgElYgWru+pAxPhuslz5MwAU0qFW3KnaNq3f5wXlVQ+h2
111l9spSiLhAQ+vLTLfotn6tCmUfjaaYsoNIUGg6b/2vH75QGYaXDq9YGoCrrkDbaRS4eDenSL5
112S2fBTZ5VMJE/1VQY1D5CWqt2CTfzRkNkU7mkarPy6SPvguDlqKJJnFaZJmeIYbGOpDt6KxWc
113DLFD9+J6CH492QwlHxDtM94nK1oIaqdu9TTV94t0ToGezElOZZuVA2DVkov5DzrYQLI5GjMw
1147iHXW1ewCaGF38DdOopqBYp7jcCCZpruKBWDq/uz40MzSBrffYTP/dg4//8Awvt/JomvTUoH
115E18Pt/G2cqdw0NqOE7YEcFpsLGfikTWmGhnrcYUkt8odDDAv/vqZRt8DLkB56waQeQw0TLit
1162M3gbTSHJ1KFsBM/kqHanVapGtnClkY7hYh8DVpgJymJpupkNFs8lDNbN4C42DhQ6Oz9P2qu
1178a/ybEb5gMZ3fsVLvvp6LhbJfqIvYgZO2uKXeKg3eLASD5nVY/Tuhnn2plhx+weKULGys0Ov
118zPKZ+N96KLerIBr3FmGByqhr3jNrBw==
119""",
120"""\
121MIIJWgYJKoZIhvcNAQcCoIIJSzCCCUcCAQMxDTALBglghkgBZQMEAgEwDQYLKoZIhvcNAQkQ
122AR2gggZ0MIIGcDCCBVigAwIBAgIRANa58hQvZ26svTWQaGtqo/YwDQYJKoZIhvcNAQELBQAw
123gZcxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcT
124B1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMT0wOwYDVQQDEzRDT01PRE8g
125UlNBIENsaWVudCBBdXRoZW50aWNhdGlvbiBhbmQgU2VjdXJlIEVtYWlsIENBMB4XDTE1MDIx
126MjAwMDAwMFoXDTIwMDIxMjIzNTk1OVowgZUxCzAJBgNVBAYTAlVTMREwDwYDVQQIEwhWaXJn
127aW5pYTEPMA0GA1UEBxMGUmVzdG9uMRMwEQYDVQQKEwpJRVRGIFRydXN0MRkwFwYDVQQLExBT
128ZWNyZXRhcmlhdCBXZXN0MQ0wCwYDVQQDEwRJRVRGMSMwIQYJKoZIhvcNAQkBFhRpZXRmLWFj
129dGlvbkBpZXRmLm9yZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMUkKtMPP1RA
130FU6sxMezYJKCt4rw30RDieB8/P67TMhA6j8Um4a2Xo+CP9Ce1oMri2bwaaQPYWB4ciEL32za
1310NUE0B0iCjZZl36hon6wW6mJw1NGD/AFxnKWzhkSWG6BHMoeOAzu/ye8sHu4Jp5nazpGptK7
13230SjTS3JJFU9pHwQY6JlcmwVv0j2rsT3gj92Cbj5S+U5wCSE6+mZbCC+VPFeeI1kFITwyaIm
133uK9kSYHr15OXua/jrYNrHNRfqtexGKSgnUT96KkTh9TVvkMETB1WJS4WuEIP6GITvwVTp0lA
134qS3oNO4SM4tgFVdYqppcvZBg52kHY9y7IdR156c99zzZDBfWBduqjs/AXa0uol0EJd7qFLUs
135xEJ96XN3tPgR/Cwq18ec29pZQH6kO81Kato/RsQrj6A05TFx/J0MYE0R1MZqvIDUu55vlicb
136wT2lpXMiz1szKuvjTZRR9H/IgbKPNpt/kDUSgXLYwuKBm+nBoJXgybEyJ+A4arb60d9Uiusu
137UA8/h6s1rDMuTnIYMbIii4Y+KgevBWPawqk0xioilEMJ0RBaBVrDreuFlK8aYh+Jo2piruBA
138QnB9ZaPmEM1HPNArJxqL6XcUJTkFxNSksOATDFV5sEoBWYIe6qv2nV2r/HWDAEaa4WH2h3o/
139kASarXk3SxPXmfjOOr1XgpKjAgMBAAGjggG1MIIBsTAfBgNVHSMEGDAWgBSCr2yM+MX+lmF8
1406B89K3FIXsSLwDAdBgNVHQ4EFgQU7Olc92Oy6nkCvpv6jCj6qN8YPtUwDgYDVR0PAQH/BAQD
141AgeAMAwGA1UdEwEB/wQCMAAwRgYDVR0gBD8wPTA7BgwrBgEEAbIxAQIBAwUwKzApBggrBgEF
142BQcCARYdaHR0cHM6Ly9zZWN1cmUuY29tb2RvLmNvbS9DUFMwWgYDVR0fBFMwUTBPoE2gS4ZJ
143aHR0cDovL2NybC5jb21vZG9jYS5jb20vQ09NT0RPUlNBQ2xpZW50QXV0aGVudGljYXRpb25h
144bmRTZWN1cmVFbWFpbENBLmNybDCBiwYIKwYBBQUHAQEEfzB9MFUGCCsGAQUFBzAChklodHRw
145Oi8vY3J0LmNvbW9kb2NhLmNvbS9DT01PRE9SU0FDbGllbnRBdXRoZW50aWNhdGlvbmFuZFNl
146Y3VyZUVtYWlsQ0EuY3J0MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21vZG9jYS5jb20w
147HwYDVR0RBBgwFoEUaWV0Zi1hY3Rpb25AaWV0Zi5vcmcwDQYJKoZIhvcNAQELBQADggEBAGPm
148QUKHxkEQ9vk69vIP68anHc8UsTv5powtLSXLqUw3rAoKAdoWkKjb7ZByHCuFiNk1BvTnhQPh
149LAZm5dI8dYWKp3zgWVxsCXOQv2K4XbaQpIk8KKdLycHWsOq2OD4xBdhfTQqDj9EidhxaLf4B
150bRUePOuWVvwNqHI6OQ9FbRllUsTsSH3XK7z9Ru/0Ub07uEzmWyrIpeFRLJUg9EqQj25pw8j7
151N9ym8ItpfEQvK4Nrzt9KnGwFDaNOUjYAvejig9iUNdOXEQKVzbq8fC25HrXPQisq8u2jrP38
152cRqzwgGHZ1bJrQa8+LPBfADZ4ZHeqlEe6IqZhS/wDSuDNCIZHtkxggKqMIICpgIBA4AU7Olc
15392Oy6nkCvpv6jCj6qN8YPtUwCwYJYIZIAWUDBAIBoGswGgYJKoZIhvcNAQkDMQ0GCyqGSIb3
154DQEJEAEdMBwGCSqGSIb3DQEJBTEPFw0xOTA3MTQwMTMyMTdaMC8GCSqGSIb3DQEJBDEiBCAJ
155zK6u0RRfrSQ2ebn+GOxnbovlG3Raul/1zOOGmTaIPzANBgkqhkiG9w0BAQEFAASCAgBlKYNd
156euVzPDqEa13k4nQthmyJUUqjWlAVolgohXioYok8Z5BkKmkp8ANLbvkJl0hV1Al1hutTRNeF
157a5ZeWyS6nAWyPFKfRSNqwWLMIi1dX+rO7Vhf15Lz944ZYsqO+O2f7rjWUJmi8/uJKD7cFDiW
158uKkPMgvqyIMnnC3ya/sC1vU+0Feqr5JcIMs2AHQeNVe8hzN4T9Pthyax7gqbxTkg3Gyt7Mwy
159WLZeK84oJmkl9ANeVgzq+P/cmqUaqtfkBFDSxaTag/eoYM3QfHNisr/jHCazqCh88VMgwhvk
160cl6NS9hdH+aOWqQ3FE1c7VJNoQRDT7ztyKCrRJFPc4wZL8tsGkKp1lP4WcaStcbUJ65AdWPb
1613CZonLY4UOBotAUpG/PObMCmWBEpr8MN0Q+kuEO2oAe9kBoFsv7MtNfyHE4CuOANRqGLRgOL
16272hN8Cy0sGWYUy+2chH3i50cT8XkDV5Rz2Z5xW3SfyAuW53j2WKLFsKkZjfkZBopSJM20V4E
1638pPnQQ/ByFwYPyS/xJZc24vsRxgogbrf11JU8hKVkfSsq3JXxUxe5w+Sh1XGTmO5tXDKFfyi
164S+VljWVifzXaR3pmTEQPhXH4nBa4K/HYytxofDP3EMli+imil2fFBbBedZkb5CIQ/Ly3soHZ
165dZlmZDkyeXJLpkNjRAsG6V82raZd9g==
166""",
167)
168
169    def setUp(self):
170        self.asn1Spec = rfc5652.ContentInfo()
171
172    def testDerCodec(self):
173        oids = [ ]
174        for pem_text in self.pem_text_list:
175            substrate = pem.readBase64fromText(pem_text)
176            asn1Object, rest = der_decode(substrate, asn1Spec=self.asn1Spec)
177            assert not rest
178            assert asn1Object.prettyPrint()
179            assert der_encode(asn1Object) == substrate
180
181            assert asn1Object['contentType'] == rfc5652.id_signedData
182            sd, rest = der_decode(asn1Object['content'], asn1Spec=rfc5652.SignedData())
183            assert not rest
184            assert sd.prettyPrint()
185            assert der_encode(sd) == asn1Object['content']
186
187            oids.append(sd['encapContentInfo']['eContentType'])
188
189        assert rfc8358.id_ct_asciiTextWithCRLF in oids
190        assert rfc8358.id_ct_pdf in oids
191        assert rfc8358.id_ct_xml in oids
192
193
194suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
195
196if __name__ == '__main__':
197    import sys
198
199    result = unittest.TextTestRunner(verbosity=2).run(suite)
200    sys.exit(not result.wasSuccessful())
201