diff options
author | Emery Hemingway <ehmry@posteo.net> | 2024-08-26T02·06+0300 |
---|---|---|
committer | Emery Hemingway <ehmry@posteo.net> | 2024-08-27T15·01+0300 |
commit | 0e35e937e47ce68c35ee6e997c81b2cd412bb32a (patch) | |
tree | c1422747480d3f8866b52891115ce4b58a14aad6 | |
parent | 151037cf4dac74a3d9eb2cbe84f167a21c50d820 (diff) |
Swap argument order at <eval …>
-rw-r--r-- | protocol.prs | 7 | ||||
-rw-r--r-- | sbom.json | 2 | ||||
-rw-r--r-- | src/nix_actor.nim | 2 | ||||
-rw-r--r-- | tests/test_eval_actor.nim | 191 |
4 files changed, 197 insertions, 5 deletions
diff --git a/protocol.prs b/protocol.prs index c39a44a6853d..e9ad096989c0 100644 --- a/protocol.prs +++ b/protocol.prs @@ -39,9 +39,10 @@ Realise = <realise @value any @result #:Result> . CopyClosure = <copy-closure @dest #:any @storePath string @result #:Result>. # Assertion. -# Eval at a nix-repo. @expr must be a function that takes two parameters, -# the first is the nix-repo value, the second is @args. -# The result is asserted to @result +# Eval at a nix capability. +# @expr must be a function that takes two parameters, +# the first is @args and the second is the value of +# the previous evaluation. The result is asserted to @result Eval = <eval @expr string @args any @result #:Result> . AttrSet = {symbol: any ...:...} . diff --git a/sbom.json b/sbom.json index 4082821204a3..12deb59ddb58 100644 --- a/sbom.json +++ b/sbom.json @@ -7,7 +7,7 @@ "bom-ref": "pkg:nim/nix_actor", "name": "nix_actor", "description": "Syndicated Nix Actor", - "version": "20240825", + "version": "20240826", "authors": [ { "name": "Emery Hemingway" diff --git a/src/nix_actor.nim b/src/nix_actor.nim index e19b1397e251..2a2715296159 100644 --- a/src/nix_actor.nim +++ b/src/nix_actor.nim @@ -154,8 +154,8 @@ proc serve(entity: NixEntity; turn: Turn; r: Realise) = proc serve(entity: NixEntity; turn: Turn; e: Eval) = tryPublish(turn, e.result.Cap): var expr = entity.state.eval.evalFromString(e.expr) - expr = entity.state.eval.apply(expr, entity.root) expr = entity.state.eval.apply(expr, e.args.toNix(entity.state.eval)) + expr = entity.state.eval.apply(expr, entity.root) publishOk(turn, e.result.Cap, entity.newChild(turn, expr).self.toPreserves) method publish(entity: NixEntity; turn: Turn; a: AssertionRef; h: Handle) = diff --git a/tests/test_eval_actor.nim b/tests/test_eval_actor.nim new file mode 100644 index 000000000000..384ab58635c0 --- /dev/null +++ b/tests/test_eval_actor.nim @@ -0,0 +1,191 @@ +# SPDX-FileCopyrightText: ☭ Emery Hemingway +# SPDX-License-Identifier: Unlicense + +import + std/options, + pkg/balls, + pkg/sys/ioqueue, + pkg/preserves, + pkg/preserves/sugar, + pkg/syndicate, + pkg/syndicate/protocols/[gatekeeper, rpc], + ../src/nix_actor, + ../src/nix_actor/[nix_api, nix_values, protocol] + +type Value = preserves.Value + +initLibstore() +initLibexpr() + +type + ResultContinuation {.final.} = ref object of Entity + cb: proc (turn: Turn; v: Value) + +method publish(cont: ResultContinuation; turn: Turn; ass: AssertionRef; h: Handle) = + cont.cb(turn, ass.value) + +proc newResultContinuation[T](turn: Turn; cb: proc (turn: Turn; v: T)): Cap = + proc wrapper(turn: Turn; v: Value) = + var + err: ResultError + ok: ResultOk + if err.fromPreserves(v): + raiseAssert $err.error + check ok.fromPreserves(v) + var x = ok.value.preservesTo(T) + check x.isSome + if x.isSome: cb(turn, x.get) + turn.newCap(ResultContinuation(cb: wrapper)) + +suite "basic": + + var completed: bool + + proc actorTest(turn: Turn) = + turn.onStop do (turn: Turn): + block: + ## actor stopped + check completed + + checkpoint "actor booted" + let rootFacet = turn.facet + let ds = turn.newDataspace() + + let stepC = newResultContinuation(turn) do (turn: Turn; nix: Cap): + checkpoint "stepC" + block: + ## stepC + onPublish(turn, nix, grab()) do (v: Value): + checkpoint("stepC grabbed nix value " & $v) + assert not v.isRecord("null") + assert v == %"Hello VolgaSprint!" + completed = true + stop(rootFacet) + + let stepB = newResultContinuation(turn) do (turn: Turn; nix: Cap): + checkpoint "stepB" + block: + ## stepB + onPublish(turn, nix, grab()) do (v: Value): + checkpoint("stepB grabbed nix value " & $v) + assert not v.isRecord("null") + check v == %"Hello Volga" + publish(turn, nix, Eval( + expr: "y: x: x + y", + args: %"Sprint!", + result: stepC + )) + + let stepA = newResultContinuation(turn) do (turn: Turn; nix: Cap): + checkpoint "stepA" + block: + ## stepA + onPublish(turn, nix, grab()) do (v: Value): + checkpoint "stepA grabbed nix value " & $v + assert not v.isRecord("null") + check v == %"Hello" + publish(turn, nix, Eval( + expr: "y: x: x + y", + args: %" Volga", + result: stepB + )) + + during(turn, ds, ResolvedAccepted.grabWithin) do (nix: Cap): + checkpoint "resolve accepted" + block: + ## Resolved nix actor through gatekeeper + onPublish(turn, nix, grab()) do (v: Value): + checkpoint $v + publish(turn, nix, Eval( + expr: "y: x: y", + args: %"Hello", + result: stepA, + )) + + during(turn, ds, Rejected.grabType) do (rej: Rejected): + raiseAssert("resolve failed: " & $rej) + + publish(turn, ds, Resolve( + step: parsePreserves"""<nix { }>""", + observer: ds, + )) + + nix_actor.bootActor(turn, ds) + + block: + ## runActor + runActor("tests", actorTest) + check completed + +suite "nixpkgs": + + var completed: bool + + proc actorTest(turn: Turn) = + turn.onStop do (turn: Turn): + block: + ## actor stopped + check completed + + checkpoint "actor booted" + let rootFacet = turn.facet + let ds = turn.newDataspace() + + let stepC = newResultContinuation(turn) do (turn: Turn; nix: Cap): + checkpoint "stepC" + block: + ## stepC + onPublish(turn, nix, grab()) do (v: Value): + checkpoint("stepC grabbed nix value " & $v) + assert v == %"https://9fans.github.io/plan9port/" + completed = true + stop(rootFacet) + + let stepB = newResultContinuation(turn) do (turn: Turn; nix: Cap): + checkpoint "stepB" + block: + ## stepB + publish(turn, nix, Eval( + expr: "_: pkg: pkg.meta.homepage", + args: %false, + result: stepC + )) + + let stepA = newResultContinuation(turn) do (turn: Turn; nix: Cap): + checkpoint "stepA" + block: + ## stepA + publish(turn, nix, Eval( + expr: "builtins.getAttr", + args: %"plan9port", + result: stepB + )) + + during(turn, ds, ResolvedAccepted.grabWithin) do (nix: Cap): + checkpoint "resolve accepted" + block: + ## Resolved nix actor through gatekeeper + onPublish(turn, nix, grab()) do (v: Value): + checkpoint $v + publish(turn, nix, Eval( + expr: "args: _: import <nixpkgs> args", + args: initDictionary(), + result: stepA, + )) + + during(turn, ds, Rejected.grabType) do (rej: Rejected): + raiseAssert("resolve failed: " & $rej) + + publish(turn, ds, Resolve( + step: parsePreserves""" + <nix { lookupPath: [ "nixpkgs=/home/repo/nixpkgs" ] }> + """, + observer: ds, + )) + + nix_actor.bootActor(turn, ds) + + block: + ## runActor + runActor("tests", actorTest) + check completed |