t_nice.c revision 276478
1164190Sjkoshy/*	$NetBSD: t_nice.c,v 1.8 2012/03/18 07:00:51 jruoho Exp $ */
2164190Sjkoshy
3164190Sjkoshy/*-
4164190Sjkoshy * Copyright (c) 2011 The NetBSD Foundation, Inc.
5164190Sjkoshy * All rights reserved.
6164190Sjkoshy *
7164190Sjkoshy * This code is derived from software contributed to The NetBSD Foundation
8164190Sjkoshy * by Jukka Ruohonen.
9164190Sjkoshy *
10164190Sjkoshy * Redistribution and use in source and binary forms, with or without
11164190Sjkoshy * modification, are permitted provided that the following conditions
12164190Sjkoshy * are met:
13164190Sjkoshy * 1. Redistributions of source code must retain the above copyright
14164190Sjkoshy *    notice, this list of conditions and the following disclaimer.
15164190Sjkoshy * 2. Redistributions in binary form must reproduce the above copyright
16164190Sjkoshy *    notice, this list of conditions and the following disclaimer in the
17164190Sjkoshy *    documentation and/or other materials provided with the distribution.
18164190Sjkoshy *
19164190Sjkoshy * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20164190Sjkoshy * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21165535Sjkoshy * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22164190Sjkoshy * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23164190Sjkoshy * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24164190Sjkoshy * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25164190Sjkoshy * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26164190Sjkoshy * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27164190Sjkoshy * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28165317Sjkoshy * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29164190Sjkoshy * POSSIBILITY OF SUCH DAMAGE.
30164190Sjkoshy */
31164190Sjkoshy#include <sys/cdefs.h>
32165317Sjkoshy__RCSID("$NetBSD: t_nice.c,v 1.8 2012/03/18 07:00:51 jruoho Exp $");
33165317Sjkoshy
34165317Sjkoshy#include <sys/resource.h>
35164190Sjkoshy#include <sys/wait.h>
36164190Sjkoshy
37164190Sjkoshy#include <atf-c.h>
38164190Sjkoshy#include <errno.h>
39164190Sjkoshy#include <limits.h>
40165317Sjkoshy#include <pthread.h>
41164190Sjkoshy#include <stdlib.h>
42164190Sjkoshy#include <unistd.h>
43164190Sjkoshy
44164190Sjkoshystatic void	*threadfunc(void *);
45164190Sjkoshy
46164190Sjkoshystatic void *
47210348Skaiwthreadfunc(void *arg)
48164190Sjkoshy{
49164190Sjkoshy	int pri, val;
50164190Sjkoshy
51165535Sjkoshy	val = *(int *)arg;
52164190Sjkoshy
53164190Sjkoshy	errno = 0;
54164225Sjkoshy	pri = getpriority(PRIO_PROCESS, 0);
55164225Sjkoshy	ATF_REQUIRE(errno == 0);
56164190Sjkoshy
57164190Sjkoshy	if (pri != val)
58237528Sandrew		atf_tc_fail("nice(3) value was not propagated to threads");
59237528Sandrew
60237528Sandrew	return NULL;
61237528Sandrew}
62237528Sandrew
63237528SandrewATF_TC(nice_err);
64237528SandrewATF_TC_HEAD(nice_err, tc)
65237528Sandrew{
66164577Sru	atf_tc_set_md_var(tc, "descr",
67164577Sru	    "Test nice(3) for invalid parameters (PR lib/42587)");
68237531Sandrew	atf_tc_set_md_var(tc, "require.user", "unprivileged");
69237528Sandrew}
70164190Sjkoshy
71238741SacheATF_TC_BODY(nice_err, tc)
72238741Sache{
73237528Sandrew	int i;
74237528Sandrew
75164190Sjkoshy#ifdef __FreeBSD__
76164190Sjkoshy	atf_tc_expect_fail("nice(incr) with incr < 0 fails with unprivileged "
77164190Sjkoshy	   "users and sets errno == EPERM; see PR # 189821 for more details");
78164190Sjkoshy#endif
79164190Sjkoshy
80210345Skaiw	/*
81210345Skaiw	 * The call should fail with EPERM if the
82164190Sjkoshy	 * supplied parameter is negative and the
83164190Sjkoshy	 * caller does not have privileges.
84164190Sjkoshy	 */
85164190Sjkoshy	for (i = -20; i < 0; i++) {
86164190Sjkoshy
87164190Sjkoshy		errno = 0;
88164190Sjkoshy
89164190Sjkoshy		ATF_REQUIRE_ERRNO(EPERM, nice(i) == -1);
90210345Skaiw	}
91165535Sjkoshy}
92210345Skaiw
93164190SjkoshyATF_TC(nice_priority);
94210345SkaiwATF_TC_HEAD(nice_priority, tc)
95164190Sjkoshy{
96164190Sjkoshy	atf_tc_set_md_var(tc, "descr", "Test nice(3) vs. getpriority(2)");
97164190Sjkoshy}
98164190Sjkoshy
99164190SjkoshyATF_TC_BODY(nice_priority, tc)
100164190Sjkoshy{
101164190Sjkoshy#ifdef __FreeBSD__
102164190Sjkoshy	int i, pri, pri2, nic;
103164190Sjkoshy#else
104164190Sjkoshy	int i, pri, nic;
105164190Sjkoshy#endif
106164190Sjkoshy	pid_t pid;
107164190Sjkoshy	int sta;
108164190Sjkoshy
109164190Sjkoshy	for (i = 0; i <= 20; i++) {
110164190Sjkoshy
111164190Sjkoshy		nic = nice(i);
112164190Sjkoshy		ATF_REQUIRE(nic != -1);
113164190Sjkoshy
114164190Sjkoshy		errno = 0;
115164190Sjkoshy		pri = getpriority(PRIO_PROCESS, 0);
116164190Sjkoshy		ATF_REQUIRE(errno == 0);
117164190Sjkoshy
118164190Sjkoshy#ifdef __NetBSD__
119164190Sjkoshy		if (nic != pri)
120164190Sjkoshy			atf_tc_fail("nice(3) and getpriority(2) conflict");
121164190Sjkoshy#endif
122164190Sjkoshy
123164190Sjkoshy		/*
124164190Sjkoshy		 * Also verify that the nice(3) values
125164190Sjkoshy		 * are inherited by child processes.
126164190Sjkoshy		 */
127164190Sjkoshy		pid = fork();
128164190Sjkoshy		ATF_REQUIRE(pid >= 0);
129164190Sjkoshy
130164190Sjkoshy		if (pid == 0) {
131164190Sjkoshy
132164190Sjkoshy			errno = 0;
133164190Sjkoshy#ifdef __FreeBSD__
134164190Sjkoshy			pri = getpriority(PRIO_PROCESS, 0);
135164190Sjkoshy#else
136164190Sjkoshy			pri2 = getpriority(PRIO_PROCESS, 0);
137164190Sjkoshy#endif
138164190Sjkoshy			ATF_REQUIRE(errno == 0);
139164190Sjkoshy
140164190Sjkoshy#ifdef __FreeBSD__
141164190Sjkoshy			if (pri != pri2)
142164190Sjkoshy#else
143164190Sjkoshy			if (nic != pri)
144164190Sjkoshy#endif
145164190Sjkoshy				_exit(EXIT_FAILURE);
146164190Sjkoshy
147164190Sjkoshy			_exit(EXIT_SUCCESS);
148164190Sjkoshy		}
149164190Sjkoshy
150164190Sjkoshy		(void)wait(&sta);
151164190Sjkoshy
152164190Sjkoshy		if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
153164190Sjkoshy			atf_tc_fail("nice(3) value was not inherited");
154164190Sjkoshy	}
155164190Sjkoshy}
156164190Sjkoshy
157164190SjkoshyATF_TC(nice_root);
158164190SjkoshyATF_TC_HEAD(nice_root, tc)
159164190Sjkoshy{
160164190Sjkoshy	atf_tc_set_md_var(tc, "descr", "Test that nice(3) works");
161164190Sjkoshy	atf_tc_set_md_var(tc, "require.user", "root");
162164190Sjkoshy}
163164190Sjkoshy
164164190SjkoshyATF_TC_BODY(nice_root, tc)
165164190Sjkoshy{
166164190Sjkoshy	int i;
167189721Sobrien
168164190Sjkoshy	for (i = -20; i <= 20; i++) {
169164190Sjkoshy
170164190Sjkoshy		ATF_REQUIRE(nice(i) != -1);
171164190Sjkoshy	}
172164190Sjkoshy}
173164190Sjkoshy
174164190SjkoshyATF_TC(nice_thread);
175164190SjkoshyATF_TC_HEAD(nice_thread, tc)
176164225Sjkoshy{
177164190Sjkoshy	atf_tc_set_md_var(tc, "descr", "Test nice(3) with threads");
178164190Sjkoshy}
179165317Sjkoshy
180ATF_TC_BODY(nice_thread, tc)
181{
182	pthread_t tid[5];
183#ifdef __FreeBSD__
184	int pri, rv, val;
185#else
186	int rv, val;
187#endif
188	size_t i;
189
190	/*
191	 * Test that the scheduling priority is
192	 * propagated to all system scope threads.
193	 */
194	for (i = 0; i < __arraycount(tid); i++) {
195
196		val = nice(i);
197		ATF_REQUIRE(val != -1);
198
199#ifdef __FreeBSD__
200		pri = getpriority(PRIO_PROCESS, 0);
201		rv = pthread_create(&tid[i], NULL, threadfunc, &pri);
202#else
203		rv = pthread_create(&tid[i], NULL, threadfunc, &val);
204#endif
205		ATF_REQUIRE(rv == 0);
206
207		rv = pthread_join(tid[i], NULL);
208		ATF_REQUIRE(rv == 0);
209	}
210}
211
212ATF_TP_ADD_TCS(tp)
213{
214
215	ATF_TP_ADD_TC(tp, nice_err);
216	ATF_TP_ADD_TC(tp, nice_priority);
217	ATF_TP_ADD_TC(tp, nice_root);
218	ATF_TP_ADD_TC(tp, nice_thread);
219
220	return atf_no_error();
221}
222