summaryrefslogtreecommitdiffstats
path: root/test/ruby/test_method.rb
blob: c30705cb15e0d73e1c58d8768c252c6ce0c26379 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
require 'test/unit'

class TestMethod < Test::Unit::TestCase
  def m0() end
  def m1(a) end
  def m2(a, b) end
  def mo1(a = nil, &b) end
  def mo2(a, b = nil) end
  def mo3(*a) end
  def mo4(a, *b, &c) end

  class Base
    def foo() :base end
  end
  class Derived < Base
    def foo() :derived end
  end

  def test_arity
    assert_equal(0, method(:m0).arity)
    assert_equal(1, method(:m1).arity)
    assert_equal(2, method(:m2).arity)
    assert_equal(-1, method(:mo1).arity)
    assert_equal(-2, method(:mo2).arity)
    assert_equal(-1, method(:mo3).arity)
    assert_equal(-2, method(:mo4).arity)
  end

  def test_unbind
    assert_equal(:derived, Derived.new.foo)
    um = Derived.new.method(:foo).unbind
    assert_instance_of(UnboundMethod, um)
    Derived.class_eval do
      def foo() :changed end
    end
    assert_equal(:changed, Derived.new.foo)
    assert_equal(:derived, um.bind(Derived.new).call)
    assert_raise(TypeError) do
      um.bind(Base.new)
    end
  end
end
'>241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272
/* The kernel log module.
 *
 * This is an abstracted module. As Linux and BSD kernel log is conceptually the
 * same, we do not do different input plugins for them but use
 * imklog in both cases, just with different "backend drivers" for
 * the different platforms. This also enables a rsyslog.conf to
 * be used on multiple platforms without the need to take care of
 * what the kernel log is coming from.
 *
 * See platform-specific files (e.g. linux.c, bsd.c) in the plugin's
 * working directory. For other systems with similar kernel logging
 * functionality, no new input plugin shall be written but rather a
 * driver be developed for imklog. Please note that imklog itself is
 * mostly concerned with handling the interface. Any real action happens
 * in the drivers, as things may be pretty different on different
 * platforms.
 *
 * Please note that this file replaces the klogd daemon that was
 * also present in pre-v3 versions of rsyslog.
 *
 * Copyright (C) 2008 by Rainer Gerhards and Adiscon GmbH
 *
 * This file is part of rsyslog.
 *
 * Rsyslog is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Rsyslog is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Rsyslog.  If not, see <http://www.gnu.org/licenses/>.
 *
 * A copy of the GPL can be found in the file "COPYING" in this distribution.
*/
#include "config.h"
#include "rsyslog.h"
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdarg.h>
#include <ctype.h>

#include "dirty.h"
#include "cfsysline.h"
#include "obj.h"
#include "msg.h"
#include "module-template.h"
#include "datetime.h"
#include "imklog.h"
#include "glbl.h"

MODULE_TYPE_INPUT

/* Module static data */
DEF_IMOD_STATIC_DATA
DEFobjCurrIf(datetime)
DEFobjCurrIf(glbl)

/* configuration settings */
int dbgPrintSymbols = 0; /* this one is extern so the helpers can access it! */
int symbols_twice = 0;
int use_syscall = 0;
int symbol_lookup = 0; /* on recent kernels > 2.6, the kernel does this */
int bPermitNonKernel = 0; /* permit logging of messages not having LOG_KERN facility */
int iFacilIntMsg; /* the facility to use for internal messages (set by driver) */
/* TODO: configuration for the following directives must be implemented. It 
 * was not done yet because we either do not yet have a config handler for
 * that type or I thought it was acceptable to push it to a later stage when
 * I gained more handson experience with the input module interface (and the
 * changes resulting from that). -- rgerhards, 2007-12-20
 */
char *symfile = NULL; 
int console_log_level = -1;


/* enqueue the the kernel message into the message queue.
 * The provided msg string is not freed - thus must be done
 * by the caller.
 * rgerhards, 2008-04-12
 */
static rsRetVal
enqMsg(uchar *msg, uchar* pszTag, int iFacility, int iSeverity)
{
	DEFiRet;
	msg_t *pMsg;

	assert(msg != NULL);
	assert(pszTag != NULL);

	CHKiRet(msgConstruct(&pMsg));
	MsgSetFlowControlType(pMsg, eFLOWCTL_LIGHT_DELAY);
	MsgSetUxTradMsg(pMsg, (char*)msg);
	MsgSetRawMsg(pMsg, (char*)msg);
	MsgSetMSG(pMsg, (char*)msg);
	MsgSetRcvFrom(pMsg, (char*)glbl.GetLocalHostName());
	MsgSetRcvFromIP(pMsg, (uchar*)"127.0.0.1");
	MsgSetHOSTNAME(pMsg, (char*)glbl.GetLocalHostName());
	MsgSetTAG(pMsg, (char*)pszTag);
	pMsg->iFacility = LOG_FAC(iFacility);
	pMsg->iSeverity = LOG_PRI(iSeverity);
	pMsg->bParseHOSTNAME = 0;
	datetime.getCurrTime(&(pMsg->tTIMESTAMP)); /* use the current time! */
	CHKiRet(submitMsg(pMsg));

finalize_it:
	RETiRet;
}

/* parse the PRI from a kernel message. At least BSD seems to have
 * non-kernel messages inside the kernel log...
 * Expected format: "<pri>". piPri is only valid if the function 
 * successfully returns. If there was a proper pri ppSz is advanced to the
 * position right after ">".
 * rgerhards, 2008-04-14
 */
