1--
2-- This file and its contents are supplied under the terms of the
3-- Common Development and Distribution License ("CDDL"), version 1.0.
4-- You may only use this file in accordance with the terms of version
5-- 1.0 of the CDDL.
6--
7-- A full copy of the text of the CDDL should have accompanied this
8-- source.  A copy of the CDDL is also available via the Internet at
9-- http://www.illumos.org/license/CDDL.
10--
11
12--
13-- Copyright (c) 2017 by Delphix. All rights reserved.
14-- Copyright 2020 Joyent, Inc.
15--
16
17arg = ...
18fs = arg["argv"][1]
19
20-- values from zfs.h
21maxname = 256       -- ZAP_MAXNAMELEN
22maxvalue = 8192     -- ZAP_MAXVALUELEN
23
24pos_props = {}
25neg_props = {}
26
27-- In lua, strings are immutable, so to avoid a bunch of copies, we
28-- build the value in a table and use concat (which appears to be the
29-- recommended method for such things).
30largeprop = {}
31for i = 0,maxvalue,8
32do
33    table.insert(largeprop, "aaaaaaaa")
34end
35-- add an extra character so we spill over the limit
36table.insert(largeprop, "b")
37
38largepropv = table.concat(largeprop)
39
40largepropname = { "b:" }
41for i = 0,maxname,8
42do
43    table.insert(largepropname, "aaaaaaaa")
44end
45largepropnamev = table.concat(largepropname)
46
47pos_props["a:prop"] = {"hello"}
48
49-- For neg_props, an optional expected error value can be added after the
50-- property value as seen below.
51neg_props["notaproperty"] = {"hello", EINVAL}
52neg_props["a:very.long.property.value"] = { largepropv, E2BIG }
53neg_props[largepropnamev] = {"greetings", ENAMETOOLONG }
54
55-- non-user properties aren't currently supported
56-- Even if they were, the argument must be a string due to requirements of
57-- the ZCP api.
58neg_props["mountpoint"] = {"/foo/bar"}
59neg_props["copies"] = { "2" }
60
61-- read-only properties should never succeed
62neg_props["guid"] = { "12345" }
63
64set_fail = {}
65val_fail = {}
66
67-- Test properties that should work
68for prop, values in pairs(pos_props) do
69    for i, val in ipairs(values) do
70        old_val, src = zfs.get_prop(fs, prop)
71
72        -- Attempt to set the property to the specified value
73        err = zfs.sync.set_prop(fs, prop, val)
74
75        if (err ~= 0) then
76            set_fail[prop] = err -- tuple of prop, val that resulted in error
77        else
78            -- use get_prop to check that the set took effect
79            new_val, src = zfs.get_prop(fs, prop)
80            if (tostring(new_val) ~= tostring(val)) then
81                val_fail[prop] = new_val
82            end
83
84            -- We modified the prop, restore old value (if one existed)
85            if (old_val ~= nil) then
86                err = zfs.sync.set_prop(fs, prop, old_val)
87                if (err ~= 0) then return err end
88            else
89                -- Didn't have an old value, delete (inherit) instead
90                err = zfs.sync.inherit(fs, prop)
91                if (err ~= 0) then return err end
92            end
93        end
94    end
95end
96
97-- Test properties that should fail
98for prop, expected in pairs(neg_props) do
99    exp_val = expected[1]
100    exp_err = expected[2]
101
102    -- Attempt to set the property to the specified value
103    err = zfs.sync.set_prop(fs, prop, exp_val)
104    if (err == 0 or (exp_err ~= nil and err ~= exp_err)) then
105        set_fail[prop] = err -- tuple of prop, val that resulted in error
106    end
107end
108
109return {set_fail, val_fail}
110