mirror of
https://github.com/nix-community/dream2nix.git
synced 2024-09-11 14:35:30 +03:00
test nix funcs with pytest via nix_ffi.py
This commit is contained in:
parent
d22d99ff96
commit
9d2d385273
19
.github/workflows/tests.yml
vendored
19
.github/workflows/tests.yml
vendored
@ -5,7 +5,7 @@ on:
|
||||
|
||||
jobs:
|
||||
|
||||
pure-tests:
|
||||
tests-pure:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2.4.0
|
||||
@ -22,7 +22,8 @@ jobs:
|
||||
|
||||
- run: nix flake check
|
||||
|
||||
impure-tests:
|
||||
|
||||
tests-impure:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2.4.0
|
||||
@ -38,3 +39,17 @@ jobs:
|
||||
signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'
|
||||
|
||||
- run: nix run .#tests-impure
|
||||
|
||||
|
||||
tests-unit-nix:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- uses: cachix/install-nix-action@v15
|
||||
with:
|
||||
install_url: https://nixos-nix-install-tests.cachix.org/serve/w659aglf1hfvkj5wj696q9x8r19p6b7k/install
|
||||
install_options: '--tarball-url-prefix https://nixos-nix-install-tests.cachix.org/serve'
|
||||
extra_nix_config: |
|
||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- run: nix run .#tests-unit
|
||||
|
14
flake.nix
14
flake.nix
@ -132,12 +132,14 @@
|
||||
# all apps including cli, install, etc.
|
||||
apps = forAllSystems (system: pkgs:
|
||||
dream2nixFor."${system}".apps.flakeApps // {
|
||||
tests-impure = {
|
||||
type = "app";
|
||||
program =
|
||||
b.toString
|
||||
(dream2nixFor."${system}".callPackageDream ./tests/impure {});
|
||||
};
|
||||
tests-impure.type = "app";
|
||||
tests-impure.program = b.toString
|
||||
(dream2nixFor."${system}".callPackageDream ./tests/impure {});
|
||||
tests-unit.type = "app";
|
||||
tests-unit.program = b.toString
|
||||
(dream2nixFor."${system}".callPackageDream ./tests/unit {
|
||||
inherit self;
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -8,8 +8,8 @@ import tempfile
|
||||
import networkx as nx
|
||||
from cleo import Command, argument, option
|
||||
|
||||
from utils import config, dream2nix_src, checkLockJSON, callNixFunction, buildNixFunction, buildNixAttribute, \
|
||||
list_translators_for_source, strip_hashes_from_lock
|
||||
from utils import config, dream2nix_src, checkLockJSON, list_translators_for_source, strip_hashes_from_lock
|
||||
from nix_ffi import callNixFunction, buildNixFunction, buildNixAttribute
|
||||
|
||||
|
||||
class AddCommand(Command):
|
||||
|
@ -6,7 +6,8 @@ import tempfile
|
||||
|
||||
from cleo import Command, argument, option
|
||||
|
||||
from utils import config, buildNixFunction, callNixFunction
|
||||
from utils import config
|
||||
from nix_ffi import callNixFunction, buildNixFunction
|
||||
|
||||
|
||||
class UpdateCommand(Command):
|
||||
|
89
src/apps/cli/nix_ffi.py
Normal file
89
src/apps/cli/nix_ffi.py
Normal file
@ -0,0 +1,89 @@
|
||||
import json
|
||||
import os
|
||||
import subprocess as sp
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
dream2nix_src = os.environ.get("dream2nixSrc")
|
||||
|
||||
|
||||
def callNixFunction(function_path, **kwargs):
|
||||
with tempfile.NamedTemporaryFile("w") as input_json_file:
|
||||
json.dump(dict(**kwargs), input_json_file, indent=2)
|
||||
input_json_file.seek(0) # flushes write cache
|
||||
env = os.environ.copy()
|
||||
env.update(dict(
|
||||
FUNC_ARGS=input_json_file.name
|
||||
))
|
||||
proc = sp.run(
|
||||
[
|
||||
"nix", "eval", "--show-trace", "--impure", "--raw", "--expr",
|
||||
f'''
|
||||
let
|
||||
d2n = (import {dream2nix_src} {{}});
|
||||
in
|
||||
builtins.toJSON (
|
||||
(d2n.utils.callViaEnv d2n.{function_path})
|
||||
)
|
||||
''',
|
||||
],
|
||||
capture_output=True,
|
||||
env=env
|
||||
)
|
||||
if proc.returncode:
|
||||
print(f"Failed calling nix function '{function_path}'", file=sys.stderr)
|
||||
print(proc.stderr.decode(), file=sys.stderr)
|
||||
exit(1)
|
||||
|
||||
# parse result data
|
||||
return json.loads(proc.stdout)
|
||||
|
||||
|
||||
def buildNixFunction(function_path, **kwargs):
|
||||
with tempfile.NamedTemporaryFile("w") as input_json_file:
|
||||
json.dump(dict(**kwargs), input_json_file, indent=2)
|
||||
input_json_file.seek(0) # flushes write cache
|
||||
env = os.environ.copy()
|
||||
env.update(dict(
|
||||
FUNC_ARGS=input_json_file.name
|
||||
))
|
||||
proc = sp.run(
|
||||
[
|
||||
"nix", "build", "--show-trace", "--impure", "-o", "tmp-result", "--expr",
|
||||
f'''
|
||||
let
|
||||
d2n = (import {dream2nix_src} {{}});
|
||||
in
|
||||
(d2n.utils.callVieEnv d2n.{function_path})
|
||||
''',
|
||||
],
|
||||
capture_output=True,
|
||||
env=env
|
||||
)
|
||||
if proc.returncode:
|
||||
print(f"Failed calling nix function '{function_path}'", file=sys.stderr)
|
||||
print(proc.stderr.decode(), file=sys.stderr)
|
||||
exit(1)
|
||||
|
||||
# return store path of result
|
||||
result = os.path.realpath("tmp-result")
|
||||
os.remove("tmp-result")
|
||||
return result
|
||||
|
||||
|
||||
def buildNixAttribute(attribute_path):
|
||||
proc = sp.run(
|
||||
[
|
||||
"nix", "build", "--show-trace", "--impure", "-o", "tmp-result", "--expr",
|
||||
f"(import {dream2nix_src} {{}}).{attribute_path}",
|
||||
],
|
||||
capture_output=True,
|
||||
)
|
||||
if proc.returncode:
|
||||
print(f"Failed to build '{attribute_path}'", file=sys.stderr)
|
||||
print(proc.stderr.decode(), file=sys.stderr)
|
||||
exit(1)
|
||||
|
||||
result = os.path.realpath("tmp-result")
|
||||
os.remove("tmp-result")
|
||||
return result
|
@ -2,10 +2,11 @@ import json
|
||||
import os
|
||||
import subprocess as sp
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
from jsonschema import validate
|
||||
|
||||
from nix_ffi import callNixFunction
|
||||
|
||||
dream2nix_src = os.environ.get("dream2nixSrc")
|
||||
|
||||
def find_repo_root():
|
||||
@ -45,88 +46,6 @@ def checkLockJSON(lock):
|
||||
raise
|
||||
|
||||
|
||||
def callNixFunction(function_path, **kwargs):
|
||||
with tempfile.NamedTemporaryFile("w") as input_json_file:
|
||||
json.dump(dict(**kwargs), input_json_file, indent=2)
|
||||
input_json_file.seek(0) # flushes write cache
|
||||
env = os.environ.copy()
|
||||
env.update(dict(
|
||||
FUNC_ARGS=input_json_file.name
|
||||
))
|
||||
proc = sp.run(
|
||||
[
|
||||
"nix", "eval", "--show-trace", "--impure", "--raw", "--expr",
|
||||
f'''
|
||||
let
|
||||
d2n = (import {dream2nix_src} {{}});
|
||||
in
|
||||
builtins.toJSON (
|
||||
(d2n.utils.makeCallableViaEnv d2n.{function_path}) {{}}
|
||||
)
|
||||
''',
|
||||
],
|
||||
capture_output=True,
|
||||
env=env
|
||||
)
|
||||
if proc.returncode:
|
||||
print(f"Failed calling nix function '{function_path}'", file=sys.stderr)
|
||||
print(proc.stderr.decode(), file=sys.stderr)
|
||||
exit(1)
|
||||
|
||||
# parse result data
|
||||
return json.loads(proc.stdout)
|
||||
|
||||
|
||||
def buildNixFunction(function_path, **kwargs):
|
||||
with tempfile.NamedTemporaryFile("w") as input_json_file:
|
||||
json.dump(dict(**kwargs), input_json_file, indent=2)
|
||||
input_json_file.seek(0) # flushes write cache
|
||||
env = os.environ.copy()
|
||||
env.update(dict(
|
||||
FUNC_ARGS=input_json_file.name
|
||||
))
|
||||
proc = sp.run(
|
||||
[
|
||||
"nix", "build", "--show-trace", "--impure", "-o", "tmp-result", "--expr",
|
||||
f'''
|
||||
let
|
||||
d2n = (import {dream2nix_src} {{}});
|
||||
in
|
||||
(d2n.utils.makeCallableViaEnv d2n.{function_path}) {{}}
|
||||
''',
|
||||
],
|
||||
capture_output=True,
|
||||
env=env
|
||||
)
|
||||
if proc.returncode:
|
||||
print(f"Failed calling nix function '{function_path}'", file=sys.stderr)
|
||||
print(proc.stderr.decode(), file=sys.stderr)
|
||||
exit(1)
|
||||
|
||||
# return store path of result
|
||||
result = os.path.realpath("tmp-result")
|
||||
os.remove("tmp-result")
|
||||
return result
|
||||
|
||||
|
||||
def buildNixAttribute(attribute_path):
|
||||
proc = sp.run(
|
||||
[
|
||||
"nix", "build", "--show-trace", "--impure", "-o", "tmp-result", "--expr",
|
||||
f"(import {dream2nix_src} {{}}).{attribute_path}",
|
||||
],
|
||||
capture_output=True,
|
||||
)
|
||||
if proc.returncode:
|
||||
print(f"Failed to build '{attribute_path}'", file=sys.stderr)
|
||||
print(proc.stderr.decode(), file=sys.stderr)
|
||||
exit(1)
|
||||
|
||||
result = os.path.realpath("tmp-result")
|
||||
os.remove("tmp-result")
|
||||
return result
|
||||
|
||||
|
||||
def list_translators_for_source(sourcePath):
|
||||
translatorsList = callNixFunction(
|
||||
"translators.translatorsForInput",
|
||||
|
@ -75,13 +75,33 @@ rec {
|
||||
(pattern: lib.any (file: b.match pattern file != null) (listFiles dir))
|
||||
patterns;
|
||||
|
||||
# allow a function to receive its input from an environment variable
|
||||
# whenever an empty set is passed
|
||||
makeCallableViaEnv = func: args:
|
||||
if args == {} then
|
||||
func (builtins.fromJSON (builtins.readFile (builtins.getEnv "FUNC_ARGS")))
|
||||
else
|
||||
func args;
|
||||
# Calls any function with an attrset arugment, even if that function
|
||||
# doesn't accept an attrset argument, in which case the arguments are
|
||||
# recursively applied as parameters.
|
||||
# For this to work, the function parameters defined by the called function
|
||||
# must always be ordered alphabetically.
|
||||
callWithAttrArgs = func: args:
|
||||
let
|
||||
applyParamsRec = func: params:
|
||||
if b.length params == 1 then
|
||||
func (b.head params)
|
||||
else
|
||||
applyParamsRec
|
||||
(func (b.head params))
|
||||
(b.tail params);
|
||||
|
||||
in
|
||||
if lib.functionArgs func == {} then
|
||||
applyParamsRec func (b.attrValues args)
|
||||
else
|
||||
func args;
|
||||
|
||||
# call a function using arguments defined by the env var FUNC_ARGS
|
||||
callViaEnv = func:
|
||||
let
|
||||
funcArgs = b.fromJSON (b.readFile (b.getEnv "FUNC_ARGS"));
|
||||
in
|
||||
callWithAttrArgs func funcArgs;
|
||||
|
||||
# hash the contents of a path via `nix hash path`
|
||||
hashPath = algo: path:
|
||||
@ -147,42 +167,12 @@ rec {
|
||||
{ inherit name version; };
|
||||
|
||||
# determines if version v1 is greater than version v2
|
||||
versionGreater = v1: v2:
|
||||
versionGreaterList
|
||||
(lib.splitString "." v1)
|
||||
(lib.splitString "." v2);
|
||||
|
||||
# internal helper for 'versionGreater'
|
||||
versionGreaterList = v1: v2:
|
||||
let
|
||||
head1 = b.head v1;
|
||||
head2 = b.head v2;
|
||||
n1 =
|
||||
if builtins.match ''[[:digit:]]*'' head1 != null then
|
||||
lib.toInt head1
|
||||
else
|
||||
0;
|
||||
n2 = if builtins.match ''[[:digit:]]*'' head2 != null then
|
||||
lib.toInt head2
|
||||
else
|
||||
0;
|
||||
in
|
||||
if n1 > n2 then
|
||||
true
|
||||
else
|
||||
# end recursion condition
|
||||
if b.length v1 == 1 || b.length v1 == 1 then
|
||||
false
|
||||
else
|
||||
# continue recursion
|
||||
versionGreaterList (b.tail v1) (b.tail v2);
|
||||
versionGreater = v1: v2: b.compareVersions v1 v2 == 1;
|
||||
|
||||
# picks the latest version from a list of version strings
|
||||
latestVersion = versions:
|
||||
b.head
|
||||
(lib.sort
|
||||
(v1: v2: versionGreater v1 v2)
|
||||
versions);
|
||||
(lib.sort versionGreater versions);
|
||||
|
||||
satisfiesSemver = poetry2nixSemver.satisfiesSemver;
|
||||
|
||||
|
23
tests/unit/default.nix
Normal file
23
tests/unit/default.nix
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
self,
|
||||
|
||||
lib,
|
||||
nix,
|
||||
python3,
|
||||
|
||||
utils,
|
||||
dream2nixWithExternals,
|
||||
...
|
||||
}:
|
||||
let
|
||||
l = lib // builtins;
|
||||
|
||||
in
|
||||
utils.writePureShellScript
|
||||
[
|
||||
nix
|
||||
]
|
||||
''
|
||||
export dream2nixSrc=${dream2nixWithExternals}
|
||||
${python3.pkgs.pytest}/bin/pytest ${self}/tests/unit
|
||||
''
|
1
tests/unit/nix_ffi.py
Symbolic link
1
tests/unit/nix_ffi.py
Symbolic link
@ -0,0 +1 @@
|
||||
../../src/apps/cli/nix_ffi.py
|
9
tests/unit/test_nix.py
Normal file
9
tests/unit/test_nix.py
Normal file
@ -0,0 +1,9 @@
|
||||
import pytest
|
||||
import nix_ffi
|
||||
|
||||
@pytest.mark.parametrize("expected, versions", [
|
||||
('3', [ '2', '3', '1' ]),
|
||||
])
|
||||
def test_latestVersion(expected, versions):
|
||||
result = nix_ffi.callNixFunction('utils.latestVersion', versions=versions)
|
||||
assert result == expected
|
Loading…
Reference in New Issue
Block a user