flok 0.0.40 → 0.0.41

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/app/drivers/chrome/src/dispatch.js +7 -2
  3. data/app/kern/dispatch.js +10 -1
  4. data/app/kern/mod/event.js +9 -0
  5. data/app/kern/pagers/pg_mem.js +21 -0
  6. data/app/kern/pagers/pg_net_sim.js +44 -0
  7. data/app/kern/pagers/pg_spec.js +23 -0
  8. data/app/kern/services/vm.rb +60 -64
  9. data/bin/flok +44 -23
  10. data/docs/callout.md +1 -1
  11. data/docs/client_api.md +5 -2
  12. data/docs/config_yml.md +41 -0
  13. data/docs/controllers.md +4 -0
  14. data/docs/datatypes.md +5 -2
  15. data/docs/debug_server.md +2 -0
  16. data/docs/dispatch.md +8 -3
  17. data/docs/known_issues.md +6 -0
  18. data/docs/mod/event.md +25 -20
  19. data/docs/mod/persist.md +1 -1
  20. data/docs/mod/speech.md +12 -0
  21. data/docs/project.md +2 -2
  22. data/docs/services/vm.md +46 -17
  23. data/docs/services/vm/pagers.md +22 -2
  24. data/lib/flok/build.rb +0 -4
  25. data/lib/flok/user_compiler.rb +123 -47
  26. data/lib/flok/user_compiler_templates/ctable.js.erb +39 -1
  27. data/lib/flok/version.rb +1 -1
  28. data/spec/env/global.rb +1 -0
  29. data/spec/env/kern.rb +5 -1
  30. data/spec/etc/cli_spec.rb +337 -322
  31. data/spec/etc/service_compiler/config0.rb +1 -1
  32. data/spec/etc/service_compiler/config0b.rb +1 -0
  33. data/spec/etc/services_compiler_spec.rb +29 -29
  34. data/spec/etc/user_compiler/controller0b.rb +9 -0
  35. data/spec/etc/user_compiler/controller0timer.rb +16 -0
  36. data/spec/etc/user_compiler_spec.rb +24 -1
  37. data/spec/iface/driver/dispatch_spec.rb +8 -2
  38. data/spec/iface/driver/persist_spec.rb +11 -0
  39. data/spec/kern/assets/controller0defer.rb +18 -0
  40. data/spec/kern/assets/controller0defer0.rb +13 -0
  41. data/spec/kern/assets/controller0defer2.rb +17 -0
  42. data/spec/kern/assets/global_on_entry.rb +8 -0
  43. data/spec/kern/assets/global_on_entry2.rb +16 -0
  44. data/spec/kern/assets/global_on_entry3.rb +17 -0
  45. data/spec/kern/assets/global_on_entry4.rb +12 -0
  46. data/spec/kern/assets/interval.rb +29 -0
  47. data/spec/kern/assets/interval2.rb +33 -0
  48. data/spec/kern/assets/interval3.rb +39 -0
  49. data/spec/kern/assets/service1.rb +4 -1
  50. data/spec/kern/assets/service_controller1.rb +11 -0
  51. data/spec/kern/assets/specimin/controller0.rb +74 -0
  52. data/spec/kern/assets/vm/config5.rb +20 -0
  53. data/spec/kern/assets/vm/config6.rb +20 -0
  54. data/spec/kern/assets/vm/controller10.rb +1 -1
  55. data/spec/kern/assets/vm/controller11.rb +1 -1
  56. data/spec/kern/assets/vm/controller12.rb +1 -1
  57. data/spec/kern/assets/vm/controller13.rb +1 -1
  58. data/spec/kern/assets/vm/controller16b.rb +28 -0
  59. data/spec/kern/assets/vm/controller18.rb +1 -1
  60. data/spec/kern/assets/vm/controller21.rb +1 -1
  61. data/spec/kern/assets/vm/controller22.rb +8 -0
  62. data/spec/kern/assets/vm/controller_exc_ewatch.rb +1 -0
  63. data/spec/kern/assets/vm/controller_exc_ewatch2.rb +30 -0
  64. data/spec/kern/assets/vm/controller_exc_ewatch3.rb +16 -0
  65. data/spec/kern/assets/vm/controller_exc_ewatch4.rb +16 -0
  66. data/spec/kern/assets/vm/macros/copy_page_c.rb +1 -0
  67. data/spec/kern/assets/vm/macros/copy_page_ch.rb +25 -0
  68. data/spec/kern/assets/vm/macros/entry_del_c.rb +1 -0
  69. data/spec/kern/assets/vm/macros/entry_del_ch.rb +20 -0
  70. data/spec/kern/assets/vm/macros/entry_insert_c.rb +1 -0
  71. data/spec/kern/assets/vm/macros/entry_insert_ch.rb +23 -0
  72. data/spec/kern/assets/vm/macros/entry_mutable_c.rb +8 -7
  73. data/spec/kern/assets/vm/macros/entry_mutable_ch.rb +34 -0
  74. data/spec/kern/assets/vm/macros/new_page_c.rb +1 -1
  75. data/spec/kern/assets/vm/macros/new_page_c2.rb +1 -1
  76. data/spec/kern/assets/vm/macros/new_page_ch.rb +7 -0
  77. data/spec/kern/assets/vm/pg_mem/config.rb +10 -0
  78. data/spec/kern/assets/vm/pg_mem/config1.rb +10 -0
  79. data/spec/kern/assets/vm/pg_mem/config2.rb +10 -0
  80. data/spec/kern/assets/vm/pg_mem/config3.rb +15 -0
  81. data/spec/kern/assets/vm/pg_mem/write.rb +23 -0
  82. data/spec/kern/assets/vm/pg_mem/write2.rb +38 -0
  83. data/spec/kern/assets/vm/pg_net_sim/config.rb +10 -0
  84. data/spec/kern/assets/vm/pg_net_sim/nothing.rb +12 -0
  85. data/spec/kern/assets/vm/pg_net_sim/pages.json +1 -0
  86. data/spec/kern/assets/vm/pg_net_sim/watch.rb +18 -0
  87. data/spec/kern/callout_spec.rb +1 -1
  88. data/spec/kern/controller_macro_spec.rb +153 -20
  89. data/spec/kern/controller_spec.rb +232 -1
  90. data/spec/kern/debug_ui_spec.rb +235 -235
  91. data/spec/kern/event_spec.rb +112 -0
  92. data/spec/kern/service_controller_spec.rb +14 -2
  93. data/spec/kern/vm_service_mem_pagers_spec.rb +117 -0
  94. data/spec/kern/vm_service_net_sim_pager_spec.rb +97 -0
  95. data/spec/kern/vm_service_spec.rb +304 -17
  96. data/spec/kern/vm_service_spec2.rb +39 -0
  97. metadata +88 -6
  98. data/app/kern/pagers/mem_pager.js +0 -2
  99. data/app/kern/pagers/pg_spec0.js +0 -20
  100. data/lib/flok/project_template/Guardfile +0 -7
  101. data/lib/flok/project_template/config/config.yml +0 -1
