synapse 2.175.0__py311-none-any.whl → 2.177.0__py311-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of synapse might be problematic. Click here for more details.

Files changed (73) hide show
  1. synapse/axon.py +24 -9
  2. synapse/cortex.py +330 -168
  3. synapse/cryotank.py +46 -37
  4. synapse/datamodel.py +17 -4
  5. synapse/exc.py +19 -0
  6. synapse/lib/agenda.py +7 -13
  7. synapse/lib/ast.py +6 -5
  8. synapse/lib/auth.py +1520 -0
  9. synapse/lib/cell.py +255 -53
  10. synapse/lib/grammar.py +5 -0
  11. synapse/lib/hive.py +24 -3
  12. synapse/lib/hiveauth.py +6 -32
  13. synapse/lib/layer.py +7 -4
  14. synapse/lib/link.py +21 -17
  15. synapse/lib/lmdbslab.py +149 -0
  16. synapse/lib/modelrev.py +1 -1
  17. synapse/lib/schemas.py +136 -0
  18. synapse/lib/storm.py +70 -33
  19. synapse/lib/stormlib/aha.py +1 -1
  20. synapse/lib/stormlib/auth.py +185 -10
  21. synapse/lib/stormlib/cortex.py +16 -5
  22. synapse/lib/stormlib/gen.py +80 -0
  23. synapse/lib/stormlib/model.py +55 -0
  24. synapse/lib/stormlib/modelext.py +60 -0
  25. synapse/lib/stormlib/storm.py +117 -5
  26. synapse/lib/stormlib/tabular.py +212 -0
  27. synapse/lib/stormtypes.py +14 -1
  28. synapse/lib/trigger.py +1 -1
  29. synapse/lib/version.py +2 -2
  30. synapse/lib/view.py +55 -28
  31. synapse/models/base.py +7 -0
  32. synapse/models/biz.py +4 -0
  33. synapse/models/files.py +8 -1
  34. synapse/models/inet.py +31 -0
  35. synapse/tests/files/changelog/model_2.176.0_16ee721a6b7221344eaf946c3ab4602dda546b1a.yaml.gz +0 -0
  36. synapse/tests/files/changelog/model_2.176.0_2a25c58bbd344716cd7cbc3f4304d8925b0f4ef2.yaml.gz +0 -0
  37. synapse/tests/test_axon.py +7 -4
  38. synapse/tests/test_cortex.py +127 -82
  39. synapse/tests/test_cryotank.py +4 -4
  40. synapse/tests/test_datamodel.py +7 -0
  41. synapse/tests/test_lib_agenda.py +7 -0
  42. synapse/tests/{test_lib_hiveauth.py → test_lib_auth.py} +314 -11
  43. synapse/tests/test_lib_cell.py +161 -8
  44. synapse/tests/test_lib_httpapi.py +18 -14
  45. synapse/tests/test_lib_layer.py +33 -33
  46. synapse/tests/test_lib_link.py +42 -1
  47. synapse/tests/test_lib_lmdbslab.py +68 -0
  48. synapse/tests/test_lib_nexus.py +4 -4
  49. synapse/tests/test_lib_node.py +0 -7
  50. synapse/tests/test_lib_storm.py +45 -0
  51. synapse/tests/test_lib_stormlib_aha.py +1 -2
  52. synapse/tests/test_lib_stormlib_auth.py +21 -0
  53. synapse/tests/test_lib_stormlib_cortex.py +12 -12
  54. synapse/tests/test_lib_stormlib_gen.py +99 -0
  55. synapse/tests/test_lib_stormlib_model.py +108 -0
  56. synapse/tests/test_lib_stormlib_modelext.py +64 -0
  57. synapse/tests/test_lib_stormlib_storm.py +82 -1
  58. synapse/tests/test_lib_stormlib_tabular.py +226 -0
  59. synapse/tests/test_lib_stormsvc.py +4 -1
  60. synapse/tests/test_lib_stormtypes.py +10 -0
  61. synapse/tests/test_model_base.py +3 -0
  62. synapse/tests/test_model_biz.py +3 -0
  63. synapse/tests/test_model_files.py +12 -2
  64. synapse/tests/test_model_inet.py +55 -0
  65. synapse/tests/test_tools_changelog.py +196 -0
  66. synapse/tests/test_tools_healthcheck.py +4 -3
  67. synapse/tests/utils.py +1 -1
  68. synapse/tools/changelog.py +774 -15
  69. {synapse-2.175.0.dist-info → synapse-2.177.0.dist-info}/METADATA +3 -3
  70. {synapse-2.175.0.dist-info → synapse-2.177.0.dist-info}/RECORD +73 -67
  71. {synapse-2.175.0.dist-info → synapse-2.177.0.dist-info}/WHEEL +1 -1
  72. {synapse-2.175.0.dist-info → synapse-2.177.0.dist-info}/LICENSE +0 -0
  73. {synapse-2.175.0.dist-info → synapse-2.177.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,226 @@
1
+ import synapse.exc as s_exc
2
+ import synapse.tests.utils as s_test
3
+
4
+ def printlines(mesgs):
5
+ return [part for m in mesgs if m[0] == 'print' for part in m[1]['mesg'].split('\n')]
6
+
7
+ class TabularTest(s_test.SynTest):
8
+
9
+ async def test_stormlib_tabular(self):
10
+
11
+ async with self.getTestCore() as core:
12
+
13
+ opts = {
14
+ 'vars': {
15
+ 'rows': [
16
+ (1973, 'Issac Asimov', 'The Gods Themselves'),
17
+ (1974, 'Arthur C. Clarke', 'Rendezvous with Rama'),
18
+ (1975, 'Ursula K. Le Guin', 'The Dispossessed'),
19
+ (1976, 'Joe Haldeman', 'The Forever War'),
20
+ ],
21
+ },
22
+ }
23
+
24
+ # get schema
25
+
26
+ mesgs = await core.stormlist('$lib.print($lib.yaml.save($lib.tabular.schema()))')
27
+ self.stormHasNoWarnErr(mesgs)
28
+ self.stormIsInPrint('column:outline', mesgs)
29
+
30
+ # single line defaults
31
+
32
+ mesgs = await core.stormlist('''
33
+ $printer = $lib.tabular.printer(({
34
+ "columns": [
35
+ {"name": "Year", "width": 6, "justify": "right"},
36
+ {"name": "Author", "width": 20, "justify": "center"},
37
+ {"name": "Title", "width": 12},
38
+ ]
39
+ }))
40
+
41
+ $lib.print($printer.header())
42
+ for $row in $rows {
43
+ $lib.print($printer.row($row))
44
+ }
45
+ ''', opts=opts)
46
+ self.stormHasNoWarnErr(mesgs)
47
+ self.eq([
48
+ ' Year | Author | Title ',
49
+ '========|======================|==============',
50
+ ' 1973 | Issac Asimov | The Gods ... ',
51
+ '--------|----------------------|--------------',
52
+ ' 1974 | Arthur C. Clarke | Rendezvou... ',
53
+ '--------|----------------------|--------------',
54
+ ' 1975 | Ursula K. Le Guin | The Dispo... ',
55
+ '--------|----------------------|--------------',
56
+ ' 1976 | Joe Haldeman | The Forev... ',
57
+ ], printlines(mesgs))
58
+
59
+ # custom separators
60
+
61
+ mesgs = await core.stormlist('''
62
+ $printer = $lib.tabular.printer(({
63
+ "separators": {
64
+ "row:outline": true,
65
+ "column:outline": true,
66
+ "header:row": "#",
67
+ "data:row": "*",
68
+ "column": "+",
69
+ },
70
+ "columns": [
71
+ {"name": "Year", "width": 6, "justify": "right"},
72
+ {"name": "Author", "width": 20, "justify": "center"},
73
+ {"name": "Title", "width": 12},
74
+ ]
75
+ }))
76
+
77
+ $lib.print($printer.header())
78
+ for $row in $rows {
79
+ $lib.print($printer.row($row))
80
+ }
81
+ ''', opts=opts)
82
+ self.stormHasNoWarnErr(mesgs)
83
+ self.eq([
84
+ '+########+######################+##############+',
85
+ '+ Year + Author + Title +',
86
+ '+########+######################+##############+',
87
+ '+ 1973 + Issac Asimov + The Gods ... +',
88
+ '+********+**********************+**************+',
89
+ '+ 1974 + Arthur C. Clarke + Rendezvou... +',
90
+ '+********+**********************+**************+',
91
+ '+ 1975 + Ursula K. Le Guin + The Dispo... +',
92
+ '+********+**********************+**************+',
93
+ '+ 1976 + Joe Haldeman + The Forev... +',
94
+ '+********+**********************+**************+',
95
+ ], printlines(mesgs))
96
+
97
+ # no col separators or end width
98
+
99
+ mesgs = await core.stormlist('''
100
+ $printer = $lib.tabular.printer(({
101
+ "separators": {
102
+ "header:row": "",
103
+ "data:row": "",
104
+ "column": "",
105
+ },
106
+ "columns": [
107
+ {"name": "Year", "width": 6, "justify": "right"},
108
+ {"name": "Author", "width": 20, "justify": "center"},
109
+ {"name": "Title"},
110
+ ]
111
+ }))
112
+
113
+ $lib.print($printer.header())
114
+ for $row in $rows {
115
+ $lib.print($printer.row($row))
116
+ }
117
+ ''', opts=opts)
118
+ self.stormHasNoWarnErr(mesgs)
119
+ self.eq([
120
+ ' Year Author Title ',
121
+ ' 1973 Issac Asimov The Gods Themselves ',
122
+ ' 1974 Arthur C. Clarke Rendezvous with Rama ',
123
+ ' 1975 Ursula K. Le Guin The Dispossessed ',
124
+ ' 1976 Joe Haldeman The Forever War ',
125
+ ], printlines(mesgs))
126
+
127
+ # wraps
128
+
129
+ mesgs = await core.stormlist('''
130
+ $printer = $lib.tabular.printer(({
131
+ "columns": [
132
+ {"name": "Year", "width": 6, "justify": "right"},
133
+ {"name": "Author", "width": 10, "justify": "center", "overflow": "wrap"},
134
+ {"name": "Title", "width": 10, "overflow": "wrap"},
135
+ ]
136
+ }))
137
+
138
+ $lib.print($printer.header())
139
+ for $row in $rows {
140
+ $lib.print($printer.row($row))
141
+ }
142
+ ''', opts=opts)
143
+ self.stormHasNoWarnErr(mesgs)
144
+ self.eq([
145
+ ' Year | Author | Title ',
146
+ '========|============|============',
147
+ ' 1973 | Issac | The Gods ',
148
+ ' | Asimov | Themselves ',
149
+ '--------|------------|------------',
150
+ ' 1974 | Arthur C. | Rendezvous ',
151
+ ' | Clarke | with Rama ',
152
+ '--------|------------|------------',
153
+ ' 1975 | Ursula K. | The Dispos ',
154
+ ' | Le Guin | sessed ',
155
+ '--------|------------|------------',
156
+ ' 1976 | Joe | The ',
157
+ ' | Haldeman | Forever ',
158
+ ' | | War ',
159
+ ], printlines(mesgs))
160
+
161
+ # newlines
162
+
163
+ mesgs = await core.stormlist('''
164
+ $printer = $lib.tabular.printer(({
165
+ "columns": [
166
+ {"name": "Foo", "width": 10},
167
+ {"name": "Bar", "width": 10, "newlines": "split"},
168
+ {"name": "Baz", "newlines": "split"},
169
+ ],
170
+ }))
171
+
172
+ $lib.print($printer.header())
173
+ $lib.print($printer.row(("aaa\\nbbb", "ccc\\nddd", "eee\\nfff")))
174
+ $lib.print($printer.row(("a", "dummy", "row")))
175
+ ''', opts=opts)
176
+ self.stormHasNoWarnErr(mesgs)
177
+ self.eq([
178
+ ' Foo | Bar | Baz ',
179
+ '============|============|=====',
180
+ ' aaa bbb | ccc ddd | eee ',
181
+ ' | | fff ',
182
+ '------------|------------|-----',
183
+ ' a | dummy | row ',
184
+ ], printlines(mesgs))
185
+
186
+ # reprs
187
+
188
+ mesgs = await core.stormlist('''
189
+ $printer = $lib.tabular.printer(({
190
+ "separators": {"header:row": "", "data:row": ""},
191
+ "columns": [{"name": "Foo", "width": 20}],
192
+ }))
193
+
194
+ $lib.print($printer.row(($lib.null,)))
195
+ $lib.print($printer.row((({"bar": "baz"}),)))
196
+ $lib.print($printer.row((${ps:name=cool},)))
197
+ ''', opts=opts)
198
+ self.stormHasNoWarnErr(mesgs)
199
+ self.eq([
200
+ " ",
201
+ " {'bar': 'baz'} ",
202
+ " ps:name=cool ",
203
+ ], printlines(mesgs))
204
+
205
+ # sad
206
+
207
+ with self.raises(s_exc.SchemaViolation):
208
+ await core.nodes('$lib.tabular.printer(({"columns": [{"name": "newp", "width": -43}]}))')
209
+
210
+ with self.raises(s_exc.BadArg) as ecm:
211
+ await core.nodes('''
212
+ $printer = $lib.tabular.printer(({
213
+ "columns": [{"name": "Foo", "width": 20}],
214
+ }))
215
+ $printer.row(({"yeah": "no"}))
216
+ ''')
217
+ self.eq('tabular:printer row() requires a list argument', ecm.exception.errinfo['mesg'])
218
+
219
+ with self.raises(s_exc.BadArg) as ecm:
220
+ await core.nodes('''
221
+ $printer = $lib.tabular.printer(({
222
+ "columns": [{"name": "Foo", "width": 20}],
223
+ }))
224
+ $printer.row((too, many, items))
225
+ ''')
226
+ self.eq('tabular:printer row() requires data length to equal column count', ecm.exception.errinfo['mesg'])
@@ -419,13 +419,16 @@ class StormSvcTest(s_test.SynTest):
419
419
  self.stormIsInPrint(f'List the storm services configured in the cortex.', msgs)
420
420
 
421
421
  msgs = await core.stormlist('service.add fake tcp://localhost:3333/foo')
422
- iden = core.getStormSvcs()[0].iden
422
+ ssvc = core.getStormSvcs()[0]
423
+ iden = ssvc.iden
423
424
  self.stormIsInPrint(f'added {iden} (fake): tcp://localhost:3333/foo', msgs)
424
425
 
425
426
  msgs = await core.stormlist('service.list')
426
427
  self.stormIsInPrint('Storm service list (iden, ready, name, service name, service version, url):', msgs)
427
428
  self.stormIsInPrint(f' {iden} false (fake) (Unknown @ Unknown): tcp://localhost:3333/foo', msgs)
428
429
 
430
+ self.eq(ssvc.sdef, await core._addStormSvc({'iden': iden}))
431
+
429
432
  msgs = await core.stormlist(f'service.del {iden[:4]}')
430
433
  self.stormIsInPrint(f'removed {iden} (fake): tcp://localhost:3333/foo', msgs)
431
434
 
@@ -3277,6 +3277,16 @@ class StormTypesTest(s_test.SynTest):
3277
3277
  self.eq(err[0], 'StormRuntimeError')
3278
3278
  self.isin('Error during base64 decoding - Incorrect padding', err[1].get('mesg'))
3279
3279
 
3280
+ opts = {'vars': {'bytes': None}}
3281
+ text = '[test:str=$lib.base64.decode($bytes)]'
3282
+ mesgs = await core.stormlist(text, opts=opts)
3283
+ errs = [m[1] for m in mesgs if m[0] == 'err']
3284
+ self.len(1, errs)
3285
+ err = errs[0]
3286
+ self.eq(err[0], 'StormRuntimeError')
3287
+ emsg = "Error during base64 decoding - argument should be a bytes-like object or ASCII string, not 'NoneType'"
3288
+ self.isin(emsg, err[1].get('mesg'))
3289
+
3280
3290
  async def test_storm_lib_vars(self):
3281
3291
 
3282
3292
  async with self.getTestCore() as core:
@@ -278,6 +278,7 @@ class BaseTest(s_t_utils.SynTest):
278
278
  [ meta:rule=*
279
279
  :created=20200202 :updated=20220401 :author=*
280
280
  :name=" My Rule" :desc="My cool rule"
281
+ :type=foo.bar
281
282
  :text="while TRUE { BAD }"
282
283
  :ext:id=WOOT-20 :url=https://vertex.link/rules/WOOT-20
283
284
  <(has)+ { meta:ruleset }
@@ -287,6 +288,7 @@ class BaseTest(s_t_utils.SynTest):
287
288
  self.len(1, nodes)
288
289
 
289
290
  self.nn(nodes[0].get('author'))
291
+ self.eq(nodes[0].get('type'), 'foo.bar.')
290
292
  self.eq(nodes[0].get('created'), 1580601600000)
291
293
  self.eq(nodes[0].get('updated'), 1648771200000)
292
294
  self.eq(nodes[0].get('name'), 'my rule')
@@ -296,6 +298,7 @@ class BaseTest(s_t_utils.SynTest):
296
298
  self.eq(nodes[0].get('ext:id'), 'WOOT-20')
297
299
 
298
300
  self.len(1, await core.nodes('meta:rule -> ps:contact'))
301
+ self.len(1, await core.nodes('meta:rule -> meta:rule:type:taxonomy'))
299
302
  self.len(1, await core.nodes('meta:ruleset -> ps:contact'))
300
303
  self.len(1, await core.nodes('meta:ruleset -(has)> meta:rule -(matches)> *'))
301
304
 
@@ -51,6 +51,7 @@ class BizModelTest(s_t_utils.SynTest):
51
51
  nodes = await core.nodes('''
52
52
  [ biz:deal=*
53
53
 
54
+ :id = " 12345 "
54
55
  :title = HeHeHaHa
55
56
  :type = baz.faz
56
57
  :status = foo.bar
@@ -74,6 +75,7 @@ class BizModelTest(s_t_utils.SynTest):
74
75
  ]
75
76
  ''')
76
77
  self.len(1, nodes)
78
+ self.eq(nodes[0].get('id'), '12345')
77
79
  self.eq(nodes[0].get('title'), 'HeHeHaHa')
78
80
  self.eq(nodes[0].get('type'), 'baz.faz.')
79
81
  self.eq(nodes[0].get('status'), 'foo.bar.')
@@ -128,6 +130,7 @@ class BizModelTest(s_t_utils.SynTest):
128
130
  self.nn(nodes[0].get('purchase'))
129
131
 
130
132
  self.len(1, await core.nodes('biz:bundle -> biz:deal'))
133
+ self.len(1, await core.nodes('biz:bundle -> biz:deal +:id=12345'))
131
134
  self.len(1, await core.nodes('biz:bundle -> econ:purchase'))
132
135
  self.len(1, await core.nodes('biz:bundle -> biz:product +:name=LoLoLoL'))
133
136
  self.len(1, await core.nodes('biz:bundle -> biz:service +:name=WoWoWoW'))
@@ -586,7 +586,7 @@ class FileTest(s_t_utils.SynTest):
586
586
  :entry:primary="c:\\some\\stuff\\prog~2\\cmd.exe"
587
587
  :entry:secondary="c:\\some\\stuff\program files\\cmd.exe"
588
588
  :entry:extended="c:\\some\\actual\\stuff\\I\\swear\\cmd.exe"
589
- :entry:localized="c:\\some\\actual\\stuff\\I\\swear\\cmd.exe"
589
+ :entry:localized="c:\\some\\actual\\archivos\\I\\swear\\cmd.exe"
590
590
  :entry:icon="%windir%\\system32\\notepad.exe"
591
591
 
592
592
  :environment:path="%windir%\\system32\\cmd.exe"
@@ -602,6 +602,10 @@ class FileTest(s_t_utils.SynTest):
602
602
  :target:created="2023/01/25 18:57:45.284"
603
603
  :target:accessed="2023/01/25 18:57:45.284"
604
604
  :target:written="2023/01/25 18:57:45.284"
605
+
606
+ :driveserial=0x6af54670
607
+ :machineid=stellarcollapse
608
+ :iconindex=1
605
609
  ]''')
606
610
  self.len(1, nodes)
607
611
  node = nodes[0]
@@ -609,7 +613,7 @@ class FileTest(s_t_utils.SynTest):
609
613
  self.eq(node.get('entry:primary'), 'c:/some/stuff/prog~2/cmd.exe')
610
614
  self.eq(node.get('entry:secondary'), 'c:/some/stuff/program files/cmd.exe')
611
615
  self.eq(node.get('entry:extended'), 'c:/some/actual/stuff/i/swear/cmd.exe')
612
- self.eq(node.get('entry:localized'), 'c:/some/actual/stuff/i/swear/cmd.exe')
616
+ self.eq(node.get('entry:localized'), 'c:/some/actual/archivos/i/swear/cmd.exe')
613
617
 
614
618
  self.eq(node.get('entry:icon'), '%windir%/system32/notepad.exe')
615
619
  self.eq(node.get('environment:path'), '%windir%/system32/cmd.exe')
@@ -628,3 +632,9 @@ class FileTest(s_t_utils.SynTest):
628
632
  self.eq(node.get('target:created'), time)
629
633
  self.eq(node.get('target:accessed'), time)
630
634
  self.eq(node.get('target:written'), time)
635
+
636
+ self.eq(node.get('driveserial'), 0x6af54670)
637
+ self.eq(node.get('machineid'), 'stellarcollapse')
638
+ self.eq(node.get('iconindex'), 1)
639
+
640
+ self.len(1, await core.nodes('file:mime:lnk -> it:hostname'))
@@ -3173,16 +3173,19 @@ class InetModelTest(s_t_utils.SynTest):
3173
3173
  q = '''
3174
3174
  [
3175
3175
  (inet:service:message=(blackout, developers, 1715856900000, vertex, slack)
3176
+ :type=chat.group
3176
3177
  :group=$devsiden
3177
3178
  :public=$lib.false
3178
3179
  )
3179
3180
 
3180
3181
  (inet:service:message=(blackout, visi, 1715856900000, vertex, slack)
3182
+ :type=chat.direct
3181
3183
  :to=$visiiden
3182
3184
  :public=$lib.false
3183
3185
  )
3184
3186
 
3185
3187
  (inet:service:message=(blackout, general, 1715856900000, vertex, slack)
3188
+ :type=chat.channel
3186
3189
  :channel=$gnrliden
3187
3190
  :public=$lib.true
3188
3191
  )
@@ -3224,12 +3227,33 @@ class InetModelTest(s_t_utils.SynTest):
3224
3227
 
3225
3228
  self.eq(nodes[0].get('group'), devsgrp.ndef[1])
3226
3229
  self.false(nodes[0].get('public'))
3230
+ self.eq(nodes[0].get('type'), 'chat.group.')
3227
3231
 
3228
3232
  self.eq(nodes[1].get('to'), visiacct.ndef[1])
3229
3233
  self.false(nodes[1].get('public'))
3234
+ self.eq(nodes[1].get('type'), 'chat.direct.')
3230
3235
 
3231
3236
  self.eq(nodes[2].get('channel'), gnrlchan.ndef[1])
3232
3237
  self.true(nodes[2].get('public'))
3238
+ self.eq(nodes[2].get('type'), 'chat.channel.')
3239
+
3240
+ svcmsgs = await core.nodes('inet:service:message:type:taxonomy -> inet:service:message')
3241
+ self.len(3, svcmsgs)
3242
+ self.sorteq(
3243
+ [k.ndef for k in svcmsgs],
3244
+ [k.ndef for k in nodes],
3245
+ )
3246
+
3247
+ nodes = await core.nodes('inet:service:message:type:taxonomy')
3248
+ self.len(4, nodes)
3249
+ self.sorteq(
3250
+ [k.ndef[1] for k in nodes],
3251
+ ('chat.', 'chat.channel.', 'chat.direct.', 'chat.group.'),
3252
+ )
3253
+
3254
+ nodes = await core.nodes('inet:service:message:type:taxonomy=chat.channel -> inet:service:message')
3255
+ self.len(1, nodes)
3256
+ self.eq(nodes[0].ndef, ('inet:service:message', 'c0d64c559e2f42d57b37b558458c068b'))
3233
3257
 
3234
3258
  q = '''
3235
3259
  [ inet:service:resource=(web, api, vertex, slack)
@@ -3300,3 +3324,34 @@ class InetModelTest(s_t_utils.SynTest):
3300
3324
  self.eq(nodes[0].get('resource'), resource.ndef[1])
3301
3325
  self.true(nodes[0].get('success'))
3302
3326
  self.eq(nodes[0].get('time'), 1715856900000)
3327
+
3328
+ q = '''
3329
+ [ inet:service:message=(visi, says, relax)
3330
+ :title="Hehe Haha"
3331
+ :thread={[
3332
+ inet:service:thread=*
3333
+ :title="Woot Woot"
3334
+ :message=(visi, says, hello)
3335
+ :channel={[
3336
+ inet:service:channel=(synapse, subreddit)
3337
+ :name="/r/synapse"
3338
+ ]}
3339
+ ]}
3340
+ ]
3341
+ '''
3342
+ nodes = await core.nodes(q)
3343
+ self.len(1, nodes)
3344
+ self.len(1, await core.nodes('inet:service:message=(visi, says, hello) -> inet:service:thread:message'))
3345
+ self.len(1, await core.nodes('''
3346
+ inet:service:message:title="hehe haha"
3347
+ :thread -> inet:service:thread
3348
+ +:title="woot woot"
3349
+ '''))
3350
+ self.len(2, await core.nodes('inet:service:thread -> inet:service:message'))
3351
+
3352
+ self.len(1, await core.nodes('''
3353
+ inet:service:message:title="hehe haha"
3354
+ :thread -> inet:service:thread
3355
+ :channel -> inet:service:channel
3356
+ +:name="/r/synapse"
3357
+ '''))
@@ -0,0 +1,196 @@
1
+ import synapse.tests.utils as s_test_utils
2
+
3
+ import synapse.tools.changelog as s_t_changelog
4
+
5
+ class ChangelogToolTest(s_test_utils.SynTest):
6
+
7
+ async def test_model_diff(self):
8
+ outp = self.getTestOutp()
9
+ old_fp = self.getTestFilePath('changelog', 'model_2.176.0_16ee721a6b7221344eaf946c3ab4602dda546b1a.yaml.gz')
10
+ new_fp = self.getTestFilePath('changelog', 'model_2.176.0_2a25c58bbd344716cd7cbc3f4304d8925b0f4ef2.yaml.gz')
11
+ oldmodel = s_t_changelog._getModelFile(old_fp)
12
+ newmodel = s_t_changelog._getModelFile(new_fp)
13
+
14
+ differ = s_t_changelog.ModelDiffer(newmodel.get('model'), oldmodel.get('model'))
15
+
16
+ self.eq(differ.cur_type2iface['it:host'], ['inet:service:object', 'inet:service:base'])
17
+ self.eq(differ.cur_type2iface['mat:type'], ['meta:taxonomy'])
18
+ self.eq(differ.cur_iface_to_allifaces['it:host:activity'], ['it:host:activity'])
19
+ self.eq(differ.cur_iface_to_allifaces['file:mime:msoffice'], ['file:mime:msoffice', 'file:mime:meta'])
20
+ changes = differ.diffModl(outp)
21
+
22
+ self.len(4, changes.get('edges').get('new_edges'))
23
+
24
+ form_chng = changes.get('forms')
25
+ self.isin('it:beeper:thingy', form_chng.get('new_forms'))
26
+ self.notin('it:beeper:name', form_chng.get('new_forms'))
27
+ updt_frms = form_chng.get('updated_forms')
28
+ self.isin('new_properties', updt_frms.get('file:mime:pe:resource'))
29
+ self.isin('new_properties_no_interfaces', updt_frms.get('file:mime:pe:resource'))
30
+ self.isin('new_properties', updt_frms.get('inet:http:request'))
31
+ self.notin('new_properties_no_interfaces', updt_frms.get('inet:http:request'))
32
+ self.isin('updated_properties', updt_frms.get('file:mime:macho:section'))
33
+ self.isin('deprecated_properties', updt_frms.get('file:mime:lnk'))
34
+ self.isin('deprecated_properties_no_interfaces', updt_frms.get('file:mime:lnk'))
35
+ self.isin('deprecated_properties', updt_frms.get('inet:http:request'))
36
+ self.notin('deprecated_properties_no_interfaces', updt_frms.get('inet:http:request'))
37
+ self.isin('new_properties', updt_frms.get('file:mime:lnk'))
38
+ self.isin('new_properties_no_interfaces', updt_frms.get('file:mime:lnk'))
39
+ self.isin('updated_properties', updt_frms.get('file:mime:lnk'))
40
+ self.isin('updated_properties_no_interfaces', updt_frms.get('file:mime:lnk'))
41
+ self.isin('updated_properties', updt_frms.get('inet:service:access'))
42
+ self.notin('updated_properties_no_interfaces', updt_frms.get('inet:service:access'))
43
+
44
+ self.isin('it:host:beeper', changes.get('interfaces').get('new_interfaces'))
45
+ updt_iface = changes.get('interfaces').get('updated_interfaces')
46
+ self.isin('deprecated_properties', updt_iface.get('it:host:activity'))
47
+ self.isin('new_properties', updt_iface.get('it:host:activity'))
48
+ self.isin('updated_properties', updt_iface.get('inet:service:base'))
49
+
50
+ self.eq(changes.get('tagprops'), {})
51
+
52
+ self.isin('it:reveng:function', changes.get('types').get('deprecated_types'))
53
+ self.isin('inet:port', changes.get('types').get('deprecated_types'))
54
+ self.isin('it:beeper:thingy', changes.get('types').get('new_types'))
55
+ self.isin('it:beeper:name', changes.get('types').get('new_types'))
56
+ uptd_types = changes.get('types').get('updated_types')
57
+ self.isin('updated_opts', uptd_types.get('it:query'))
58
+ self.isin('updated_interfaces', uptd_types.get('it:reveng:impfunc'))
59
+
60
+ rst = s_t_changelog._gen_model_rst('v2.177.0', 'userguide_model_v2_177_0',
61
+ changes, newmodel.get('model'), outp)
62
+ text = rst.getRstText()
63
+ self.isin('v2.177.0 Model Updates', text)
64
+ self.isin('''**************
65
+ New Interfaces
66
+ **************
67
+
68
+ ``it:host:beeper``
69
+ Properties common to instances of beepers.''', text)
70
+ self.isin('''*********
71
+ New Types
72
+ *********
73
+
74
+ ``it:beeper:name``
75
+ The friendly name of a beeper.
76
+ ''', text)
77
+ self.isin('''*********
78
+ New Forms
79
+ *********
80
+
81
+ ``it:beeper:thingy``
82
+ A beeper thingy.
83
+ ''', text)
84
+ self.isin('''**************
85
+ New Properties
86
+ **************
87
+
88
+ ``file:mime:lnk``
89
+ The form had the following properties added to it:
90
+
91
+
92
+ ``driveserial``
93
+ The drive serial number of the volume the link target is stored on.
94
+
95
+
96
+ ``iconindex``
97
+ A resource index for an icon within an icon location.
98
+ ''', text)
99
+ self.isin('''``inet:http:request``
100
+ The form had the following property added to it:
101
+
102
+ ``beep``
103
+ The time that the host went beep.
104
+ ''', text)
105
+ # Some updates will require manual intervention to rewrite.
106
+ self.isin('''******************
107
+ Updated Interfaces
108
+ ******************
109
+
110
+ ``inet:service:base``
111
+ The property ``id`` has been modified from ['str', {'strip': True}] to ['str',
112
+ {'lower': True, 'strip': True}].
113
+
114
+
115
+ ``it:host:activity``
116
+ The interface property ``time`` has been deprecated.
117
+
118
+
119
+ The property ``beep`` has been added to the interface.
120
+ ''', text)
121
+ self.isin('''*************
122
+ Updated Types
123
+ *************
124
+
125
+ ``it:query``
126
+ The type has been modified from {'enums': None, 'globsuffix': False, 'lower':
127
+ False, 'onespace': False, 'regex': None, 'replace': [], 'strip': True} to
128
+ {'enums': None, 'globsuffix': False, 'lower': True, 'onespace': False,
129
+ 'regex': None, 'replace': [], 'strip': True}.
130
+
131
+
132
+ ``it:reveng:impfunc``
133
+ The type interface has been modified from None to ['it:host:beeper'].
134
+ ''', text)
135
+ self.isin('''******************
136
+ Updated Properties
137
+ ******************
138
+
139
+ ``file:mime:lnk``
140
+ The form had the following property updated:
141
+
142
+
143
+ The property ``entry:icon`` has been modified from ['file:path', {}] to
144
+ ['time', {}].
145
+ ''', text)
146
+ self.isin('''***********
147
+ Light Edges
148
+ ***********
149
+
150
+ ``jenkies``
151
+ When used with a ``it:prod:soft`` node, the edge indicates The software uses
152
+ the jenkies technique.
153
+
154
+
155
+ ``loves``
156
+ The source node loves the target node.
157
+
158
+
159
+ ``sneaky``
160
+ When used with a ``ou:technique`` target node, the edge indicates The
161
+ technique referred to is sneakily used.
162
+
163
+
164
+ ``zoinks``
165
+ When used with a ``it:prod:soft`` and an ``ou:technique`` node, the edge
166
+ indicates The software uses the zoinks technique.
167
+ ''', text)
168
+ self.isin('''****************
169
+ Deprecated Types
170
+ ****************
171
+
172
+ The following types have been marked as deprecated:
173
+
174
+
175
+ * ``inet:port``
176
+
177
+ ''', text)
178
+ self.isin('''****************
179
+ Deprecated Types
180
+ ****************
181
+
182
+ The following forms have been marked as deprecated:
183
+
184
+
185
+ * ``it:reveng:function``
186
+ ''', text)
187
+ self.isin('''*********************
188
+ Deprecated Properties
189
+ *********************
190
+
191
+ ``file:mime:lnk``
192
+ The form had the following property deprecated:
193
+
194
+ ``target:attrs``
195
+ The attributes of the target file according to the LNK header.
196
+ ''', text)
@@ -65,11 +65,12 @@ class HealthcheckTest(s_t_utils.SynTest):
65
65
  m = 'Synapse error encountered.'
66
66
  self.eq(resp.get('components')[0].get('mesg'), m)
67
67
 
68
- # dont do this in prod...
68
+ visi = await core.auth.addUser('visi')
69
+ await visi.setPasswd('secret')
70
+
69
71
  logger.info('Checking without perms')
70
- await root.setAdmin(False)
71
72
  outp.clear()
72
- retn = await s_t_healthcheck.main(['-c', curl, '-t', '0.2'], outp)
73
+ retn = await s_t_healthcheck.main(['-c', f'tcp://visi:secret@127.0.0.1:{port}/cortex', '-t', '0.2'], outp)
73
74
  self.eq(retn, 1)
74
75
  resp = json.loads(str(outp))
75
76
  self.eq(resp.get('components')[0].get('name'), 'error')
synapse/tests/utils.py CHANGED
@@ -1785,7 +1785,7 @@ class SynTest(unittest.TestCase):
1785
1785
  await stream.wait(timeout=10)
1786
1786
 
1787
1787
  data = stream.getvalue()
1788
- raw_mesgs = [m for m in data.split('\\n') if m]
1788
+ raw_mesgs = [m for m in data.split('\n') if m]
1789
1789
  msgs = [json.loads(m) for m in raw_mesgs]
1790
1790
  # Do something with messages
1791
1791