kobako 0.28.0 → 0.30.0

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.
Files changed (218) hide show
  1. checksums.yaml +4 -4
  2. data/.release-please-manifest.json +1 -1
  3. data/CHANGELOG.md +377 -0
  4. data/Cargo.lock +181 -154
  5. data/README.md +99 -459
  6. data/ROADMAP.md +7 -1
  7. data/SECURITY.md +1 -1
  8. data/crates/kobako-runtime/CHANGELOG.md +354 -0
  9. data/crates/kobako-runtime/Cargo.toml +38 -7
  10. data/crates/kobako-runtime/README.md +17 -8
  11. data/crates/kobako-runtime/src/dispatch.rs +9 -1
  12. data/crates/kobako-runtime/src/endpoint/buffer.rs +192 -0
  13. data/crates/kobako-runtime/src/endpoint/capture.rs +115 -0
  14. data/crates/kobako-runtime/src/endpoint/dispatch.rs +253 -0
  15. data/crates/kobako-runtime/src/endpoint/invoke.rs +194 -0
  16. data/crates/kobako-runtime/src/endpoint/memory_cap.rs +238 -0
  17. data/crates/kobako-runtime/src/endpoint.rs +166 -0
  18. data/crates/kobako-runtime/src/filesystem/bind/fid.rs +82 -0
  19. data/crates/kobako-runtime/src/filesystem/bind/lookup.rs +236 -0
  20. data/crates/kobako-runtime/src/filesystem/bind/walk.rs +249 -0
  21. data/crates/kobako-runtime/src/filesystem/bind.rs +2665 -0
  22. data/crates/kobako-runtime/src/filesystem/overlay/file.rs +89 -0
  23. data/crates/kobako-runtime/src/filesystem/overlay/inode.rs +106 -0
  24. data/crates/kobako-runtime/src/filesystem/overlay/path.rs +285 -0
  25. data/crates/kobako-runtime/src/filesystem/overlay/stack/copy_up.rs +135 -0
  26. data/crates/kobako-runtime/src/filesystem/overlay/stack/dir.rs +263 -0
  27. data/crates/kobako-runtime/src/filesystem/overlay/stack/namei.rs +135 -0
  28. data/crates/kobako-runtime/src/filesystem/overlay/stack/readdir.rs +57 -0
  29. data/crates/kobako-runtime/src/filesystem/overlay/stack.rs +301 -0
  30. data/crates/kobako-runtime/src/filesystem/overlay.rs +3469 -0
  31. data/crates/kobako-runtime/src/filesystem/path.rs +21 -0
  32. data/crates/kobako-runtime/src/filesystem/pipe.rs +221 -0
  33. data/crates/kobako-runtime/src/filesystem/rdir.rs +101 -0
  34. data/crates/kobako-runtime/src/filesystem/tmpfs/tmpfile.rs +32 -0
  35. data/crates/kobako-runtime/src/filesystem/tmpfs/whiteout.rs +85 -0
  36. data/crates/kobako-runtime/src/filesystem/tmpfs/xattr.rs +22 -0
  37. data/crates/kobako-runtime/src/filesystem/tmpfs.rs +1985 -0
  38. data/crates/kobako-runtime/src/filesystem/wrap.rs +224 -0
  39. data/crates/kobako-runtime/src/filesystem.rs +26 -0
  40. data/crates/kobako-runtime/src/grant.rs +20 -0
  41. data/crates/kobako-runtime/src/hashtable.rs +44 -0
  42. data/crates/kobako-runtime/src/lib.rs +16 -1
  43. data/crates/kobako-runtime/src/locking/seqlock.rs +66 -0
  44. data/crates/kobako-runtime/src/locking.rs +218 -0
  45. data/crates/kobako-runtime/src/mount.rs +105 -0
  46. data/crates/kobako-runtime/src/profile.rs +140 -4
  47. data/crates/kobako-runtime/src/runtime.rs +12 -0
  48. data/crates/kobako-runtime/src/sched.rs +210 -0
  49. data/crates/kobako-runtime/src/security.rs +696 -0
  50. data/crates/kobako-runtime/src/snapshot.rs +20 -5
  51. data/crates/kobako-runtime/src/vfs/attr.rs +162 -0
  52. data/crates/kobako-runtime/src/vfs/cred.rs +334 -0
  53. data/crates/kobako-runtime/src/vfs/dentry.rs +1412 -0
  54. data/crates/kobako-runtime/src/vfs/errno.rs +153 -0
  55. data/crates/kobako-runtime/src/vfs/file.rs +1915 -0
  56. data/crates/kobako-runtime/src/vfs/inode.rs +429 -0
  57. data/crates/kobako-runtime/src/vfs/kern_path.rs +217 -0
  58. data/crates/kobako-runtime/src/vfs/mount.rs +59 -0
  59. data/crates/kobako-runtime/src/vfs/namei.rs +5708 -0
  60. data/crates/kobako-runtime/src/vfs/openat2.rs +116 -0
  61. data/crates/kobako-runtime/src/vfs/path.rs +64 -0
  62. data/crates/kobako-runtime/src/vfs/readdir.rs +163 -0
  63. data/crates/kobako-runtime/src/vfs/stat.rs +157 -0
  64. data/crates/kobako-runtime/src/vfs/super_block.rs +122 -0
  65. data/crates/kobako-runtime/src/vfs/utimes.rs +289 -0
  66. data/crates/kobako-runtime/src/vfs.rs +60 -0
  67. data/crates/kobako-runtime/src/yielder.rs +11 -6
  68. data/crates/kobako-runtime/tests/linux_baseline/calls.rs +171 -0
  69. data/crates/kobako-runtime/tests/linux_baseline/concurrent.rs +276 -0
  70. data/crates/kobako-runtime/tests/linux_baseline/kobako.rs +323 -0
  71. data/crates/kobako-runtime/tests/linux_baseline/linux-baseline-expected.txt +16 -0
  72. data/crates/kobako-runtime/tests/linux_baseline/linux.rs +449 -0
  73. data/crates/kobako-runtime/tests/linux_baseline/main.rs +611 -0
  74. data/crates/kobako-runtime/tests/linux_baseline/permissions.rs +236 -0
  75. data/crates/kobako-transport/CHANGELOG.md +23 -0
  76. data/crates/kobako-transport/Cargo.toml +3 -3
  77. data/crates/kobako-transport/README.md +6 -5
  78. data/crates/kobako-transport/src/abi.rs +1 -1
  79. data/crates/kobako-transport/src/envelope/bytes.rs +33 -25
  80. data/crates/kobako-transport/src/envelope/call.rs +5 -5
  81. data/crates/kobako-transport/src/envelope/compile_reply.rs +2 -2
  82. data/crates/kobako-transport/src/envelope/error_record.rs +3 -3
  83. data/crates/kobako-transport/src/envelope/fault.rs +4 -3
  84. data/crates/kobako-transport/src/envelope/outcome.rs +3 -3
  85. data/crates/kobako-transport/src/envelope/preamble.rs +24 -24
  86. data/crates/kobako-transport/src/envelope/reply.rs +34 -16
  87. data/crates/kobako-transport/src/envelope/request.rs +19 -9
  88. data/crates/kobako-transport/src/envelope/run.rs +1 -1
  89. data/crates/kobako-transport/src/envelope/unsupported.rs +2 -2
  90. data/crates/kobako-transport/src/envelope.rs +2 -2
  91. data/crates/kobako-wasmtime/CHANGELOG.md +265 -0
  92. data/crates/kobako-wasmtime/Cargo.toml +25 -19
  93. data/crates/kobako-wasmtime/README.md +13 -7
  94. data/crates/kobako-wasmtime/src/abi.rs +75 -49
  95. data/crates/kobako-wasmtime/src/ambient.rs +64 -6
  96. data/crates/kobako-wasmtime/src/cache.rs +188 -77
  97. data/crates/kobako-wasmtime/src/config.rs +77 -5
  98. data/crates/kobako-wasmtime/src/descriptors.rs +200 -0
  99. data/crates/kobako-wasmtime/src/driver.rs +70 -135
  100. data/crates/kobako-wasmtime/src/exports.rs +5 -16
  101. data/crates/kobako-wasmtime/src/guest.rs +38 -0
  102. data/crates/kobako-wasmtime/src/imports.rs +52 -0
  103. data/crates/kobako-wasmtime/src/instance_pre.rs +18 -46
  104. data/crates/kobako-wasmtime/src/invocation.rs +43 -74
  105. data/crates/kobako-wasmtime/src/lib.rs +5 -4
  106. data/crates/kobako-wasmtime/src/limiter.rs +6 -230
  107. data/crates/kobako-wasmtime/src/preview1/differential/mount.rs +632 -0
  108. data/crates/kobako-wasmtime/src/preview1/differential.rs +486 -0
  109. data/crates/kobako-wasmtime/src/preview1/errno.rs +135 -0
  110. data/crates/kobako-wasmtime/src/preview1/fd.rs +1420 -0
  111. data/crates/kobako-wasmtime/src/preview1/memory.rs +172 -0
  112. data/crates/kobako-wasmtime/src/preview1/mount_view/wrap.rs +211 -0
  113. data/crates/kobako-wasmtime/src/preview1/mount_view.rs +3766 -0
  114. data/crates/kobako-wasmtime/src/preview1/path.rs +302 -0
  115. data/crates/kobako-wasmtime/src/preview1/poll.rs +381 -0
  116. data/crates/kobako-wasmtime/src/preview1/sock.rs +13 -0
  117. data/crates/kobako-wasmtime/src/preview1/testsuite-expected.txt +6 -0
  118. data/crates/kobako-wasmtime/src/preview1/testsuite.rs +157 -0
  119. data/crates/kobako-wasmtime/src/preview1.rs +512 -0
  120. data/crates/kobako-wasmtime/src/trap.rs +45 -25
  121. data/crates/kobako-wasmtime/src/wasi.rs +333 -0
  122. data/crates/kobako-wasmtime/tests/integration/compile_posture.rs +43 -0
  123. data/crates/kobako-wasmtime/tests/integration/guest_file.rs +1085 -0
  124. data/crates/kobako-wasmtime/tests/integration/main.rs +29 -0
  125. data/crates/kobako-wasmtime/tests/{preamble_flags.rs → integration/preamble_flags.rs} +4 -3
  126. data/crates/kobako-wasmtime/tests/{snippet_compile.rs → integration/snippet_compile.rs} +5 -4
  127. data/crates/kobako-wasmtime/tests/{support → integration/support}/mod.rs +9 -13
  128. data/crates/kobako-wasmtime/tests/integration/unanswered_call.rs +86 -0
  129. data/crates/kobako-wasmtime/tests/{unsupported_call.rs → integration/unsupported_call.rs} +2 -1
  130. data/crates/kobako-wasmtime/witx/typenames.witx +750 -0
  131. data/crates/kobako-wasmtime/witx/wasi_snapshot_preview1.witx +441 -0
  132. data/data/kobako.wasm +0 -0
  133. data/ext/kobako/Cargo.toml +4 -2
  134. data/ext/kobako/src/runtime/bridge.rs +154 -81
  135. data/ext/kobako/src/runtime/errors.rs +1 -1
  136. data/ext/kobako/src/runtime/escape.rs +67 -0
  137. data/ext/kobako/src/runtime/filesystem/grants.rs +107 -0
  138. data/ext/kobako/src/runtime/filesystem/ruby.rs +708 -0
  139. data/ext/kobako/src/runtime/filesystem.rs +208 -0
  140. data/ext/kobako/src/runtime/gvl.rs +49 -8
  141. data/ext/kobako/src/runtime/pinned_value.rs +31 -0
  142. data/ext/kobako/src/runtime/snapshot.rs +127 -0
  143. data/ext/kobako/src/runtime.rs +125 -199
  144. data/lib/kobako/catalog/extensions.rb +5 -5
  145. data/lib/kobako/catalog/flags.rb +2 -14
  146. data/lib/kobako/catalog/grants.rb +30 -0
  147. data/lib/kobako/catalog/handles.rb +6 -6
  148. data/lib/kobako/catalog/mount.rb +19 -0
  149. data/lib/kobako/catalog/services.rb +13 -2
  150. data/lib/kobako/catalog/snippets.rb +11 -15
  151. data/lib/kobako/catalog.rb +11 -0
  152. data/lib/kobako/codec/decoder.rb +10 -9
  153. data/lib/kobako/codec/ext_types.rb +4 -6
  154. data/lib/kobako/codec/handle_walk.rb +4 -6
  155. data/lib/kobako/codec/nesting.rb +7 -7
  156. data/lib/kobako/codec/state.rb +19 -3
  157. data/lib/kobako/codec/utils.rb +1 -1
  158. data/lib/kobako/codec/value_budget.rb +86 -0
  159. data/lib/kobako/codec.rb +7 -0
  160. data/lib/kobako/context.rb +40 -13
  161. data/lib/kobako/errors.rb +15 -14
  162. data/lib/kobako/filesystem.rb +69 -0
  163. data/lib/kobako/payload/arguments.rb +2 -2
  164. data/lib/kobako/pool.rb +6 -6
  165. data/lib/kobako/sandbox.rb +55 -27
  166. data/lib/kobako/sandbox_options.rb +39 -13
  167. data/lib/kobako/snippet/{binary.rb → bytecode.rb} +2 -2
  168. data/lib/kobako/snippet/source.rb +1 -1
  169. data/lib/kobako/snippet.rb +1 -1
  170. data/lib/kobako/transport/block_failure.rb +35 -0
  171. data/lib/kobako/transport/dispatcher.rb +33 -29
  172. data/lib/kobako/transport/exposure.rb +7 -9
  173. data/lib/kobako/transport/reflection.rb +79 -23
  174. data/lib/kobako/transport/run.rb +5 -5
  175. data/lib/kobako/transport/yielder.rb +9 -31
  176. data/lib/kobako/transport.rb +1 -0
  177. data/lib/kobako/version.rb +1 -1
  178. data/lib/kobako.rb +35 -0
  179. data/release-please-config.json +1 -0
  180. data/sig/kobako/catalog/extensions.rbs +3 -3
  181. data/sig/kobako/catalog/flags.rbs +0 -4
  182. data/sig/kobako/catalog/grants.rbs +13 -0
  183. data/sig/kobako/catalog/handles.rbs +3 -3
  184. data/sig/kobako/catalog/mount.rbs +24 -0
  185. data/sig/kobako/catalog/services.rbs +5 -1
  186. data/sig/kobako/catalog/snippets.rbs +4 -4
  187. data/sig/kobako/catalog.rbs +1 -0
  188. data/sig/kobako/codec/decoder.rbs +1 -1
  189. data/sig/kobako/codec/handle_walk.rbs +1 -1
  190. data/sig/kobako/codec/nesting.rbs +2 -2
  191. data/sig/kobako/codec/state.rbs +7 -1
  192. data/sig/kobako/codec/utils.rbs +1 -1
  193. data/sig/kobako/codec/value_budget.rbs +23 -0
  194. data/sig/kobako/codec.rbs +3 -2
  195. data/sig/kobako/context.rbs +14 -6
  196. data/sig/kobako/errors.rbs +4 -4
  197. data/sig/kobako/filesystem.rbs +93 -0
  198. data/sig/kobako/guest_yielder.rbs +9 -0
  199. data/sig/kobako/payload/arguments.rbs +1 -1
  200. data/sig/kobako/pool.rbs +3 -3
  201. data/sig/kobako/runtime.rbs +21 -49
  202. data/sig/kobako/sandbox.rbs +9 -5
  203. data/sig/kobako/sandbox_options.rbs +25 -3
  204. data/sig/kobako/snapshot.rbs +20 -0
  205. data/sig/kobako/snippet/bytecode.rbs +12 -0
  206. data/sig/kobako/transport/block_failure.rbs +13 -0
  207. data/sig/kobako/transport/dispatcher.rbs +4 -4
  208. data/sig/kobako/transport/exposure.rbs +2 -2
  209. data/sig/kobako/transport/reflection.rbs +14 -1
  210. data/sig/kobako/transport/run.rbs +3 -3
  211. data/sig/kobako/transport/yielder.rbs +3 -7
  212. data/sig/kobako/transport.rbs +3 -3
  213. metadata +116 -15
  214. data/crates/kobako-wasmtime/src/capture.rs +0 -96
  215. data/crates/kobako-wasmtime/src/dispatch.rs +0 -107
  216. data/crates/kobako-wasmtime/src/guest_mem.rs +0 -265
  217. data/crates/kobako-wasmtime/src/io.rs +0 -286
  218. data/sig/kobako/snippet/binary.rbs +0 -12
