Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

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

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

# Copyright (C) 2011  Internet Systems Consortium. 

# 

# Permission to use, copy, modify, and distribute this software for any 

# purpose with or without fee is hereby granted, provided that the above 

# copyright notice and this permission notice appear in all copies. 

# 

# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM 

# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL 

# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL 

# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, 

# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING 

# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, 

# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 

# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 

 

# This tests it can be loaded, nothing more yet 

import isc.log 

import unittest 

import json 

import sys 

import bind10_config 

from isc.config.ccsession import path_search 

 

class LogDict(unittest.TestCase): 

    def setUp(self): 

        # We work on a test dictionary now. 

        isc.log.set_test_dictionary(True) 

    def tearDown(self): 

        # Return to the global dictionary 

        isc.log.set_test_dictionary(False) 

 

    def test_load_msgs(self): 

        # Try loading a message and see it's there, but nothing more 

        self.assertEqual(isc.log.create_message("ID", "Text"), "ID") 

        self.assertEqual(isc.log.get_message("ID"), "Text") 

        self.assertEqual(isc.log.get_message("no-ID"), None) 

 

class Manager(unittest.TestCase): 

    def tearDown(self): 

        isc.log.reset() 

 

    def test_init_debug(self): 

        # We try calling it now only, as we don't have any other functions 

        # to check the outcome by it. Once we add the logger class, we may 

        # check more. 

        isc.log.init("root", "DEBUG", 50, None) 

 

    def test_init_defaults(self): 

        # We try calling it now only, as we don't have any other functions 

        # to check the outcome by it. Once we add the logger class, we may 

        # check more. 

        isc.log.init("root") 

 

    def test_init_notfound(self): 

        # This should not throw, because the C++ one doesn't. Should we really 

        # ignore errors like missing file? 

        isc.log.init("root", "INFO", 0, "/no/such/file"); 

 

    def test_log_config_update(self): 

        log_spec = json.dumps(isc.config.module_spec_from_file(path_search('logging.spec', bind10_config.PLUGIN_PATHS)).get_full_spec()) 

 

        self.assertRaises(TypeError, isc.log.log_config_update) 

        self.assertRaises(TypeError, isc.log.log_config_update, 1) 

        self.assertRaises(TypeError, isc.log.log_config_update, 1, 1) 

        self.assertRaises(TypeError, isc.log.log_config_update, 1, 1, 1) 

 

        self.assertRaises(TypeError, isc.log.log_config_update, 1, log_spec) 

        self.assertRaises(TypeError, isc.log.log_config_update, [], log_spec) 

        self.assertRaises(TypeError, isc.log.log_config_update, "foo", log_spec) 

        self.assertRaises(TypeError, isc.log.log_config_update, "{ '", log_spec) 

 

        # empty should pass 

        isc.log.log_config_update("{}", log_spec) 

 

        # bad spec 

        self.assertRaises(TypeError, isc.log.log_config_update, "{}", json.dumps({"foo": "bar"})) 

 

        # Try a correct one 

        log_conf = json.dumps({"loggers": 

                                [{"name": "b10-xfrout", "output_options": 

                                    [{"output": "/tmp/bind10.log", 

                                       "destination": "file", 

                                       "flush": True}]}]}) 

        isc.log.log_config_update(log_conf, log_spec) 

 