@@ -0,0 +1,112 @@
1
+ Dir.chdir File.join File.dirname(__FILE__), '../../'
2
+ require './spec/env/kern.rb'
3
+ require './spec/lib/helpers.rb'
4
+ require './spec/lib/io_extensions.rb'
5
+ require './spec/lib/rspec_extensions.rb'
6
+
7
+ RSpec.describe "kern:event_spec" do
8
+ include_context "kern"
9
+
10
+ it "Can call int_event_defer" do
11
+ #Compile the controller
12
+ ctx = flok_new_user File.read('./spec/kern/assets/controller0.rb')
13
+
14
+ #Register callout
15
+ ctx.eval %{
16
+ base = _embed("my_controller", 0, {}, null);
17
+
18
+ //Queue up a deferred event
19
+ int_event_defer(base, "defer_res", {});
20
+ }
21
+
22
+ edefer_q = ctx.dump("edefer_q")
23
+ base = ctx.eval("base")
24
+ expect(edefer_q).to eq([
25
+ base, "defer_res", {}
26
+ ])
27
+ end
28
+
29
+ it "Does call if_dispatch with an 'i' for incomplete" do
30
+ #Compile the controller
31
+ ctx = flok_new_user File.read('./spec/kern/assets/controller0.rb')
32
+
33
+ #Register callout
34
+ ctx.eval %{
35
+ base = _embed("my_controller", 0, {}, null);
36
+
37
+ //Queue up two deferred event b/c the first will get eaten
38
+ int_event_defer(base, "defer_res", {});
39
+ int_event_defer(base, "defer_res", {});
40
+
41
+ //Drain queue
42
+ int_dispatch([]);
43
+ }
44
+
45
+ #Incomplete should have been added
46
+ q = @driver.dump_q
47
+ expect(q[0]).to eq("i")
48
+ end
49
+
50
+ it "Does call the event trigger for the controller after the dispatch" do
51
+ #Compile the controller
52
+ ctx = flok_new_user File.read('./spec/kern/assets/controller0defer.rb')
53
+
54
+ #Register callout
55
+ ctx.eval %{
56
+ base = _embed("my_controller", 0, {}, null);
57
+ }
58
+
59
+ #At this point, the synchronous event should have been dispatched in the _embed
60
+ #because int_event is located in the controller on_entry
61
+ sync_res_params = ctx.dump("sync_res_params")
62
+ expect(sync_res_params).to eq({
63
+ "foo_sync" => "bar"
64
+ })
65
+
66
+ #But the deferred response should only be available during the
67
+ #next int_disp
68
+ expect {
69
+ ctx.dump("defer_res_params")
70
+ }.to raise_exception
71
+
72
+ ctx.eval("int_dispatch([])")
73
+
74
+ #At this point, we only have one int_dispatch, so the event
75
+ #should never have been de-queued because it will on teh second one
76
+ defer_res_params = ctx.dump("defer_res_params")
77
+ expect(defer_res_params).to eq({
78
+ "foo" => "bar"
79
+ })
80
+ end
81
+
82
+ it "Does call the event trigger for the controller after the dispatch only one at a time" do
83
+ #Compile the controller
84
+ ctx = flok_new_user File.read('./spec/kern/assets/controller0defer2.rb')
85
+
86
+ #Register callout
87
+ ctx.eval %{
88
+ base = _embed("my_controller", 0, {}, null);
89
+ int_dispatch([]);
90
+ }
91
+
92
+ #Should have dequeued the first asynchronous event callback
93
+ defer_res_params = ctx.dump("defer_res_params")
94
+ expect(defer_res_params).to eq({
95
+ "foo" => "bar"
96
+ })
97
+
98
+ #But the second one should not have dequeued yet
99
+ expect {
100
+ ctx.dump("defer_res2_params")
101
+ }.to raise_exception
102
+
103
+ #Until we throw another int_dispatch
104
+ ctx.eval("int_dispatch([])")
105
+
106
+ #And now it should be there
107
+ defer_res2_params = ctx.dump("defer_res2_params")
108
+ expect(defer_res2_params).to eq({
109
+ "foo" => "bar"
110
+ })
111
+ end
112
+ end
@@ -140,7 +140,7 @@ RSpec.describe "kern:service_controller_spec" do
140
140
  int_dispatch([3, "int_event", base, "next", {}]);