@@ -0,0 +1,29 @@
1
+ //! The driver's integration tests, built as one binary so a run links
2
+ //! wasmtime once rather than once per file.
3
+
4
+ mod support;
5
+
6
+ mod compile_posture;
7
+ mod guest_file;
8
+ mod preamble_flags;
9
+ mod snippet_compile;
10
+ mod unanswered_call;
11
+ mod unsupported_call;
12
+
13
+ // Cargo compiles only the modules declared above, so a test file left out
14
+ // would never run and nothing would say so.
15
+ #[test]
16
+ fn every_file_in_this_directory_is_a_declared_module() {
17
+ let dir = concat!(env!("CARGO_MANIFEST_DIR"), "/tests/integration");
18
+ for entry in std::fs::read_dir(dir).expect("the test directory must list") {
19
+ let path = entry.expect("an entry must read").path();
20
+ let name = path
21
+ .file_stem()
22
+ .and_then(|stem| stem.to_str())
23
+ .expect("a UTF-8 name");
24
+ assert!(
25
+ name == "main" || include_str!("main.rs").contains(&format!("mod {name};")),
26
+ "tests/integration/{name} must be declared in main.rs, or it never runs"
27
+ );
28
+ }
29
+ }
@@ -1,8 +1,8 @@
1
- //! The bundled guest recognises no flag, so every flag a host sets meets
2
- //! the unrecognised path: a critical one must refuse the invocation under
1
+ //! A flag the bundled guest does not recognise meets the unrecognised
2
+ //! path: a critical one must refuse the invocation under
3
3
  //! its own class, and an advisory one must leave the run untouched.
