flok 0.0.40 → 0.0.41
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/drivers/chrome/src/dispatch.js +7 -2
- data/app/kern/dispatch.js +10 -1
- data/app/kern/mod/event.js +9 -0
- data/app/kern/pagers/pg_mem.js +21 -0
- data/app/kern/pagers/pg_net_sim.js +44 -0
- data/app/kern/pagers/pg_spec.js +23 -0
- data/app/kern/services/vm.rb +60 -64
- data/bin/flok +44 -23
- data/docs/callout.md +1 -1
- data/docs/client_api.md +5 -2
- data/docs/config_yml.md +41 -0
- data/docs/controllers.md +4 -0
- data/docs/datatypes.md +5 -2
- data/docs/debug_server.md +2 -0
- data/docs/dispatch.md +8 -3
- data/docs/known_issues.md +6 -0
- data/docs/mod/event.md +25 -20
- data/docs/mod/persist.md +1 -1
- data/docs/mod/speech.md +12 -0
- data/docs/project.md +2 -2
- data/docs/services/vm.md +46 -17
- data/docs/services/vm/pagers.md +22 -2
- data/lib/flok/build.rb +0 -4
- data/lib/flok/user_compiler.rb +123 -47
- data/lib/flok/user_compiler_templates/ctable.js.erb +39 -1
- data/lib/flok/version.rb +1 -1
- data/spec/env/global.rb +1 -0
- data/spec/env/kern.rb +5 -1
- data/spec/etc/cli_spec.rb +337 -322
- data/spec/etc/service_compiler/config0.rb +1 -1
- data/spec/etc/service_compiler/config0b.rb +1 -0
- data/spec/etc/services_compiler_spec.rb +29 -29
- data/spec/etc/user_compiler/controller0b.rb +9 -0
- data/spec/etc/user_compiler/controller0timer.rb +16 -0
- data/spec/etc/user_compiler_spec.rb +24 -1
- data/spec/iface/driver/dispatch_spec.rb +8 -2
- data/spec/iface/driver/persist_spec.rb +11 -0
- data/spec/kern/assets/controller0defer.rb +18 -0
- data/spec/kern/assets/controller0defer0.rb +13 -0
- data/spec/kern/assets/controller0defer2.rb +17 -0
- data/spec/kern/assets/global_on_entry.rb +8 -0
- data/spec/kern/assets/global_on_entry2.rb +16 -0
- data/spec/kern/assets/global_on_entry3.rb +17 -0
- data/spec/kern/assets/global_on_entry4.rb +12 -0
- data/spec/kern/assets/interval.rb +29 -0
- data/spec/kern/assets/interval2.rb +33 -0
- data/spec/kern/assets/interval3.rb +39 -0
- data/spec/kern/assets/service1.rb +4 -1
- data/spec/kern/assets/service_controller1.rb +11 -0
- data/spec/kern/assets/specimin/controller0.rb +74 -0
- data/spec/kern/assets/vm/config5.rb +20 -0
- data/spec/kern/assets/vm/config6.rb +20 -0
- data/spec/kern/assets/vm/controller10.rb +1 -1
- data/spec/kern/assets/vm/controller11.rb +1 -1
- data/spec/kern/assets/vm/controller12.rb +1 -1
- data/spec/kern/assets/vm/controller13.rb +1 -1
- data/spec/kern/assets/vm/controller16b.rb +28 -0
- data/spec/kern/assets/vm/controller18.rb +1 -1
- data/spec/kern/assets/vm/controller21.rb +1 -1
- data/spec/kern/assets/vm/controller22.rb +8 -0
- data/spec/kern/assets/vm/controller_exc_ewatch.rb +1 -0
- data/spec/kern/assets/vm/controller_exc_ewatch2.rb +30 -0
- data/spec/kern/assets/vm/controller_exc_ewatch3.rb +16 -0
- data/spec/kern/assets/vm/controller_exc_ewatch4.rb +16 -0
- data/spec/kern/assets/vm/macros/copy_page_c.rb +1 -0
- data/spec/kern/assets/vm/macros/copy_page_ch.rb +25 -0
- data/spec/kern/assets/vm/macros/entry_del_c.rb +1 -0
- data/spec/kern/assets/vm/macros/entry_del_ch.rb +20 -0
- data/spec/kern/assets/vm/macros/entry_insert_c.rb +1 -0
- data/spec/kern/assets/vm/macros/entry_insert_ch.rb +23 -0
- data/spec/kern/assets/vm/macros/entry_mutable_c.rb +8 -7
- data/spec/kern/assets/vm/macros/entry_mutable_ch.rb +34 -0
- data/spec/kern/assets/vm/macros/new_page_c.rb +1 -1
- data/spec/kern/assets/vm/macros/new_page_c2.rb +1 -1
- data/spec/kern/assets/vm/macros/new_page_ch.rb +7 -0
- data/spec/kern/assets/vm/pg_mem/config.rb +10 -0
- data/spec/kern/assets/vm/pg_mem/config1.rb +10 -0
- data/spec/kern/assets/vm/pg_mem/config2.rb +10 -0
- data/spec/kern/assets/vm/pg_mem/config3.rb +15 -0
- data/spec/kern/assets/vm/pg_mem/write.rb +23 -0
- data/spec/kern/assets/vm/pg_mem/write2.rb +38 -0
- data/spec/kern/assets/vm/pg_net_sim/config.rb +10 -0
- data/spec/kern/assets/vm/pg_net_sim/nothing.rb +12 -0
- data/spec/kern/assets/vm/pg_net_sim/pages.json +1 -0
- data/spec/kern/assets/vm/pg_net_sim/watch.rb +18 -0
- data/spec/kern/callout_spec.rb +1 -1
- data/spec/kern/controller_macro_spec.rb +153 -20
- data/spec/kern/controller_spec.rb +232 -1
- data/spec/kern/debug_ui_spec.rb +235 -235
- data/spec/kern/event_spec.rb +112 -0
- data/spec/kern/service_controller_spec.rb +14 -2
- data/spec/kern/vm_service_mem_pagers_spec.rb +117 -0
- data/spec/kern/vm_service_net_sim_pager_spec.rb +97 -0
- data/spec/kern/vm_service_spec.rb +304 -17
- data/spec/kern/vm_service_spec2.rb +39 -0
- metadata +88 -6
- data/app/kern/pagers/mem_pager.js +0 -2
- data/app/kern/pagers/pg_spec0.js +0 -20
- data/lib/flok/project_template/Guardfile +0 -7
- 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
|
-
|
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(
|
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 "
|
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
|
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 "
|
202
|
-
ctx = flok_new_user File.read('./spec/kern/assets/vm/controller_exc_2watch.rb'), File.read("./spec/kern/assets/vm/
|
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
|
-
}.
|
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 "
|
215
|
-
ctx = flok_new_user File.read('./spec/kern/assets/vm/controller_exc_ewatch.rb'), File.read("./spec/kern/assets/vm/
|
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
|
-
}.
|
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
|
-
|
1043
|
+
page2
|
759
1044
|
])
|
760
|
-
|
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"}
|