141
141
  }
142
142
 
143
- 100.times do
143
+ 103.times do
144
144
  @driver.int "int_timer"
145
145
  end
146
146
 
@@ -150,11 +150,23 @@ RSpec.describe "kern:service_controller_spec" do
150
150
  int_dispatch([3, "int_event", base, "next", {}]);
151
151
  }
152
152
 
153
+ #Should fire 25 times, but not the 26th
154
+ 103.times do
155
+ @driver.int "int_timer"
156
+ end
157
+
158
+ #Switch back into the action
159
+ ctx.eval %{
160
+ //Drain queue
161
+ int_dispatch([3, "int_event", base, "next", {}]);
162
+ int_dispatch([3, "int_event", base, "next", {}]);
163
+ }
164
+
153
165
  100.times do
154
166
  @driver.int "int_timer"
155
167
  end
156
168
 
157
- expect(ctx.eval("every_ticks")).to eq(25)
169
+ expect(ctx.eval("every_ticks")).to eq(50)
158
170
  end
159
171
 
160
172
  it "Does have all the right variables after sending a custom event to the service and a timer event has fired" do
@@ -0,0 +1,117 @@
1
+ #The pg_mem0 pager
2
+
3
+ Dir.chdir File.join File.dirname(__FILE__), '../../'
4
+ require './spec/env/kern.rb'
5
+ require './spec/lib/helpers.rb'
6
+ require './spec/lib/io_extensions.rb'
7
+ require './spec/lib/rspec_extensions.rb'
8
+ require 'zlib'
9
+
10
+ RSpec.describe "kern:vm_service_mem_pagers" do
11
+ include Zlib
12
+ include_context "kern"
13
+
14
+ it "Can initialize the pg_mem0 pager" do
15
+ ctx = flok_new_user File.read('./spec/kern/assets/vm/controller0.rb'), File.read("./spec/kern/assets/vm/pg_mem/config.rb")
16
+ ctx.eval %{
17
+ //Call embed on main root view
18
+ base = _embed("my_controller", 0, {}, null);
19
+
20
+ //Drain queue
21
+ int_dispatch([]);
22
+ }
23
+
24
+ res = ctx.eval("pg_mem0_spec_did_init")
25
+ expect(res).to eq(true)
26
+ end
27
+
28
+ it "Can make a write request to pg_mem0 and have that written in cache" do
29
+ ctx = flok_new_user File.read('./spec/kern/assets/vm/pg_mem/write.rb'), File.read("./spec/kern/assets/vm/pg_mem/config.rb")
30
+ ctx.eval %{
31
+ //Call embed on main root view
32
+ base = _embed("my_controller", 0, {}, null);
33
+
34
+ //Drain queue
35
+ int_dispatch([]);
36
+ }
37
+
38
+ page = ctx.dump "page"
39
+ vm_cache = ctx.dump("vm_cache")
40
+ expect(page).to eq(vm_cache["local"]["test"])
41
+ end
42
+
43
+ it "Can initialize the pg_mem1 pager" do
44
+ ctx = flok_new_user File.read('./spec/kern/assets/vm/controller0.rb'), File.read("./spec/kern/assets/vm/pg_mem/config1.rb")
45
+ ctx.eval %{
46
+ //Call embed on main root view
47
+ base = _embed("my_controller", 0, {}, null);
48
+
49
+ //Drain queue
50
+ int_dispatch([]);
51
+ }
52
+
53
+ res = ctx.eval("pg_mem1_spec_did_init")
54
+ expect(res).to eq(true)
55
+ end
56
+
57
+ it "Can make a write request to pg_mem1 and have that written in cache" do
58
+ ctx = flok_new_user File.read('./spec/kern/assets/vm/pg_mem/write.rb'), File.read("./spec/kern/assets/vm/pg_mem/config1.rb")
59
+ ctx.eval %{
60
+ //Call embed on main root view
61
+ base = _embed("my_controller", 0, {}, null);
62
+
63
+ //Drain queue
64
+ int_dispatch([]);
65
+ }
66
+
67
+ page = ctx.dump "page"
68
+ vm_cache = ctx.dump("vm_cache")
69
+ expect(page).to eq(vm_cache["local"]["test"])
70
+ end
71
+
72
+ it "Can initialize the pg_mem2 pager" do
73
+ ctx = flok_new_user File.read('./spec/kern/assets/vm/controller0.rb'), File.read("./spec/kern/assets/vm/pg_mem/config2.rb")
74
+ ctx.eval %{
75
+ //Call embed on main root view
76
+ base = _embed("my_controller", 0, {}, null);
77
+
78
+ //Drain queue
79
+ int_dispatch([]);
80
+ }
81
+
82
+ res = ctx.eval("pg_mem2_spec_did_init")
83
+ expect(res).to eq(true)
84
+ end
85
+
86
+ it "Can make a write request to pg_mem2 and have that written in cache" do
87
+ ctx = flok_new_user File.read('./spec/kern/assets/vm/pg_mem/write.rb'), File.read("./spec/kern/assets/vm/pg_mem/config2.rb")
88
+ ctx.eval %{
89
+ //Call embed on main root view
90
+ base = _embed("my_controller", 0, {}, null);
91
+
92
+ //Drain queue
93
+ int_dispatch([]);
94
+ }
95
+
96
+ page = ctx.dump "page"
97
+ vm_cache = ctx.dump("vm_cache")
98
+ expect(page).to eq(vm_cache["local"]["test"])
99
+ end
100
+
101
+ it "Can use pg_mem0 and pg_mem1 at the same time" do
102
+ ctx = flok_new_user File.read('./spec/kern/assets/vm/pg_mem/write2.rb'), File.read("./spec/kern/assets/vm/pg_mem/config3.rb")
103
+ ctx.eval %{
104
+ //Call embed on main root view
105
+ base = _embed("my_controller", 0, {}, null);
106
+
107
+ //Drain queue
108
+ int_dispatch([]);
109
+ }
110
+
111
+ page = ctx.dump "page"
112
+ page2 = ctx.dump "page2"
113
+ vm_cache = ctx.dump("vm_cache")
114
+ expect(page).to eq(vm_cache["local0"]["test"])
115
+ expect(page2).to eq(vm_cache["local1"]["test"])
116
+ end
117
+ end
@@ -0,0 +1,97 @@
1
+ #The pg_mem0 pager
2
+
3
+ Dir.chdir File.join File.dirname(__FILE__), '../../'
4
+ require './spec/env/kern.rb'
5
+ require './spec/lib/helpers.rb'
6
+ require './spec/lib/io_extensions.rb'
7
+ require './spec/lib/rspec_extensions.rb'
8
+ require 'zlib'
9
+
10
+ RSpec.describe "kern:vm_service_net_sim_pager" do
11
+ include Zlib
12
+ include_context "kern"
13
+
14
+ it "Can initialize the pg_net_sim pager" do
15
+ ctx = flok_new_user File.read('./spec/kern/assets/vm/pg_net_sim/nothing.rb'), File.read("./spec/kern/assets/vm/pg_net_sim/config.rb")
16
+ ctx.eval %{
17
+ //Call embed on main root view
18
+ base = _embed("my_controller", 0, {}, null);
19
+
20
+ //Drain queue
21
+ int_dispatch([]);
22
+ }
23
+
24
+ res = ctx.eval("pg_net_sim_spec_did_init")
25
+ expect(res).to eq(true)
26
+ end
27
+
28
+ it "Can load the pg_net_sim pager with data" do
29
+ ctx = flok_new_user File.read('./spec/kern/assets/vm/pg_net_sim/nothing.rb'), File.read("./spec/kern/assets/vm/pg_net_sim/config.rb")
30
+ ctx.eval %{
31
+ //Call embed on main root view
32
+ base = _embed("my_controller", 0, {}, null);
33
+
34
+ //Drain queue
35
+ int_dispatch([]);
36
+
37
+ var json = #{File.read("./spec/kern/assets/vm/pg_net_sim/pages.json")};
38
+ pg_net_sim_load_pages(json)
39
+ }
40
+
41
+ pg_net_sim_stored_pages = ctx.dump("pg_net_sim_stored_pages")
42
+ res = ctx.eval("pg_net_sim_spec_did_init")
43
+ expect(res).to eq(true)
44
+
45
+ #Simulate cache build for pages, the pg_net_sim stores like vm_cache from array
46
+ pages = JSON.parse(File.read("./spec/kern/assets/vm/pg_net_sim/pages.json"))
47
+ pages_cache = {}
48
+ pages.each do |p|
49
+ pages_cache[p["_id"]] = p
50
+ end
51
+ expect(pg_net_sim_stored_pages).to eq(pages_cache)
52
+ end
53
+
54
+ it "Can watch pg_net_sim and not get a response back before 2 seconds (by design)" do
55
+ ctx = flok_new_user File.read('./spec/kern/assets/vm/pg_net_sim/watch.rb'), File.read("./spec/kern/assets/vm/pg_net_sim/config.rb")
56
+ ctx.eval %{
57
+ var json = #{File.read("./spec/kern/assets/vm/pg_net_sim/pages.json")};
58
+ pg_net_sim_load_pages(json)
59
+
60
+ //Call embed on main root view
61
+ base = _embed("my_controller", 0, {}, null);
62
+
63
+ //Drain queue
64
+ int_dispatch([]);
65
+ }
66
+
67
+ expect {
68
+ pages = JSON.parse(File.read("./spec/kern/assets/vm/pg_net_sim/pages.json"))
69
+ read_res_params = ctx.dump("read_res_params")
70
+ expect(read_res_params).to eq(pages[0])
71
+ }.to raise_error
72
+ end
73
+
74
+ it "Can watch pg_net_sim and get a response back after 2 seconds" do
75
+ ctx = flok_new_user File.read('./spec/kern/assets/vm/pg_net_sim/watch.rb'), File.read("./spec/kern/assets/vm/pg_net_sim/config.rb")
76
+ ctx.eval %{
77
+ var json = #{File.read("./spec/kern/assets/vm/pg_net_sim/pages.json")};
78
+ pg_net_sim_load_pages(json)
79
+
80
+ //Call embed on main root view
81
+ base = _embed("my_controller", 0, {}, null);
82
+
83
+ //Drain queue
84
+ int_dispatch([]);
85
+ }
86
+
87
+ (4*2).times do
88
+ @driver.int "int_timer"
89
+ end
90
+
91
+ ctx.eval "int_dispatch([]);"
92
+
93
+ pages = JSON.parse(File.read("./spec/kern/assets/vm/pg_net_sim/pages.json"))
94
+ read_res_params = ctx.dump("read_res_params")
95
+ expect(read_res_params).to eq(pages[0])
96
+ end
97
+ end
@@ -11,7 +11,30 @@ RSpec.describe "kern:vm_service" do
11
11
  include Zlib