static rsRetVal
parsePRI(uchar **ppSz, int *piPri)
{
	DEFiRet;
	int i;
	uchar *pSz;

	assert(ppSz != NULL);
	pSz = *ppSz;
	assert(pSz != NULL);
	assert(piPri != NULL);

	if(*pSz != '<' || !isdigit(*(pSz+1)))
		ABORT_FINALIZE(RS_RET_INVALID_PRI);

	++pSz;
	i = 0;
	while(isdigit(*pSz)) {
		i = i * 10 + *pSz++ - '0';
	}

	if(*pSz != '>')
		ABORT_FINALIZE(RS_RET_INVALID_PRI);

	/* OK, we have a valid PRI */
	*piPri = i;

finalize_it:
	RETiRet;
}


/* log an imklog-internal message
 * rgerhards, 2008-04-14
 */
rsRetVal imklogLogIntMsg(int priority, char *fmt, ...)
{
	DEFiRet;
	va_list ap;
	uchar msgBuf[2048]; /* we use the same size as sysklogd to remain compatible */
	uchar *pLogMsg;

	va_start(ap, fmt);
	vsnprintf((char*)msgBuf, sizeof(msgBuf) / sizeof(char), fmt, ap);
	pLogMsg = msgBuf;
	va_end(ap);

	iRet = enqMsg((uchar*)pLogMsg, (uchar*) ((iFacilIntMsg == LOG_KERN) ? "kernel:" : "imklog:"),
		      iFacilIntMsg, LOG_PRI(priority));

	RETiRet;
}


/* log a kernel message 
 * rgerhards, 2008-04-14
 */
rsRetVal Syslog(int priority, uchar *pMsg)
{
	DEFiRet;
	rsRetVal localRet;

	/* Output using syslog */
	localRet = parsePRI(&pMsg, &priority);
	if(localRet != RS_RET_INVALID_PRI && localRet != RS_RET_OK)
		FINALIZE;
	/* if we don't get the pri, we use whatever we were supplied */

	/* ignore non-kernel messages if not permitted */
	if(bPermitNonKernel == 0 && LOG_FAC(priority) != LOG_KERN)
		FINALIZE; /* silently ignore */

	iRet = enqMsg((uchar*)pMsg, (uchar*) "kernel:", LOG_FAC(priority), LOG_PRI(priority));

finalize_it:
	RETiRet;
}


BEGINrunInput
CODESTARTrunInput
	/* this is an endless loop - it is terminated when the thread is
	 * signalled to do so. This, however, is handled by the framework,
	 * right into the sleep below.
	 */
	while(!pThrd->bShallStop) {
		/* klogLogKMsg() waits for the next kernel message, obtains it
                 * and then submits it to the rsyslog main queue.
	   	 * rgerhards, 2008-04-09
	   	 */
                CHKiRet(klogLogKMsg());
	}
finalize_it:
ENDrunInput


BEGINwillRun
CODESTARTwillRun
        iRet = klogWillRun();
ENDwillRun


BEGINafterRun
CODESTARTafterRun
        iRet = klogAfterRun();
ENDafterRun


BEGINmodExit
CODESTARTmodExit
	/* release objects we used */
	objRelease(glbl, CORE_COMPONENT);
	objRelease(datetime, CORE_COMPONENT);
ENDmodExit


BEGINqueryEtryPt
CODESTARTqueryEtryPt
CODEqueryEtryPt_STD_IMOD_QUERIES
ENDqueryEtryPt

static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal)
{
	dbgPrintSymbols = 0;
	symbols_twice = 0;
	use_syscall = 0;
	symfile = NULL;
	symbol_lookup = 0;
	bPermitNonKernel = 0;
	iFacilIntMsg = klogFacilIntMsg();
	return RS_RET_OK;
}

BEGINmodInit()
CODESTARTmodInit
	*ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
CODEmodInit_QueryRegCFSLineHdlr
	CHKiRet(objUse(datetime, CORE_COMPONENT));
	CHKiRet(objUse(glbl, CORE_COMPONENT));

	iFacilIntMsg = klogFacilIntMsg();

	CHKiRet(omsdRegCFSLineHdlr((uchar *)"debugprintkernelsymbols", 0, eCmdHdlrBinary, NULL, &dbgPrintSymbols, STD_LOADABLE_MODULE_ID));
	CHKiRet(omsdRegCFSLineHdlr((uchar *)"klogsymbollookup", 0, eCmdHdlrBinary, NULL, &symbol_lookup, STD_LOADABLE_MODULE_ID));
	CHKiRet(omsdRegCFSLineHdlr((uchar *)"klogsymbolstwice", 0, eCmdHdlrBinary, NULL, &symbols_twice, STD_LOADABLE_MODULE_ID));
	CHKiRet(omsdRegCFSLineHdlr((uchar *)"klogusesyscallinterface", 0, eCmdHdlrBinary, NULL, &use_syscall, STD_LOADABLE_MODULE_ID));
	CHKiRet(omsdRegCFSLineHdlr((uchar *)"klogpermitnonkernelfacility", 0, eCmdHdlrBinary, NULL, &bPermitNonKernel, STD_LOADABLE_MODULE_ID));
	CHKiRet(omsdRegCFSLineHdlr((uchar *)"kloginternalmsgfacility", 0, eCmdHdlrFacility, NULL, &iFacilIntMsg, STD_LOADABLE_MODULE_ID));
	CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
ENDmodInit
/* vim:set ai:
 */