source: nscp/scripts/python/test_nsca.py @ bd1e5e5

0.4.00.4.10.4.2
Last change on this file since bd1e5e5 was bd1e5e5, checked in by Michael Medin <michael@…>, 16 months ago

ARGH!!! included the script this time :)

  • Property mode set to 100644
File size: 9.7 KB
Line 
1from NSCP import Settings, Registry, Core, log, status, log_error, sleep
2from test_helper import BasicTest, TestResult, Callable, setup_singleton, install_testcases, init_testcases, shutdown_testcases
3import plugin_pb2
4from types import *
5import socket
6import uuid
7import unicodedata
8#import _thread
9#sync = _thread.allocate_lock()
10
11import threading
12sync = threading.RLock()
13
14core = Core.get()
15
16def isOpen(ip, port):
17        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
18        try:
19                s.connect((ip, int(port)))
20                s.shutdown(2)
21                return True
22        except:
23                return False
24
25class NSCAMessage:
26        uuid = None
27        source = None
28        command = None
29        status = None
30        message = None
31        perfdata = None
32        got_response = False
33        got_simple_response = False
34
35        def __init__(self, command):
36                if type(command) == 'unicode':
37                        try:
38                                self.uuid = command.decode('ascii', 'replace')
39                        except UnicodeDecodeError:
40                                self.uuid = command
41                else:
42                        self.uuid = command
43                #self.uuid = unicodedata.normalize('NFKD', command).encode('ascii','ignore')
44                self.command = command
45                self.source = None
46                self.status = None
47                self.message = None
48                self.perfdata = None
49                self.got_response = False
50                self.got_simple_response = False
51               
52               
53        def copy_changed_attributes(self, other):
54                if other.source:
55                        self.source = other.source
56                if other.command:
57                        self.command = other.command
58                if other.status:
59                        self.status = other.status
60                if other.message:
61                        self.message = other.message
62                if other.perfdata:
63                        self.perfdata = other.perfdata
64                if other.got_simple_response:
65                        self.got_simple_response = True
66       
67        def __str__(self):
68                return 'Message: %s (%s, %s, %s)'%(self.uuid, self.source, self.command, self.status)
69
70class NSCAServerTest(BasicTest):
71        instance = None
72        key = ''
73        reg = None
74        _responses = {}
75       
76        def has_response(self, id):
77                with sync:
78                        return id in self._responses
79       
80        def get_response(self, id):
81                with sync:
82                        if id in self._responses:
83                                return self._responses[id]
84                        msg = NSCAMessage(id)
85                        self._responses[id] = msg
86                        return msg
87
88        def set_response(self, msg):
89                with sync:
90                        if msg.uuid in self._responses:
91                                log('Updated: %s'%msg.uuid)
92                        self._responses[msg.uuid].copy_changed_attributes(msg)
93                        else:
94                                log('Added: %s'%msg.uuid)
95                                self._responses[msg.uuid] = msg
96                       
97
98        def del_response(self, id):
99                with sync:
100                        del self._responses[id]
101                       
102       
103        def desc(self):
104                return 'Testcase for NSCA protocol'
105
106        def title(self):
107                return 'NSCA Server test'
108
109        def setup(self, plugin_id, prefix):
110                self.key = '_%stest_command'%prefix
111                self.reg = Registry.get(plugin_id)
112                self.reg.simple_subscription('nsca_test_inbox', NSCAServerTest.simple_inbox_handler)
113                self.reg.subscription('nsca_test_inbox', NSCAServerTest.inbox_handler)
114
115        def simple_inbox_handler(channel, source, command, code, message, perf):
116                instance = NSCAServerTest.getInstance()
117                return instance.simple_inbox_handler_wrapped(channel, source, command, code, message, perf)
118        simple_inbox_handler = Callable(simple_inbox_handler)
119
120        def inbox_handler(channel, request):
121                instance = NSCAServerTest.getInstance()
122                return instance.inbox_handler_wrapped(channel, request)
123        inbox_handler = Callable(inbox_handler)
124       
125        def simple_inbox_handler_wrapped(self, channel, source, command, status, message, perf):
126                log('Got simple message %s on %s'%(command, channel))
127                msg = NSCAMessage(command)
128                msg.source = source
129                msg.status = status
130                msg.message = message
131                msg.perfdata = perf
132                msg.got_simple_response = True
133                self.set_response(msg)
134                return True
135
136        def inbox_handler_wrapped(self, channel, request):
137                message = plugin_pb2.SubmitRequestMessage()
138                message.ParseFromString(request)
139                command = message.payload[0].command
140                log('Got message %s on %s'%(command, channel))
141               
142                msg = NSCAMessage(command)
143                msg.got_response = True
144                self.set_response(msg)
145                return None
146               
147        def teardown(self):
148                None
149               
150        def wait_and_validate(self, uuid, result, msg, perf, tag):
151                found = False
152                for i in range(0,10):
153                        if self.has_response(uuid):
154                                rmsg = self.get_response(uuid)
155                                if not rmsg.got_simple_response or not rmsg.got_response:
156                                        for j in range(0,3):
157                                                rmsg = self.get_response(uuid)
158                                                if rmsg.got_simple_response and rmsg.got_response:
159                                                        log('Got delayed response %s'%uuid)
160                                else:
161                                                        log('Waiting for delayed response %s (%d/10)'%(uuid, j+1))
162                                       
163                                result.add_message(rmsg.got_response, 'Testing to recieve message using %s'%tag)
164                                        result.add_message(rmsg.got_simple_response, 'Testing to recieve simple message using %s'%tag)
165                                result.assert_equals(rmsg.command, uuid, 'Verify that command is sent through using %s'%tag)
166                                result.assert_contains(rmsg.message, msg, 'Verify that message is sent through using %s'%tag)
167                               
168                                #result.assert_equals(rmsg.last_source, source, 'Verify that source is sent through')
169                                #result.assert_equals(rmsg.perfdata, perf, 'Verify that performance data is sent through using %s'%tag)
170                                self.del_response(uuid)
171                                return True
172                        else:
173                                log('Waiting for %s (%d/10)'%(uuid, i+1))
174                                sleep(1)
175                result.add_message(False, 'Failed to recieve message %s using %s'%(uuid, tag))
176                return False
177       
178               
179        def submit_payload(self, encryption, source, status, msg, perf, tag):
180                message = plugin_pb2.SubmitRequestMessage()
181               
182                message.header.version = plugin_pb2.Common.VERSION_1
183                message.header.recipient_id = "test_rp"
184                message.channel = 'nsca_test_outbox'
185                host = message.header.hosts.add()
186                host.address = "127.0.0.1:15667"
187                host.id = "test_rp"
188                enc = host.metadata.add()
189                enc.key = "encryption"
190                enc.value = encryption
191                enc = host.metadata.add()
192                enc.key = "password"
193                enc.value = 'pwd-%s'%encryption
194
195                uid = str(uuid.uuid4())
196                payload = message.payload.add()
197                payload.result = status
198                payload.command = uid
199                payload.message = '%s - %s'%(uid, msg)
200                payload.source = source
201                (result_code, err) = core.submit('nsca_test_outbox', message.SerializeToString())
202
203                result = TestResult('Testing payload submission (via API): %s'%tag)
204                result.add_message(len(err) == 0, 'Testing to send message using %s/sbp'%tag, err)
205                self.wait_and_validate(uid, result, msg, perf, '%s/spb'%tag)
206                return result
207               
208        def submit_via_exec(self, encryption, source, status, msg, perf, tag):
209                uid = str(uuid.uuid4())
210       
211                args = [
212                        #'--exec', 'submit',
213                        '--alias', uid,
214                        '--result', '%d'%status,
215                        '--message', '%s - %s'%(uid, msg),
216                        '--encryption', encryption,
217                        '--password', 'pwd-%s'%encryption,
218                        '--host', '127.0.0.1:15667'
219                        ]
220                (result_code, result_message) = core.simple_exec('any', 'nsca_submit', args)
221                result = TestResult('Testing payload submission (via command line exec): %s'%tag)
222               
223                result.add_message(result_code == 0, 'Testing to send message using %s/exec:1'%tag)
224                result.add_message(len(result_message) == 1, 'Testing to send message using %s/exec:2'%tag, len(result_message))
225                result.add_message(len(result_message[0]) == 0, 'Testing to send message using %s/exec:3'%tag, result_message[0])
226                self.wait_and_validate(uid, result, msg, perf, '%s/exec'%tag)
227                return result
228
229        def test_one_crypto_full(self, encryption, state, key):
230                result = TestResult('Testing %s/%s'%(encryption, key))
231                result.add(self.submit_payload(encryption, '%ssrc%s'%(key, key), state, '%smsg%s'%(key, key), '', '%s/%s'%(state, encryption)))
232                result.add(self.submit_via_exec(encryption, '%ssrc%s'%(key, key), state, '%smsg%s'%(key, key), '', '%s/%s'%(state, encryption)))
233                return result
234
235        def test_one_crypto(self, crypto):
236                conf = Settings.get()
237                conf.set_string('/settings/NSCA/test_nsca_server', 'encryption', '%s'%crypto)
238                conf.set_string('/settings/NSCA/test_nsca_server', 'password', 'pwd-%s'%crypto)
239                core.reload('test_nsca_server')
240                result = TestResult('Testing encryption algorith: %s'%crypto)
241                result.add_message(isOpen('localhost', 15667), 'Checking that port is open')
242                result.add(self.test_one_crypto_full(crypto, status.UNKNOWN, 'unknown'))
243                result.add(self.test_one_crypto_full(crypto, status.OK, 'ok'))
244                result.add(self.test_one_crypto_full(crypto, status.WARNING, 'warn'))
245                result.add(self.test_one_crypto_full(crypto, status.CRITICAL, 'crit'))
246                return result
247
248        def run_test(self):
249                result = TestResult()
250                cryptos = ["none", "xor", "des", "3des", "cast128", "xtea", "blowfish", "twofish", "rc2", "aes", "aes256", "aes192", "aes128", "serpent", "gost", "3way"]
251                for c in cryptos:
252                        result.add_message(True, 'Testing crypto: %s'%c)
253                        result.add(self.test_one_crypto(c))
254               
255                return result
256               
257        def install(self, arguments):
258                conf = Settings.get()
259                conf.set_string('/modules', 'test_nsca_server', 'NSCAServer')
260                conf.set_string('/modules', 'test_nsca_client', 'NSCAClient')
261                conf.set_string('/modules', 'pytest', 'PythonScript')
262
263                conf.set_string('/settings/pytest/scripts', 'test_nsca', 'test_nsca.py')
264               
265                conf.set_string('/settings/NSCA/test_nsca_server', 'port', '15667')
266                conf.set_string('/settings/NSCA/test_nsca_server', 'inbox', 'nsca_test_inbox')
267                conf.set_string('/settings/NSCA/test_nsca_server', 'encryption', '1')
268
269                conf.set_string('/settings/NSCA/test_nsca_client/targets', 'nsca_test_local', 'nsca://127.0.0.1:15667')
270                conf.set_string('/settings/NSCA/test_nsca_client', 'channel', 'nsca_test_outbox')
271               
272                conf.save()
273
274        def uninstall(self):
275                None
276
277        def help(self):
278                None
279
280        def init(self, plugin_id):
281                None
282
283        def shutdown(self):
284                None
285               
286        def require_boot(self):
287                return True
288               
289
290setup_singleton(NSCAServerTest)
291
292all_tests = [NSCAServerTest]
293
294def __main__():
295        install_testcases(all_tests)
296       
297def init(plugin_id, plugin_alias, script_alias):
298        init_testcases(plugin_id, plugin_alias, script_alias, all_tests)
299
300def shutdown():
301        shutdown_testcases()
Note: See TracBrowser for help on using the repository browser.