12
12
  include_context "kern"
13
13
 
14
- it "vm_rehash_page can calculate the hash correctly" do
14
+ it "Contains a preloaded vm_cache, vm_dirty, and vm_notify_map for each namespace with a blank hash" do
15
+ ctx = flok_new_user File.read('./spec/kern/assets/vm/controller0.rb'), File.read("./spec/kern/assets/vm/config5.rb")
16
+ ctx.eval %{
17
+ base = _embed("my_controller", 0, {}, null);
18
+
19
+ //Drain queue
20
+ int_dispatch([]);
21
+ }
22
+
23
+ vm_cache = ctx.dump("vm_cache")
24
+ vm_dirty = ctx.dump("vm_dirty")
25
+ vm_notify_map = ctx.dump("vm_notify_map")
26
+
27
+ res = {
28
+ "spec0" => {},
29
+ "spec1" => {}
30
+ }
31
+
32
+ expect(vm_cache).to eq(res)
33
+ expect(vm_dirty ).to eq(res)
34
+ expect(vm_notify_map).to eq(res)
35
+ end
36
+
37
+ it "vm_rehash_page can calculate the hash correctly for arrays" do
15
38
  ctx = flok_new_user File.read('./spec/kern/assets/vm/controller0.rb'), File.read("./spec/kern/assets/vm/config3.rb")
