arborist 0.1.0 → 0.2.0.pre20170519125456

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.
@@ -1,791 +0,0 @@
1
- #!/usr/bin/env rspec -cfd
2
-
3
- require_relative '../../spec_helper'
4
-
5
-
6
- describe Arborist::Manager::TreeAPI, :testing_manager do
7
-
8
- before( :each ) do
9
- @manager = nil
10
- @manager_thread = Thread.new do
11
- @manager = make_testing_manager()
12
- Thread.current.abort_on_exception = true
13
- @manager.run
14
- Loggability[ Arborist ].info "Stopped the test manager"
15
- end
16
-
17
- count = 0
18
- until (@manager && @manager.running?) || count > 30
19
- sleep 0.1
20
- count += 1
21
- end
22
- raise "Manager didn't start up" unless @manager.running?
23
- end
24
-
25
- after( :each ) do
26
- @manager.simulate_signal( :TERM )
27
- unless @manager_thread.join( 5 )
28
- $stderr.puts "Manager thread didn't exit on its own; killing it."
29
- @manager_thread.kill
30
- end
31
-
32
- count = 0
33
- while @manager.zmq_loop.running? || count > 30
34
- sleep 0.1
35
- Loggability[ Arborist ].info "ZMQ loop still running"
36
- count += 1
37
- end
38
- raise "ZMQ Loop didn't stop" if @manager.zmq_loop.running?
39
- end
40
-
41
-
42
- let( :manager ) { @manager }
43
-
44
- let!( :sock ) do
45
- sock = Arborist.zmq_context.socket( :REQ )
46
- sock.linger = 0
47
- sock.connect( TESTING_API_SOCK )
48
- sock
49
- end
50
-
51
- let( :api_handler ) { described_class.new( rep_sock, manager ) }
52
-
53
-
54
- describe "malformed requests" do
55
-
56
- it "send an error response if the request can't be deserialized" do
57
- sock.send( "whatevs, dude!" )
58
- resmsg = sock.recv
59
-
60
- hdr, body = unpack_message( resmsg )
61
- expect( hdr ).to include(
62
- 'success' => false,
63
- 'reason' => /invalid request/i,
64
- 'category' => 'client'
65
- )
66
- expect( body ).to be_nil
67
- end
68
-
69
-
70
- it "send an error response if the request isn't a tuple" do
71
- sock.send( MessagePack.pack({ version: 1, action: 'list' }) )
72
- resmsg = sock.recv
73
-
74
- hdr, body = unpack_message( resmsg )
75
- expect( hdr ).to include(
76
- 'success' => false,
77
- 'reason' => /invalid request.*not a tuple/i,
78
- 'category' => 'client'
79
- )
80
- expect( body ).to be_nil
81
- end
82
-
83
-
84
- it "send an error response if the request is empty" do
85
- sock.send( MessagePack.pack([]) )
86
- resmsg = sock.recv
87
-
88
- hdr, body = unpack_message( resmsg )
89
- expect( hdr ).to include(
90
- 'success' => false,
91
- 'reason' => /invalid request.*incorrect length/i,
92
- 'category' => 'client'
93
- )
94
- expect( body ).to be_nil
95
- end
96
-
97
-
98
- it "send an error response if the request is an incorrect length" do
99
- sock.send( MessagePack.pack([{}, {}, {}]) )
100
- resmsg = sock.recv
101
-
102
- hdr, body = unpack_message( resmsg )
103
- expect( hdr ).to include(
104
- 'success' => false,
105
- 'reason' => /invalid request.*incorrect length/i,
106
- 'category' => 'client'
107
- )
108
- expect( body ).to be_nil
109
- end
110
-
111
-
112
- it "send an error response if the request's header is not a Map" do
113
- sock.send( MessagePack.pack([nil, {}]) )
114
- resmsg = sock.recv
115
-
116
- hdr, body = unpack_message( resmsg )
117
- expect( hdr ).to include(
118
- 'success' => false,
119
- 'reason' => /invalid request.*header is not a map/i,
120
- 'category' => 'client'
121
- )
122
- expect( body ).to be_nil
123
- end
124
-
125
-
126
- it "send an error response if the request's body is not Nil, a Map, or an Array of Maps" do
127
- sock.send( MessagePack.pack([{version: 1, action: 'list'}, 18]) )
128
- resmsg = sock.recv
129
-
130
- hdr, body = unpack_message( resmsg )
131
- expect( hdr ).to include(
132
- 'success' => false,
133
- 'reason' => /invalid request.*body must be nil, a map, or an array of maps/i,
134
- 'category' => 'client'
135
- )
136
- expect( body ).to be_nil
137
- end
138
-
139
-
140
- it "send an error response if missing a version" do
141
- sock.send( MessagePack.pack([{action: 'list'}]) )
142
- resmsg = sock.recv
143
-
144
- hdr, body = unpack_message( resmsg )
145
- expect( hdr ).to include(
146
- 'success' => false,
147
- 'reason' => /invalid request.*missing required header 'version'/i,
148
- 'category' => 'client'
149
- )
150
- expect( body ).to be_nil
151
- end
152
-
153
-
154
- it "send an error response if missing an action" do
155
- sock.send( MessagePack.pack([{version: 1}]) )
156
- resmsg = sock.recv
157
-
158
- hdr, body = unpack_message( resmsg )
159
- expect( hdr ).to include(
160
- 'success' => false,
161
- 'reason' => /invalid request.*missing required header 'action'/i,
162
- 'category' => 'client'
163
- )
164
- expect( body ).to be_nil
165
- end
166
-
167
-
168
- it "send an error response for unknown actions" do
169
- badmsg = pack_message( :slap )
170
- sock.send( badmsg )
171
- resmsg = sock.recv
172
-
173
- hdr, body = unpack_message( resmsg )
174
- expect( hdr ).to include(
175
- 'success' => false,
176
- 'reason' => /invalid request.*no such action 'slap'/i,
177
- 'category' => 'client'
178
- )
179
- expect( body ).to be_nil
180
- end
181
- end
182
-
183
-
184
- describe "status" do
185
-
186
-
187
- it "returns a Map describing the manager and its state" do
188
- msg = pack_message( :status )
189
-
190
- sock.send( msg )
191
- resmsg = sock.recv
192
-
193
- hdr, body = unpack_message( resmsg )
194
- expect( hdr ).to include( 'success' => true )
195
- expect( body.length ).to eq( 4 )
196
- expect( body ).to include( 'server_version', 'state', 'uptime', 'nodecount' )
197
- end
198
-
199
- end
200
-
201
-
202
- describe "fetch" do
203
-
204
- it "returns an array of full state maps for nodes matching specified criteria" do
205
- msg = pack_message( :fetch, type: 'service', port: 22 )
206
-
207
- sock.send( msg )
208
- resmsg = sock.recv
209
-
210
- hdr, body = unpack_message( resmsg )
211
- expect( hdr ).to include( 'success' => true )
212
-
213
- expect( body ).to be_a( Hash )
214
- expect( body.length ).to eq( 3 )
215
-
216
- expect( body.values ).to all( be_a(Hash) )
217
- expect( body.values ).to all( include('status', 'type') )
218
- end
219
-
220
-
221
- it "returns an array of full state maps for nodes not matching specified negative criteria" do
222
- msg = pack_message( :fetch, [ {}, {type: 'service', port: 22} ] )
223
-
224
- sock.send( msg )
225
- resmsg = sock.recv
226
-
227
- hdr, body = unpack_message( resmsg )
228
- expect( hdr ).to include( 'success' => true )
229
-
230
- expect( body ).to be_a( Hash )
231
- expect( body.length ).to eq( manager.nodes.length - 3 )
232
-
233
- expect( body.values ).to all( be_a(Hash) )
234
- expect( body.values ).to all( include('status', 'type') )
235
- end
236
-
237
-
238
- it "returns an array of full state maps for nodes combining positive and negative criteria" do
239
- msg = pack_message( :fetch, [ {type: 'service'}, {port: 22} ] )
240
-
241
- sock.send( msg )
242
- resmsg = sock.recv
243
-
244
- hdr, body = unpack_message( resmsg )
245
- expect( hdr ).to include( 'success' => true )
246
-
247
- expect( body ).to be_a( Hash )
248
- expect( body.length ).to eq( 16 )
249
-
250
- expect( body.values ).to all( be_a(Hash) )
251
- expect( body.values ).to all( include('status', 'type') )
252
- end
253
-
254
-
255
- it "doesn't return nodes beneath downed nodes by default" do
256
- manager.nodes['sidonie'].update( error: 'sunspots' )
257
- msg = pack_message( :fetch, type: 'service', port: 22 )
258
-
259
- sock.send( msg )
260
- resmsg = sock.recv
261
-
262
- hdr, body = unpack_message( resmsg )
263
- expect( hdr ).to include( 'success' => true )
264
- expect( body ).to be_a( Hash )
265
- expect( body.length ).to eq( 2 )
266
- expect( body ).to include( 'duir-ssh', 'yevaud-ssh' )
267
- end
268
-
269
-
270
- it "does return nodes beneath downed nodes if asked to" do
271
- manager.nodes['sidonie'].update( error: 'plague of locusts' )
272
- msg = pack_message( :fetch, {include_down: true}, type: 'service', port: 22 )
273
-
274
- sock.send( msg )
275
- resmsg = sock.recv
276
-
277
- hdr, body = unpack_message( resmsg )
278
- expect( hdr ).to include( 'success' => true )
279
- expect( body ).to be_a( Hash )
280
- expect( body.length ).to eq( 3 )
281
- expect( body ).to include( 'duir-ssh', 'yevaud-ssh', 'sidonie-ssh' )
282
- end
283
-
284
-
285
- it "returns only identifiers if the `return` header is set to `nil`" do
286
- msg = pack_message( :fetch, {return: nil}, type: 'service', port: 22 )
287
-
288
- sock.send( msg )
289
- resmsg = sock.recv
290
-
291
- hdr, body = unpack_message( resmsg )
292
- expect( hdr ).to include( 'success' => true )
293
- expect( body ).to be_a( Hash )
294
- expect( body.length ).to eq( 3 )
295
- expect( body ).to include( 'duir-ssh', 'yevaud-ssh', 'sidonie-ssh' )
296
- expect( body.values ).to all( be_empty )
297
- end
298
-
299
-
300
- it "returns only specified state if the `return` header is set to an Array of keys" do
301
- msg = pack_message( :fetch, {return: %w[status tags addresses]},
302
- type: 'service', port: 22 )
303
-
304
- sock.send( msg )
305
- resmsg = sock.recv
306
-
307
- hdr, body = unpack_message( resmsg )
308
- expect( hdr ).to include( 'success' => true )
309
- expect( body.length ).to eq( 3 )
310
- expect( body ).to include( 'duir-ssh', 'yevaud-ssh', 'sidonie-ssh' )
311
- expect( body.values.map(&:keys) ).to all( contain_exactly('status', 'tags', 'addresses') )
312
- end
313
-
314
-
315
- end
316
-
317
-
318
- describe "list" do
319
-
320
- it "returns an array of node state" do
321
- msg = pack_message( :list )
322
- sock.send( msg )
323
- resmsg = sock.recv
324
-
325
- hdr, body = unpack_message( resmsg )
326
- expect( hdr ).to include( 'success' => true )
327
- expect( body.length ).to eq( manager.nodes.length )
328
- expect( body ).to all( be_a(Hash) )
329
- expect( body ).to include( hash_including('identifier' => '_') )
330
- expect( body ).to include( hash_including('identifier' => 'duir') )
331
- expect( body ).to include( hash_including('identifier' => 'sidonie') )
332
- expect( body ).to include( hash_including('identifier' => 'sidonie-ssh') )
333
- expect( body ).to include( hash_including('identifier' => 'sidonie-demon-http') )
334
- expect( body ).to include( hash_including('identifier' => 'yevaud') )
335
- end
336
-
337
- it "can be limited by depth" do
338
- msg = pack_message( :list, {depth: 1}, nil )
339
- sock.send( msg )
340
- resmsg = sock.recv
341
-
342
- hdr, body = unpack_message( resmsg )
343
- expect( hdr ).to include( 'success' => true )
344
- expect( body.length ).to eq( 3 )
345
- expect( body ).to all( be_a(Hash) )
346
- expect( body ).to include( hash_including('identifier' => '_') )
347
- expect( body ).to include( hash_including('identifier' => 'duir') )
348
- expect( body ).to_not include( hash_including('identifier' => 'duir-ssh') )
349
- end
350
- end
351
-
352
-
353
- describe "update" do
354
-
355
- it "merges the properties sent with those of the targeted nodes" do
356
- update_data = {
357
- duir: {
358
- ping: {
359
- rtt: 254
360
- }
361
- },
362
- sidonie: {
363
- ping: {
364
- rtt: 1208
365
- }
366
- },
367
- yevaud: {
368
- ping: {
369
- rtt: 843
370
- }
371
- }
372
- }
373
- msg = pack_message( :update, update_data )
374
- sock.send( msg )
375
- resmsg = sock.recv
376
-
377
- hdr, body = unpack_message( resmsg )
378
- expect( hdr ).to include( 'success' => true )
379
- expect( body ).to be_nil
380
-
381
- expect( manager.nodes['duir'].properties['ping'] ).to include( 'rtt' => 254 )
382
- expect( manager.nodes['sidonie'].properties['ping'] ).to include( 'rtt' => 1208 )
383
- expect( manager.nodes['yevaud'].properties['ping'] ).to include( 'rtt' => 843 )
384
- end
385
-
386
-
387
- it "ignores unknown identifiers" do
388
- msg = pack_message( :update, charlie_humperton: {ping: { rtt: 8 }} )
389
- sock.send( msg )
390
- resmsg = sock.recv
391
-
392
- hdr, body = unpack_message( resmsg )
393
- expect( hdr ).to include( 'success' => true )
394
- end
395
-
396
- it "fails with a client error if the body is invalid" do
397
- msg = pack_message( :update, nil )
398
- sock.send( msg )
399
- resmsg = sock.recv
400
-
401
- hdr, body = unpack_message( resmsg )
402
- expect( hdr ).to include( 'success' => false )
403
- expect( hdr['reason'] ).to match( /respond to #each/ )
404
- end
405
- end
406
-
407
-
408
- describe "subscribe" do
409
-
410
- it "adds a subscription for all event types to the root node by default" do
411
- msg = pack_message( :subscribe, [{}, {}] )
412
-
413
- resmsg = nil
414
- expect {
415
- sock.send( msg )
416
- resmsg = sock.recv
417
- }.to change { manager.subscriptions.length }.by( 1 ).and(
418
- change { manager.root.subscriptions.length }.by( 1 )
419
- )
420
- hdr, body = unpack_message( resmsg )
421
-
422
- sub_id = manager.subscriptions.keys.first
423
-
424
- expect( hdr ).to include( 'success' => true )
425
- expect( body ).to eq([ sub_id ])
426
- end
427
-
428
-
429
- it "adds a subscription to the specified node if an identifier is specified" do
430
- msg = pack_message( :subscribe, {identifier: 'sidonie'}, [{}, {}] )
431
-
432
- resmsg = nil
433
- expect {
434
- sock.send( msg )
435
- resmsg = sock.recv
436
- }.to change { manager.subscriptions.length }.by( 1 ).and(
437
- change { manager.nodes['sidonie'].subscriptions.length }.by( 1 )
438
- )
439
- hdr, body = unpack_message( resmsg )
440
-
441
- sub_id = manager.subscriptions.keys.first
442
-
443
- expect( hdr ).to include( 'success' => true )
444
- expect( body ).to eq([ sub_id ])
445
- end
446
-
447
-
448
- it "adds a subscription for particular event types if one is specified" do
449
- msg = pack_message( :subscribe, {event_type: 'node.acked'}, [{}, {}] )
450
-
451
- resmsg = nil
452
- expect {
453
- sock.send( msg )
454
- resmsg = sock.recv
455
- }.to change { manager.subscriptions.length }.by( 1 ).and(
456
- change { manager.root.subscriptions.length }.by( 1 )
457
- )
458
- hdr, body = unpack_message( resmsg )
459
- node = manager.subscriptions[ body.first ]
460
- sub = node.subscriptions[ body.first ]
461
-
462
- expect( sub.event_type ).to eq( 'node.acked' )
463
- end
464
-
465
-
466
- it "adds a subscription for events which match a pattern if one is specified" do
467
- criteria = { type: 'host' }
468
-
469
- msg = pack_message( :subscribe, [criteria, {}] )
470
-
471
- resmsg = nil
472
- expect {
473
- sock.send( msg )
474
- resmsg = sock.recv
475
- }.to change { manager.subscriptions.length }.by( 1 ).and(
476
- change { manager.root.subscriptions.length }.by( 1 )
477
- )
478
- hdr, body = unpack_message( resmsg )
479
- node = manager.subscriptions[ body.first ]
480
- sub = node.subscriptions[ body.first ]
481
-
482
- expect( sub.event_type ).to be_nil
483
- expect( sub.criteria ).to eq({ 'type' => 'host' })
484
- end
485
-
486
-
487
- it "adds a subscription for events which don't match a pattern if an exclusion pattern is given" do
488
- criteria = { type: 'host' }
489
-
490
- msg = pack_message( :subscribe, [{}, criteria] )
491
-
492
- resmsg = nil
493
- expect {
494
- sock.send( msg )
495
- resmsg = sock.recv
496
- }.to change { manager.subscriptions.length }.by( 1 ).and(
497
- change { manager.root.subscriptions.length }.by( 1 )
498
- )
499
- hdr, body = unpack_message( resmsg )
500
- node = manager.subscriptions[ body.first ]
501
- sub = node.subscriptions[ body.first ]
502
-
503
- expect( sub.event_type ).to be_nil
504
- expect( sub.negative_criteria ).to eq({ 'type' => 'host' })
505
- end
506
-
507
- end
508
-
509
-
510
- describe "unsubscribe" do
511
-
512
- let( :subscription ) do
513
- manager.create_subscription( nil, 'node.delta', {type: 'host'} )
514
- end
515
-
516
-
517
- it "removes the subscription with the specified ID" do
518
- msg = pack_message( :unsubscribe, {subscription_id: subscription.id}, nil )
519
-
520
- resmsg = nil
521
- expect {
522
- sock.send( msg )
523
- resmsg = sock.recv
524
- }.to change { manager.subscriptions.length }.by( -1 ).and(
525
- change { manager.root.subscriptions.length }.by( -1 )
526
- )
527
- hdr, body = unpack_message( resmsg )
528
-
529
- expect( body ).to include( 'event_type' => 'node.delta', 'criteria' => {'type' => 'host'} )
530
- end
531
-
532
-
533
- it "ignores unsubscription of a non-existant ID" do
534
- msg = pack_message( :unsubscribe, {subscription_id: 'the bears!'}, nil )
535
-
536
- resmsg = nil
537
- expect {
538
- sock.send( msg )
539
- resmsg = sock.recv
540
- }.to_not change { manager.subscriptions.length }
541
- hdr, body = unpack_message( resmsg )
542
-
543
- expect( body ).to be_nil
544
- end
545
-
546
- end
547
-
548
-
549
- describe "prune" do
550
-
551
- it "removes a single node" do
552
- msg = pack_message( :prune, {identifier: 'duir-ssh'}, nil )
553
- sock.send( msg )
554
- resmsg = sock.recv
555
-
556
- hdr, body = unpack_message( resmsg )
557
- expect( hdr ).to include( 'success' => true )
558
- expect( body ).to eq( true )
559
- expect( manager.nodes ).to_not include( 'duir-ssh' )
560
- end
561
-
562
-
563
- it "returns Nil without error if the node to prune didn't exist" do
564
- msg = pack_message( :prune, {identifier: 'shemp-ssh'}, nil )
565
- sock.send( msg )
566
- resmsg = sock.recv
567
-
568
- hdr, body = unpack_message( resmsg )
569
- expect( hdr ).to include( 'success' => true )
570
- expect( body ).to be_nil
571
- end
572
-
573
-
574
- it "removes children nodes along with the parent" do
575
- msg = pack_message( :prune, {identifier: 'duir'}, nil )
576
- sock.send( msg )
577
- resmsg = sock.recv
578
-
579
- hdr, body = unpack_message( resmsg )
580
- expect( hdr ).to include( 'success' => true )
581
- expect( body ).to eq( true )
582
- expect( manager.nodes ).to_not include( 'duir' )
583
- expect( manager.nodes ).to_not include( 'duir-ssh' )
584
- end
585
-
586
-
587
- it "returns an error to the client when missing required attributes" do
588
- msg = pack_message( :prune )
589
- sock.send( msg )
590
- resmsg = sock.recv
591
-
592
- hdr, body = unpack_message( resmsg )
593
- expect( hdr ).to include( 'success' => false )
594
- expect( hdr['reason'] ).to match( /no identifier/i )
595
- end
596
- end
597
-
598
-
599
- describe "graft" do
600
-
601
- it "can add a node with no explicit parent" do
602
- header = {
603
- identifier: 'guenter',
604
- type: 'host',
605
- }
606
- attributes = {
607
- description: 'The evil penguin node of doom.',
608
- addresses: ['10.2.66.8'],
609
- tags: ['internal', 'football']
610
- }
611
- msg = pack_message( :graft, header, attributes )
612
-
613
- sock.send( msg )
614
- resmsg = sock.recv
615
-
616
- hdr, body = unpack_message( resmsg )
617
- expect( hdr ).to include( 'success' => true )
618
- expect( body ).to eq( 'guenter' )
619
-
620
- new_node = manager.nodes[ 'guenter' ]
621
- expect( new_node ).to be_a( Arborist::Node::Host )
622
- expect( new_node.identifier ).to eq( header[:identifier] )
623
- expect( new_node.description ).to eq( attributes[:description] )
624
- expect( new_node.addresses ).to eq([ IPAddr.new(attributes[:addresses].first) ])
625
- expect( new_node.tags ).to include( *attributes[:tags] )
626
- end
627
-
628
-
629
- it "can add a node with a parent specified" do
630
- header = {
631
- identifier: 'orgalorg',
632
- type: 'host',
633
- parent: 'duir'
634
- }
635
- attributes = {
636
- description: 'The true form of the evil penguin node of doom.',
637
- addresses: ['192.168.22.8'],
638
- tags: ['evil', 'space', 'entity']
639
- }
640
- msg = pack_message( :graft, header, attributes )
641
-
642
- sock.send( msg )
643
- resmsg = sock.recv
644
-
645
- hdr, body = unpack_message( resmsg )
646
- expect( hdr ).to include( 'success' => true )
647
- expect( body ).to eq( 'orgalorg' )
648
-
649
- new_node = manager.nodes[ 'orgalorg' ]
650
- expect( new_node ).to be_a( Arborist::Node::Host )
651
- expect( new_node.identifier ).to eq( header[:identifier] )
652
- expect( new_node.parent ).to eq( header[:parent] )
653
- expect( new_node.description ).to eq( attributes[:description] )
654
- expect( new_node.addresses ).to eq([ IPAddr.new(attributes[:addresses].first) ])
655
- expect( new_node.tags ).to include( *attributes[:tags] )
656
- end
657
-
658
-
659
- it "can add a subordinate node" do
660
- header = {
661
- identifier: 'echo',
662
- type: 'service',
663
- parent: 'duir'
664
- }
665
- attributes = {
666
- description: 'Mmmmm AppleTalk.'
667
- }
668
- msg = pack_message( :graft, header, attributes )
669
-
670
- sock.send( msg )
671
- resmsg = sock.recv
672
-
673
- hdr, body = unpack_message( resmsg )
674
- expect( hdr ).to include( 'success' => true )
675
- expect( body ).to eq( 'duir-echo' )
676
-
677
- new_node = manager.nodes[ 'duir-echo' ]
678
- expect( new_node ).to be_a( Arborist::Node::Service )
679
- expect( new_node.identifier ).to eq( 'duir-echo' )
680
- expect( new_node.parent ).to eq( header[:parent] )
681
- expect( new_node.description ).to eq( attributes[:description] )
682
- expect( new_node.port ).to eq( 7 )
683
- expect( new_node.protocol ).to eq( 'tcp' )
684
- expect( new_node.app_protocol ).to eq( 'echo' )
685
- end
686
-
687
-
688
- it "errors if adding a subordinate node with no parent" do
689
- header = {
690
- identifier: 'echo',
691
- type: 'service'
692
- }
693
- attributes = {
694
- description: 'Mmmmm AppleTalk.'
695
- }
696
- msg = pack_message( :graft, header, attributes )
697
-
698
- sock.send( msg )
699
- resmsg = sock.recv
700
-
701
- hdr, body = unpack_message( resmsg )
702
- expect( hdr ).to include( 'success' => false )
703
- expect( hdr['reason'] ).to match( /no host given/i )
704
- end
705
-
706
- end
707
-
708
-
709
- describe "modify" do
710
-
711
- it "can change operational attributes of a node" do
712
- header = {
713
- identifier: 'sidonie',
714
- }
715
- attributes = {
716
- parent: '_',
717
- addresses: ['192.168.32.32', '10.2.2.28']
718
- }
719
- msg = pack_message( :modify, header, attributes )
720
-
721
- sock.send( msg )
722
- resmsg = sock.recv
723
-
724
- hdr, body = unpack_message( resmsg )
725
- expect( hdr ).to include( 'success' => true )
726
-
727
- node = manager.nodes[ 'sidonie' ]
728
- expect(
729
- node.addresses
730
- ).to eq( [IPAddr.new('192.168.32.32'), IPAddr.new('10.2.2.28')] )
731
- expect( node.parent ).to eq( '_' )
732
- end
733
-
734
-
735
- it "ignores modifications to unsupported attributes" do
736
- header = {
737
- identifier: 'sidonie',
738
- }
739
- attributes = {
740
- identifier: 'somethingelse'
741
- }
742
- msg = pack_message( :modify, header, attributes )
743
-
744
- sock.send( msg )
745
- resmsg = sock.recv
746
-
747
- hdr, body = unpack_message( resmsg )
748
- expect( hdr ).to include( 'success' => true )
749
-
750
- expect( manager.nodes['sidonie'] ).to be_an( Arborist::Node )
751
- expect( manager.nodes['sidonie'].identifier ).to eq( 'sidonie' )
752
- end
753
-
754
-
755
- it "errors on modifications to the root node" do
756
- header = {
757
- identifier: '_',
758
- }
759
- attributes = {
760
- identifier: 'somethingelse'
761
- }
762
- msg = pack_message( :modify, header, attributes )
763
-
764
- sock.send( msg )
765
- resmsg = sock.recv
766
-
767
- hdr, body = unpack_message( resmsg )
768
- expect( hdr ).to include( 'success' => false )
769
- expect( manager.nodes['_'].identifier ).to eq( '_' )
770
- end
771
-
772
-
773
- it "errors on modifications to nonexistent nodes" do
774
- header = {
775
- identifier: 'nopenopenope',
776
- }
777
- attributes = {
778
- identifier: 'somethingelse'
779
- }
780
- msg = pack_message( :modify, header, attributes )
781
-
782
- sock.send( msg )
783
- resmsg = sock.recv
784
-
785
- hdr, body = unpack_message( resmsg )
786
- expect( hdr ).to include( 'success' => false )
787
- end
788
- end
789
-
790
- end
791
-