1import ./make-test-python.nix ({ pkgs, ...} :
2
3let
4 # Since we don't have access to the internet during the tests, we have to
5 # pre-fetch lxd containers beforehand.
6 #
7 # I've chosen to import Alpine Linux, because its image is turbo-tiny and,
8 # generally, sufficient for our tests.
9 alpine-meta = pkgs.fetchurl {
10 url = "https://tarballs.nixos.org/alpine/3.12/lxd.tar.xz";
11 hash = "sha256-1tcKaO9lOkvqfmG/7FMbfAEToAuFy2YMewS8ysBKuLA=";
12 };
13
14 alpine-rootfs = pkgs.fetchurl {
15 url = "https://tarballs.nixos.org/alpine/3.12/rootfs.tar.xz";
16 hash = "sha256-Tba9sSoaiMtQLY45u7p5DMqXTSDgs/763L/SQp0bkCA=";
17 };
18
19 lxd-config = pkgs.writeText "config.yaml" ''
20 storage_pools:
21 - name: default
22 driver: dir
23 config:
24 source: /var/lxd-pool
25
26 networks:
27 - name: lxdbr0
28 type: bridge
29 config:
30 ipv4.address: auto
31 ipv6.address: none
32
33 profiles:
34 - name: default
35 devices:
36 eth0:
37 name: eth0
38 network: lxdbr0
39 type: nic
40 root:
41 path: /
42 pool: default
43 type: disk
44 '';
45
46
47in {
48 name = "lxd";
49
50 meta = with pkgs.lib.maintainers; {
51 maintainers = [ patryk27 ];
52 };
53
54 machine = { lib, ... }: {
55 virtualisation = {
56 # Since we're testing `limits.cpu`, we've gotta have a known number of
57 # cores to lean on
58 cores = 2;
59
60 # Ditto, for `limits.memory`
61 memorySize = 512;
62
63 lxc.lxcfs.enable = true;
64 lxd.enable = true;
65 };
66 };
67
68 testScript = ''
69 machine.wait_for_unit("sockets.target")
70 machine.wait_for_unit("lxd.service")
71 machine.wait_for_file("/var/lib/lxd/unix.socket")
72
73 # It takes additional second for lxd to settle
74 machine.sleep(1)
75
76 # lxd expects the pool's directory to already exist
77 machine.succeed("mkdir /var/lxd-pool")
78
79 machine.succeed(
80 "cat ${lxd-config} | lxd init --preseed"
81 )
82
83 machine.succeed(
84 "lxc image import ${alpine-meta} ${alpine-rootfs} --alias alpine"
85 )
86
87 with subtest("Containers can be launched and destroyed"):
88 machine.succeed("lxc launch alpine test")
89 machine.succeed("lxc exec test true")
90 machine.succeed("lxc delete -f test")
91
92 with subtest("Containers are being mounted with lxcfs inside"):
93 machine.succeed("lxc launch alpine test")
94
95 ## ---------- ##
96 ## limits.cpu ##
97
98 machine.succeed("lxc config set test limits.cpu 1")
99 machine.succeed("lxc restart test")
100
101 # Since Alpine doesn't have `nproc` pre-installed, we've gotta resort
102 # to the primal methods
103 assert (
104 "1"
105 == machine.succeed("lxc exec test grep -- -c ^processor /proc/cpuinfo").strip()
106 )
107
108 machine.succeed("lxc config set test limits.cpu 2")
109 machine.succeed("lxc restart test")
110
111 assert (
112 "2"
113 == machine.succeed("lxc exec test grep -- -c ^processor /proc/cpuinfo").strip()
114 )
115
116 ## ------------- ##
117 ## limits.memory ##
118
119 machine.succeed("lxc config set test limits.memory 64MB")
120 machine.succeed("lxc restart test")
121
122 assert (
123 "MemTotal: 62500 kB"
124 == machine.succeed("lxc exec test grep -- MemTotal /proc/meminfo").strip()
125 )
126
127 machine.succeed("lxc config set test limits.memory 128MB")
128 machine.succeed("lxc restart test")
129
130 assert (
131 "MemTotal: 125000 kB"
132 == machine.succeed("lxc exec test grep -- MemTotal /proc/meminfo").strip()
133 )
134
135 machine.succeed("lxc delete -f test")
136 '';
137})