4
4
 
5
- mod support;
5
+ use crate::support;
6
6
 
7
7
  use kobako_runtime::{Completion, Entry, Runtime};
8
8
  use kobako_transport::envelope::{Flag, Origin, Outcome, Preamble};
@@ -26,6 +26,7 @@ fn eval_with_flag(critical: bool) -> Option<(Outcome, Vec<u8>)> {
26
26
  },
27
27
  &preamble,
28
28
  None,
29
+ &[],
29
30
  )
30
31
  .expect("the invocation must start");
31
32
  let Completion::Outcome(outcome) = snapshot.completion else {
@@ -4,21 +4,21 @@
4
4
  //! two compiles of the same Preamble have to agree byte for byte so
5
5
  //! either can stand in for the other.
6
6
 
7
- mod support;
7
+ use crate::support;
8
8
 
9
9
  use kobako_runtime::{Completion, Entry, Runtime};
10
10
  use kobako_transport::envelope::{Flag, Outcome, Preamble, Snippet, Snippets};
11
11
 
12
12
  use support::bundled_driver as driver;
13
13
 
14
- fn preamble_of(entries: Vec<Snippet>) -> Preamble {
14
+ fn preamble_with(entries: Vec<Snippet>) -> Preamble {
15
15
  let mut preamble = Preamble::default();
16
16
  preamble.snippets = Snippets { entries };
17
17
  preamble
18
18
  }
19
19
 
20
20
  fn greeter() -> Preamble {
21
- preamble_of(vec![Snippet::Source {
21
+ preamble_with(vec![Snippet::Source {
22
22
  name: "Greeter".into(),
23
23
  body: "module Greeter; def self.hi = 'hi'; end".into(),
24
24
  }])
@@ -33,7 +33,7 @@ fn compiled_snippets_replay_in_a_later_invocation() {
33
33
  let bytecodes = driver
34
34
  .compile(&greeter())
35
35
  .expect("a source snippet that parses must compile");
36
- let replay = preamble_of(
36
+ let replay = preamble_with(
37
37
  bytecodes
38
38
  .into_iter()
39
39
  .map(|body| Snippet::Bytecode { body })
@@ -47,6 +47,7 @@ fn compiled_snippets_replay_in_a_later_invocation() {
47
47
  },
48
48
  &replay,
49
49
  None,
50
+ &[],
50
51
  )
51
52
  .expect("the invocation must start");
52
53
 
@@ -18,17 +18,13 @@ pub fn bundled_driver() -> Option<Driver> {
18
18
  );
19
19
  return None;
20
20
  }
21
- Some(
22
- Driver::new(
23
- Path::new(WASM),
24
- Config {
25
- timeout: Some(Duration::from_secs(10)),
26
- memory_limit: None,
27
- stdout_limit: None,
28
- stderr_limit: None,
29
- profile: Profile::Hermetic,
30
- },
31
- )
32
- .expect("the Guest Binary must load"),
33
- )
21
+ let mut config = Config::default();
22
+ config.timeout = Some(Duration::from_secs(10));
23
+ config.setup_timeout = Some(Duration::from_secs(10));
24
+ config.memory_limit = None;
25
+ config.stdout_limit = None;
26
+ config.stderr_limit = None;
27
+ config.open_file_limit = None;
28
+ config.profile = Profile::Hermetic;
29
+ Some(Driver::new(Path::new(WASM), config).expect("the Guest Binary must load"))
34
30
  }
@@ -0,0 +1,86 @@
1
+ //! A Call the host could not answer as the Service meant still reaches the
2
+ //! guest as an answer it can rescue, and the answer says why. The default
3
+ //! frontends never hand the driver either failure, so only a handler
4
+ //! written here reaches them.
5
+
6
+ use crate::support;
7
+
8
+ use std::sync::Arc;
9
+
10
+ use kobako_runtime::{Completion, DispatchHandler, Entry, Runtime, Yielder};
11
+ use kobako_transport::envelope::{Bindings, Call, Outcome, Preamble, Reply};
12
+
13
+ /// Answers every Call with one byte more than a message carries.
14
+ struct AnswersTooMuch;
15
+
16
+ impl DispatchHandler for AnswersTooMuch {
17
+ fn dispatch(&self, _call: Call<'_>, _yielder: &mut dyn Yielder) -> Option<Reply> {
18
+ Some(Reply::Ok(vec![0xc0; (16 << 20) + 1]))
19
+ }
20
+ }
21
+
22
+ /// Breaks the handler contract by answering nothing.
23
+ struct AnswersNothing;
24
+
25
+ impl DispatchHandler for AnswersNothing {
26
+ fn dispatch(&self, _call: Call<'_>, _yielder: &mut dyn Yielder) -> Option<Reply> {
27
+ None
28
+ }
29
+ }
30
+
31
+ fn eval_against(handler: Arc<dyn DispatchHandler>, source: &[u8]) -> Option<Outcome> {
32
+ let driver = support::bundled_driver()?;
33
+ let mut preamble = Preamble::default();
34
+ preamble.bindings = Bindings {
35
+ paths: vec!["Svc".into()],
36
+ };
37
+ let snapshot = driver
38
+ .invoke(Entry::Eval { source }, &preamble, Some(handler), &[])
39
+ .expect("the invocation must start");
40
+ let Completion::Outcome(outcome) = snapshot.completion else {
41
+ panic!("the invocation must answer rather than trap");
42
+ };
43
+ Some(outcome)
44
+ }
45
+
46
+ // @behavior T-286
47
+ #[test]
48
+ fn an_answer_larger_than_a_message_raises_a_service_failure_naming_the_limit() {
49
+ let source = b"begin; Svc.go; rescue Kobako::ServiceError => e; e.message; end";
50
+ let Some(outcome) = eval_against(Arc::new(AnswersTooMuch), source) else {
51
+ return;
52
+ };
53
+
54
+ let mut expected = vec![0xd9, 0x4e];
55
+ expected.extend_from_slice(
56
+ b"Sandbox could not write the Service's answer: payload exceeds the 16 MiB limit",
57
+ );
58
+ assert_eq!(
59
+ outcome,
60
+ Outcome::Ok(expected),
61
+ "a Service answer past the message cap through Driver#invoke must raise a Service \
62
+ failure in the guest naming the limit"
63
+ );
64
+ }
65
+
66
+ // @behavior T-287
67
+ #[test]
68
+ fn a_call_the_host_could_not_answer_raises_a_transport_error_naming_why() {
69
+ let source = b"begin; Svc.go; rescue Kobako::Transport::Error => e; e.message; end";
70
+ let Some(outcome) = eval_against(Arc::new(AnswersNothing), source) else {
71
+ return;
72
+ };
73
+
74
+ let mut expected = vec![0xd9, 0x6a];
75
+ expected.extend_from_slice(
76
+ "a Sandbox callback raised an exception instead of returning a fault — please report \
77
+ this as a kobako bug"
78
+ .as_bytes(),
79
+ );
80
+ assert_eq!(
81
+ outcome,
82
+ Outcome::Ok(expected),
83
+ "a Call a handler answered with nothing through Driver#invoke must raise \
84
+ Kobako::Transport::Error in the guest naming why"
85
+ );
86
+ }
@@ -3,7 +3,7 @@
3
3
  //! rather than a broken exchange. The default frontends serve every Call,
4
4
  //! so only a handler written here reaches that answer.
5
5
 
6
- mod support;
6
+ use crate::support;
7
7
 
8
8
  use std::sync::Arc;
9
9
 
@@ -35,6 +35,7 @@ fn a_call_the_host_does_not_serve_raises_unsupported_error_in_the_guest() {
35
35
  Entry::Eval { source },
36
36
  &preamble,
37
37
  Some(Arc::new(ServesNoCall)),
38
+ &[],
38
39
  )
39
40
  .expect("the invocation must start");
40
41