class Logger(unittest.TestCase): 

    def tearDown(self): 

        isc.log.reset() 

 

    def setUp(self): 

        isc.log.init("root", "DEBUG", 50) 

        self.sevs = ['INFO', 'WARN', 'ERROR', 'FATAL'] 

        self.TEST_MSG = isc.log.create_message('TEST_MESSAGE', '%1') 

 

    # Checks defaults of the logger 

    def defaults(self, logger): 

        self.assertEqual(logger.get_effective_severity(), "DEBUG") 

        self.assertEqual(logger.get_effective_debug_level(), 50) 

 

    def test_default_severity(self): 

        logger = isc.log.Logger("child") 

        self.defaults(logger) 

 

    # Try changing the severities little bit 

    def test_severity(self): 

        logger = isc.log.Logger("child") 

        logger.set_severity('DEBUG', 25) 

        self.assertEqual(logger.get_effective_severity(), "DEBUG") 

        self.assertEqual(logger.get_effective_debug_level(), 25) 

        for sev in self.sevs: 

            logger.set_severity(sev) 

            self.assertEqual(logger.get_effective_severity(), sev) 

            self.assertEqual(logger.get_effective_debug_level(), 0) 

        # Return to default 

        logger.set_severity(None) 

        self.defaults(logger) 

 

    def test_enabled(self): 

        logger = isc.log.Logger("child") 

        self.sevs.insert(0, 'DEBUG') 

        methods = { 

            'DEBUG': logger.is_debug_enabled, 

            'INFO': logger.is_info_enabled, 

            'WARN': logger.is_warn_enabled, 

            'ERROR': logger.is_error_enabled, 

            'FATAL': logger.is_fatal_enabled 

        } 

        for sev in self.sevs: 

            logger.set_severity(sev) 

            enabled = False 

            for tested in self.sevs: 

                if tested == sev: 

                    enabled = True 

                self.assertEqual(methods[tested](), enabled) 

        logger.set_severity('DEBUG', 50) 

        self.assertTrue(logger.is_debug_enabled()) 

        self.assertTrue(logger.is_debug_enabled(0)) 

        self.assertTrue(logger.is_debug_enabled(50)) 

        self.assertFalse(logger.is_debug_enabled(99)) 

 

    def test_invalid_params(self): 

        """ 

           Tests invalid arguments for logging functions. The output is tested 

           in check_output.sh. 

        """ 

        logger = isc.log.Logger("child") 

        methods = [ 

            logger.info, 

            logger.warn, 

            logger.error, 

            logger.fatal 

        ] 

        for meth in methods: 

            # Not enough arguments 

            self.assertRaises(TypeError, meth) 

            # Bad type 

            self.assertRaises(TypeError, meth, 1) 

        # Too few arguments 

        self.assertRaises(TypeError, logger.debug, 42) 

        self.assertRaises(TypeError, logger.debug) 

        # Bad type 

        self.assertRaises(TypeError, logger.debug, "42", "hello") 

 

    def test_dbglevel_constants(self): 

        """ 

            Just check a constant to make sure it is defined and is the 

            correct value.  (The constant chosen has a non-zero value to 

            ensure that the code has both define the constant and set its 

            value correctly.) 

        """ 

        logger = isc.log.Logger("child") 

        self.assertEqual(logger.DBGLVL_COMMAND, 10) 

 

    def test_param_reference(self): 

        """ 

        Check whether passing a parameter to a logger causes a reference leak. 

        """ 

        class LogParam: 

            def __str__(self): 

                return 'LogParam' 

        logger = isc.log.Logger("child") 

        param = LogParam() 

        orig_msgrefcnt = sys.getrefcount(param) 

        orig_idrefcnt = sys.getrefcount(self.TEST_MSG) 

        logger.info(self.TEST_MSG, param); 

        self.assertEqual(sys.getrefcount(self.TEST_MSG), orig_idrefcnt) 

        self.assertEqual(sys.getrefcount(param), orig_msgrefcnt) 

 

        # intentionally pass an invalid type for debug level.  It will 

        # result in TypeError.  The passed object still shouldn't leak a 

        # reference. 

        self.assertRaises(TypeError, logger.debug, param, self.TEST_MSG, param) 

        self.assertEqual(sys.getrefcount(param), orig_msgrefcnt) 

 

    def test_bad_parameter(self): 

        # a log parameter cannot be converted to a string object. 

        class LogParam: 

            def __str__(self): 

                raise ValueError("LogParam can't be converted to string") 

        logger = isc.log.Logger("child") 

        self.assertRaises(ValueError, logger.info, self.TEST_MSG, LogParam()) 

 

exitif __name__ == '__main__': 

    unittest.main()