16
39
 
17
40
  #Run the check
@@ -19,6 +42,7 @@ it "vm_rehash_page can calculate the hash correctly" do
19
42
  //Manually construct a page
20
43
  var page = {
21
44
  _head: null,
45
+ _type: "array",
22
46
  _next: null,
23
47
  _id: "hello",
24
48
  entries: [
@@ -38,6 +62,7 @@ it "vm_rehash_page can calculate the hash correctly" do
38
62
  #Expect the same hash
39
63
  expect(page).to eq({
40
64
  "_head" => nil,
65
+ "_type" => "array",
41
66
  "_next" => nil,
42
67
  "_id" => "hello",
43
68
  "entries" => [
@@ -47,13 +72,63 @@ it "vm_rehash_page can calculate the hash correctly" do
47
72
  })
48
73
  end
49
74
 
50
- it "vm_rehash_page can calculate the hash correctly with head and next" do
75
+ it "vm_rehash_page can calculate the hash correctly for hashes" do
51
76
  ctx = flok_new_user File.read('./spec/kern/assets/vm/controller0.rb'), File.read("./spec/kern/assets/vm/config3.rb")
52
77
 
53
78
  #Run the check
54
79
  res = ctx.eval %{
55
80
  //Manually construct a page
56
81
  var page = {
82
+ _head: null,
83
+ "_type": "hash",
84
+ _next: null,
85
+ _id: "hello",
86
+ entries: {
87
+ "my_key": {_sig: "a"},
88
+ "my_key2": {_sig: "b"},
89
+ "my_key3": {_sig: "c"},
90
+ }
91
+ }
92
+
93
+ vm_rehash_page(page);
94
+ }
95
+
96
+ #Calculate hash ourselves
97
+ hash = crc32("hello")
98
+
99
+ #XOR the _sigs for the hash calculations
100
+ a = crc32("a", 0)
101
+ b = crc32("b", 0)
102
+ c = crc32("c", 0)
103
+ hash = crc32((a + b + c).to_s, hash)
104
+
105
+ page = JSON.parse(ctx.eval("JSON.stringify(page)"))
106
+ page = JSON.parse(ctx.eval("JSON.stringify(page)"))
107
+
108
+ #Expect the same hash
109
+ expect(page).to eq({
110
+ "_head" => nil,
111
+ "_next" => nil,
112
+ "_type" => "hash",
113
+ "_id" => "hello",
114
+ "entries" => {
115
+ "my_key" => {"_sig" => "a"},
116
+ "my_key2" => {"_sig" => "b"},
117
+ "my_key3" => {"_sig" => "c"},
118
+ },
119
+ "_hash" => hash.to_s
120
+ })
121
+ end
122
+
123
+
124
+ it "vm_rehash_page can calculate the hash correctly with head and next for an array" do
125
+ ctx = flok_new_user File.read('./spec/kern/assets/vm/controller0.rb'), File.read("./spec/kern/assets/vm/config3.rb")
126
+
127
+ #Run the check
128
+ res = ctx.eval %{
129
+ //Manually construct a page
130
+ var page = {
131
+ _type: "array",
57
132
  _head: "a",
58
133
  _next: "b",
59
134
  _id: "hello",
@@ -75,6 +150,7 @@ it "vm_rehash_page can calculate the hash correctly" do
75
150
  #Expect the same hash
76
151
  expect(page).to eq({
77
152
  "_head" => "a",
153
+ "_type" => "array",
78
154
  "_next" => "b",
79
155
  "_id" => "hello",
80
156
  "entries" => [
@@ -93,6 +169,7 @@ it "vm_rehash_page can calculate the hash correctly" do
93
169
  page = {
94
170
  _head: "a",
95
171
  _next: "b",
172
+ _type: "array",
96
173
  _id: "hello",
97
174
  entries: [
98
175
  {_id: "hello2", _sig: "nohteunth"},
@@ -167,6 +244,7 @@ it "vm_rehash_page can calculate the hash correctly" do
167
244
  _head: "a",
168
245
  _next: "b",
169
246
  _id: "my_key",
247
+ _type: "array",
170
248
  entries: [
171
249
  {_id: "hello2", _sig: "nohteunth"},
172
250
  ]
@@ -198,8 +276,8 @@ it "vm_rehash_page can calculate the hash correctly" do
198
276
  }])
199
277
  end
200
278
 
201
- it "throws an exception if multiple watches are attempted" do
202
- ctx = flok_new_user File.read('./spec/kern/assets/vm/controller_exc_2watch.rb'), File.read("./spec/kern/assets/vm/config4.rb")
279
+ it "does not throw an exception if multiple watches are attempted" do
280
+ ctx = flok_new_user File.read('./spec/kern/assets/vm/controller_exc_2watch.rb'), File.read("./spec/kern/assets/vm/config6.rb")
203
281
 
204
282
  expect {
205
283
  ctx.eval %{
@@ -208,11 +286,31 @@ it "vm_rehash_page can calculate the hash correctly" do
208
286
  //Drain queue
209
287
  int_dispatch([]);
210
288
  }
211
- }.to raise_exception
289
+ }.not_to raise_exception
290
+
291
+ bp = ctx.eval("base")
292
+ vm_notify_map = ctx.dump("vm_notify_map")
293
+ vm_bp_to_nmap = ctx.dump("vm_bp_to_nmap")
294
+
295
+ expect(vm_notify_map).to eq({
296
+ "spec" => {
297
+ "test" => [bp]
298
+ },
299
+ "spec1" => {}
300
+ })
301
+
302
+ expect(vm_bp_to_nmap).to eq({
303
+ bp.to_s => {
304
+ "spec" => {
305
+ "test" => [[bp], 0]
306
+ }
307
+ }
308
+ })
309
+
212
310
  end
213
311
 
214
- it "throws an exception if unwatch is called before watch" do
215
- ctx = flok_new_user File.read('./spec/kern/assets/vm/controller_exc_ewatch.rb'), File.read("./spec/kern/assets/vm/config4.rb")
312
+ it "does not throw an exception if multiple unwatches are requested" do
313
+ ctx = flok_new_user File.read('./spec/kern/assets/vm/controller_exc_ewatch.rb'), File.read("./spec/kern/assets/vm/config6.rb")
216
314
 
217
315
  expect {
218
316
  ctx.eval %{
@@ -221,7 +319,95 @@ it "vm_rehash_page can calculate the hash correctly" do
221
319
  //Drain queue
222
320
  int_dispatch([]);
223
321
  }
224
- }.to raise_exception
322
+ }.not_to raise_exception
323
+
324
+ bp = ctx.eval("base")
325
+ vm_notify_map = ctx.dump("vm_notify_map")
326
+ vm_bp_to_nmap = ctx.dump("vm_bp_to_nmap")
327
+
328
+ expect(vm_notify_map).to eq({
329
+ "spec" => {
330
+ },
331
+ "spec1" => {}
332
+ })
333
+
334
+ expect(vm_bp_to_nmap).to eq({
335
+ bp.to_s => {}
336
+ })
337
+
338
+ end
339
+
340
+ it "does not throw an exception if unwatch is called before watch on a particular controller; but it was already watched at one point" do
341
+ ctx = flok_new_user File.read('./spec/kern/assets/vm/controller_exc_ewatch2.rb'), File.read("./spec/kern/assets/vm/config6.rb")
342
+
343
+ expect {
344
+ ctx.eval %{
345
+ base = _embed("my_watch_controller", 1, {}, null);
346
+ base = _embed("my_controller", 1, {}, null);
347
+
348
+ //Drain queue
349
+ int_dispatch([]);
350
+ }
351
+ }.not_to raise_exception
352
+ end
353
+
354
+ it "does allow watch, unwatch, and then re-watch to work" do
355
+ ctx = flok_new_user File.read('./spec/kern/assets/vm/controller_exc_ewatch3.rb'), File.read("./spec/kern/assets/vm/config6.rb")
356
+
357
+ ctx.eval %{
358
+ base = _embed("my_controller", 1, {}, null);
359
+
360
+ //Drain queue
361
+ int_dispatch([]);
362
+ }
363
+
364
+ bp = ctx.eval("base")
365
+ vm_notify_map = ctx.dump("vm_notify_map")
366
+ vm_bp_to_nmap = ctx.dump("vm_bp_to_nmap")
367
+
368
+ expect(vm_notify_map).to eq({
369
+ "spec" => {
370
+ "test" => [bp]
371
+ },
372
+ "spec1" => {}
373
+ })
374
+
375
+ expect(vm_bp_to_nmap).to eq({
376
+ bp.to_s => {
377
+ "spec" => {
378
+ "test" => [[bp], 0]
379
+ }
380
+ }
381
+ })
382
+ end
383
+
384
+ it "does allow unwatch, watch, and then re-unwatch to work" do
385
+ ctx = flok_new_user File.read('./spec/kern/assets/vm/controller_exc_ewatch4.rb'), File.read("./spec/kern/assets/vm/config6.rb")
386
+
387
+ ctx.eval %{
388
+ base = _embed("my_controller", 1, {}, null);
389
+
390
+ //Drain queue
391
+ int_dispatch([]);
392
+ }
393
+
394
+ bp = ctx.eval("base")
395
+ vm_notify_map = ctx.dump("vm_notify_map")
396
+ vm_bp_to_nmap = ctx.dump("vm_bp_to_nmap")
397
+
398
+ expect(vm_notify_map).to eq({
399
+ "spec" => {
400
+ "test" => []
401
+ },
402
+ "spec1" => {}
403
+ })
404
+
405
+ expect(vm_bp_to_nmap).to eq({
406
+ bp.to_s => {
407
+ "spec" => {
408
+ }
409
+ }
410
+ })
225
411
  end
226
412
 
227
413
  it "multiple sequential watch requests from two controllers for a namespace do not hit the pager multiple times" do
@@ -312,17 +498,30 @@ it "vm_rehash_page can calculate the hash correctly" do
312
498
  expect(read_res_params).to eq(vm_write_list)
313
499
  end
314
500
 
315
- it "does send two watch callbacks to a controller if there is cached content" do
501
+ it "non-sync watch does send two watch callbacks to a controller if there is cached content" do
316
502
  ctx = flok_new_user File.read('./spec/kern/assets/vm/controller12.rb'), File.read("./spec/kern/assets/vm/config4.rb")
317
503
 
318
504
  ctx.eval %{
319
505
  base = _embed("my_controller", 1, {}, null);
320
-
321
- //Drain queue
322
- int_dispatch([]);
323
506
  }
324
507
 
508
+ #Should not have read anything at this point in time
509
+ read_res_params = JSON.parse(ctx.eval("JSON.stringify(read_res_params)"))
510
+ expect(read_res_params.length).to eq(0)
511
+
512
+ ctx.eval("int_dispatch([])")
513
+
514
+ #Now we read the first after it de-queued
325
515
  read_res_params = JSON.parse(ctx.eval("JSON.stringify(read_res_params)"))
516
+ expect(read_res_params.length).to eq(1)
517
+
518
+ ctx.eval("int_dispatch([])")
519
+
520
+ #And now the second
521
+ read_res_params = JSON.parse(ctx.eval("JSON.stringify(read_res_params)"))
522
+ expect(read_res_params.length).to eq(2)
523
+
524
+ #And they should have been read in order
326
525
  vm_write_list = JSON.parse(ctx.eval("JSON.stringify(vm_write_list)"));
327
526
  expect(read_res_params).to eq(vm_write_list)
328
527
  end
@@ -439,6 +638,30 @@ it "vm_rehash_page can calculate the hash correctly" do
439
638
  })
440
639
  end
441
640
 
641
+ it "Does not crash when a new a controller disconnects without watches" do
642
+ ctx = flok_new_user File.read('./spec/kern/assets/vm/controller16b.rb'), File.read("./spec/kern/assets/vm/config4.rb")
643
+
644
+ ctx.eval %{
645
+ base = _embed("my_controller", 1, {}, null);
646
+
647
+ //Drain queue
648
+ int_dispatch([3, "int_event", base, "next", {}]);
649
+ }
650
+
651
+ #vm_bp_To_nmap should be blank
652
+ base = ctx.eval("base")
653
+ vm_bp_to_nmap = JSON.parse(ctx.eval("JSON.stringify(vm_bp_to_nmap)"));
654
+ expect(vm_bp_to_nmap).to eq({})
655
+
656
+ #vm_notify_map should not contain the entries for the base address anymore
657
+ base = ctx.eval("base")
658
+ vm_notify_map = JSON.parse(ctx.eval("JSON.stringify(vm_notify_map)"));
659
+ expect(vm_notify_map).to eq({
660
+ "spec" => {
661
+ }
662
+ })
663
+ end
664
+
442
665
  it "Erases entries in vm_bp_to_nmap and vm_notify_map for a controller that disconnects" do
443
666
  ctx = flok_new_user File.read('./spec/kern/assets/vm/controller16.rb'), File.read("./spec/kern/assets/vm/config4.rb")
444
667
 
@@ -499,6 +722,7 @@ it "vm_rehash_page can calculate the hash correctly" do
499
722
  _head: "a",
500
723
  _next: "b",
501
724
  _id: "hello",
725
+ _type: "array",
502
726
  entries: [
503
727
  {_id: "hello2", _sig: "nohteunth"},
504
728
  ]
@@ -703,7 +927,63 @@ it "vm_rehash_page can calculate the hash correctly" do
703
927
  })
704
928
  end
705
929
 
706
- it "Responds twice to watch with a missing cache but where the disk has a copy and then the pager responds" do
930
+ #it "Responds twice to watch with a missing cache but where the disk has a copy and then the pager responds" do
931
+ #ctx = flok_new_user File.read('./spec/kern/assets/vm/controller20.rb'), File.read("./spec/kern/assets/vm/config4.rb")
932
+
933
+ #ctx.eval %{
934
+ #base = _embed("my_controller", 1, {}, null);
935
+
936
+ #//Manually construct a page
937
+ #page = {
938
+ #_head: null,
939
+ #_next: null,
940
+ #_id: "hello",
941
+ #entries: [
942
+ #{_id: "hello2", _sig: "nohteunth"},
943
+ #]
944
+ #}
945
+
946
+ #//Manually construct another page that would normally be written
947
+ #//by a 'pager' to the cache
948
+ #page2 = {
949
+ #_head: null,
950
+ #_next: null,
951
+ #_id: "hello",
952
+ #entries: [
953
+ #{_id: "hello2", _sig: "nohteunth"},
954
+ #{_id: "hello3", _sig: "athoeuntz"}
955
+ #]
956
+ #}
957
+
958
+ #//Recalculate hashes
959
+ #vm_rehash_page(page);
960
+ #vm_rehash_page(page2);
961
+
962
+ #//Drain queue
963
+ #int_dispatch([]);
964
+ #}
965
+
966
+ ##Copies of JS pages in ruby dictionary format
967
+ #page = JSON.parse(ctx.eval("JSON.stringify(page)"))
968
+ #page2 = JSON.parse(ctx.eval("JSON.stringify(page2)"))
969
+
970
+ ##At this point, flok should have attempted to grab a page to fill
971
+ ##the *now* blank cache. We are going to send it the first page.
972
+ #@driver.ignore_up_to "if_per_get", 2
973
+ #@driver.get "if_per_get", 2
974
+ #@driver.int "int_per_get_res", ["vm", "spec", page]
975
+
976
+ ##Now, we pretend that a pager has written to the cache because it has
977
+ ##received data back
978
+ #ctx.eval(%{vm_cache_write("spec", page2)})
979
+
980
+ #res = JSON.parse(ctx.eval("JSON.stringify(read_res)"))
981
+ #expect(res).to eq([
982
+ #page, page2
983
+ #])
984
+ #end
985
+
986
+ it "Responds once to watch with a missing cache but where the pager responds before the disk for array" do
707
987
  ctx = flok_new_user File.read('./spec/kern/assets/vm/controller20.rb'), File.read("./spec/kern/assets/vm/config4.rb")
708
988
 
709
989
  ctx.eval %{
@@ -714,6 +994,7 @@ it "vm_rehash_page can calculate the hash correctly" do
714
994
  _head: null,
715
995
  _next: null,
716
996
  _id: "hello",
997
+ _type: "array",
717
998
  entries: [
718
999
  {_id: "hello2", _sig: "nohteunth"},
719
1000
  ]
@@ -725,6 +1006,7 @@ it "vm_rehash_page can calculate the hash correctly" do
725
1006
  _head: null,
726
1007
  _next: null,
727
1008
  _id: "hello",
1009
+ _type: "array",
728
1010
  entries: [
729
1011
  {_id: "hello2", _sig: "nohteunth"},
730
1012
  {_id: "hello3", _sig: "athoeuntz"}
@@ -747,19 +1029,22 @@ it "vm_rehash_page can calculate the hash correctly" do
747
1029
  #the *now* blank cache. We are going to send it the first page.
748
1030
  @driver.ignore_up_to "if_per_get", 2
749
1031
  @driver.get "if_per_get", 2
750
- @driver.int "int_per_get_res", ["vm", "spec", page]
751
1032
 
752
1033
  #Now, we pretend that a pager has written to the cache because it has
753
1034
  #received data back
754
1035
  ctx.eval(%{vm_cache_write("spec", page2)})
755
1036
 
1037
+ #And then we let the cache from disk reply, which should be ignored
1038
+ #because the cache is already there from the pager
1039
+ @driver.int "int_per_get_res", ["vm", "spec", page]
1040
+
756
1041
  res = JSON.parse(ctx.eval("JSON.stringify(read_res)"))
757
1042
  expect(res).to eq([
758
- page, page2
1043
+ page2
759
1044
  ])
760
- end
1045
+ end
761
1046
 
762
- it "Responds once to watch with a missing cache but where the pager responds before the disk" do
1047
+ it "Responds once to watch with a missing cache but where the pager responds before the disk for hash" do
763
1048
  ctx = flok_new_user File.read('./spec/kern/assets/vm/controller20.rb'), File.read("./spec/kern/assets/vm/config4.rb")
764
1049
 
765
1050
  ctx.eval %{
@@ -770,6 +1055,7 @@ it "vm_rehash_page can calculate the hash correctly" do
770
1055
  _head: null,
771
1056
  _next: null,
772
1057
  _id: "hello",
1058
+ _type: "hash",
773
1059
  entries: [
774
1060
  {_id: "hello2", _sig: "nohteunth"},
775
1061
  ]
@@ -781,6 +1067,7 @@ it "vm_rehash_page can calculate the hash correctly" do
781
1067
  _head: null,
782
1068
  _next: null,
783
1069
  _id: "hello",
1070
+ _type: "hash",
784
1071
  entries: [
785
1072
  {_id: "hello2", _sig: "nohteunth"},
786
1073
  {_id: "hello3", _sig: "athoeuntz"}