xref: /illumos-gate/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_program/zfs_program_json.ksh (revision f52943a93040563107b95bccb9db87d9971ef47d)
1#!/bin/ksh -p
2#
3# CDDL HEADER START
4#
5# This file and its contents are supplied under the terms of the
6# Common Development and Distribution License ("CDDL"), version 1.0.
7# You may only use this file in accordance with the terms of version
8# 1.0 of the CDDL.
9#
10# A full copy of the text of the CDDL should have accompanied this
11# source.  A copy is of the CDDL is also available via the Internet
12# at http://www.illumos.org/license/CDDL.
13#
14# CDDL HEADER END
15#
16
17#
18# Copyright (c) 2018 Datto Inc.
19#
20
21. $STF_SUITE/include/libtest.shlib
22
23#
24# DESCRIPTION:
25#
26# STRATEGY:
27#	1. Ensure empty JSON is printed when there is no channel program output
28#	2. Compare JSON output formatting for a channel program to template
29#	3. Using bad command line option (-Z) gives correct error output
30#
31
32verify_runnable "both"
33
34function cleanup
35{
36	log_must zfs destroy -r $TESTDS
37	return 0
38}
39log_onexit cleanup
40
41log_assert "Channel programs output valid JSON"
42
43TESTDS="$TESTPOOL/zcp-json"
44TESTSNAP="$TESTDS@snap0"
45log_must zfs create $TESTDS
46
47# 1. Ensure empty JSON is printed when there is no channel program output
48TESTZCP="/$TESTDS/zfs_destroy.zcp"
49cat > "$TESTZCP" << EOF
50       args = ...
51       argv = args["argv"]
52       zfs.sync.destroy(argv[1])
53EOF
54
55EMPTY_OUTPUT=("{}")
56log_must zfs snap $TESTSNAP 2>&1
57log_must zfs list $TESTSNAP 2>&1
58log_must zfs program $TESTPOOL $TESTZCP $TESTSNAP 2>&1
59log_mustnot zfs list $TESTSNAP 2>&1
60log_must zfs snap $TESTSNAP 2>&1
61log_must zfs list $TESTSNAP 2>&1
62log_must zfs program -j $TESTPOOL $TESTZCP $TESTSNAP 2>&1
63log_mustnot zfs list $TESTSNAP 2>&1
64log_must zfs snap $TESTSNAP 2>&1
65log_must zfs list $TESTSNAP 2>&1
66OUTPUT=$(zfs program -j $TESTPOOL $TESTZCP $TESTSNAP 2>&1)
67if [ "$OUTPUT" != "$EMPTY_OUTPUT" ]; then
68       log_note "Got     :$OUTPUT"
69       log_note "Expected:$EMPTY_OUTPUT"
70       log_fail "Channel program output not empty";
71fi
72log_mustnot zfs list $TESTSNAP 2>&1
73
74# 2. Compare JSON output formatting for a channel program to template
75TESTZCP="/$TESTDS/zfs_rlist.zcp"
76cat > "$TESTZCP" << EOF
77	succeeded = {}
78	failed = {}
79
80	function list_recursive(root, prop)
81		for child in zfs.list.children(root) do
82			list_recursive(child, prop)
83		end
84		val, src  = zfs.get_prop(root, prop)
85		if (val == nil) then
86			failed[root] = val
87		else
88			succeeded[root] = val
89		end
90	end
91
92	args = ...
93
94	argv = args["argv"]
95
96	list_recursive(argv[1], argv[2])
97
98	results = {}
99	results["succeeded"] = succeeded
100	results["failed"] = failed
101	return results
102EOF
103
104typeset -a pos_cmds=("recordsize" "type")
105typeset -a pos_cmds_out=(
106"{
107    \"return\": {
108        \"failed\": {},
109        \"succeeded\": {
110            \"$TESTDS\": 131072
111        }
112    }
113}"
114"{
115    \"return\": {
116        \"failed\": {},
117        \"succeeded\": {
118            \"$TESTDS\": \"filesystem\"
119        }
120    }
121}")
122typeset -i cnt=0
123typeset cmd
124for cmd in ${pos_cmds[@]}; do
125	log_must zfs program $TESTPOOL $TESTZCP $TESTDS $cmd 2>&1
126	log_must zfs program -j $TESTPOOL $TESTZCP $TESTDS $cmd 2>&1
127	# json.tool is needed to guarantee consistent ordering of fields
128	# sed is needed to trim trailing space in CentOS 6's json.tool output
129	OUTPUT=$(zfs program -j $TESTPOOL $TESTZCP $TESTDS $cmd 2>&1 | python -m json.tool | sed 's/[[:space:]]*$//')
130	if [ "$OUTPUT" != "${pos_cmds_out[$cnt]}" ]; then
131		log_note "Got     :$OUTPUT"
132		log_note "Expected:${pos_cmds_out[$cnt]}"
133		log_fail "Unexpected channel program output";
134	fi
135	cnt=$((cnt + 1))
136done
137
138# 3. Using bad command line option (-Z) gives correct error output
139typeset -a neg_cmds=("-Z")
140typeset -a neg_cmds_out=(
141"invalid option 'Z'
142usage:
143	program [-jn] [-t <instruction limit>] [-m <memory limit (b)>] <pool> <program file> [lua args...]
144
145For the property list, run: zfs set|get
146
147For the delegated permission list, run: zfs allow|unallow")
148cnt=0
149for cmd in ${neg_cmds[@]}; do
150	log_mustnot zfs program $cmd $TESTPOOL $TESTZCP $TESTDS 2>&1
151	log_mustnot zfs program -j $cmd $TESTPOOL $TESTZCP $TESTDS 2>&1
152	OUTPUT=$(zfs program -j $cmd $TESTPOOL $TESTZCP $TESTDS 2>&1)
153	if [ "$OUTPUT" != "${neg_cmds_out[$cnt]}" ]; then
154		log_note "Got     :$OUTPUT"
155		log_note "Expected:${neg_cmds_out[$cnt]}"
156		log_fail "Unexpected channel program error output";
157	fi
158	cnt=$((cnt + 1))
159done
160
161log_pass "Channel programs output valid JSON"
162