blob: 85e75541bab3e06ab91ec978cdb584fa5274c1a3 [file] [log] [blame]
Neels Hofmeyr56aa4782017-12-19 14:12:16 +01001#!/usr/bin/env python3
2#
3# (C) 2017 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
4# All rights reserved.
5#
6# Author: Neels Hofmeyr <nhofmeyr@sysmocom.de>
7#
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation, either version 3 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program. If not, see <http://www.gnu.org/licenses/>.
20
21'''
22Run CTRL commands or test transcripts against a given application. Commandline
23invocation exposes only direct command piping, the transcript verification code
24is exposed as commandline args by osmo_verify_transcript_ctrl.py.
25'''
26
27import re
28
29from .common import *
30from osmopy.osmo_ipa import Ctrl, IPA
31
32class InteractCtrl(Interact):
33 next_id = 1
34 keep_ids = True
35 re_command = re.compile('^(SET|GET) ([^ ]*) (.*)$')
36
37 class CtrlStep(Interact.StepBase):
38
39 @staticmethod
40 def is_next_step(line, interact_instance):
41 m = InteractCtrl.re_command.match(line)
42 if not m:
43 return None
44 next_step = InteractCtrl.CtrlStep()
45
46 set_get = m.group(1)
47 cmd_id = m.group(2)
48 var_val = m.group(3)
49 if not interact_instance.keep_ids:
50 cmd_id = interact_instance.next_id
51 interact_instance.next_id += 1
52 next_step.command = '%s %s %s' % (set_get, cmd_id, var_val)
53
54 return next_step
55
56 def __init__(self, port, host, verbose=False, update=False, keep_ids=True):
57 if not update:
58 keep_ids = True
59 self.keep_ids = keep_ids
60 super().__init__(InteractCtrl.CtrlStep, port=port, host=host, verbose=verbose, update=update)
61
62 def connect(self):
63 self.next_id = 1
64 super().connect()
65
66 def send(self, data):
67 data = Ctrl().add_header(data)
68 return self.socket.send(data) == len(data)
69
70 def receive(self):
71 responses = []
72 data = self.socket.recv(4096)
73 while (len(data)>0):
74 (response_with_header, data) = IPA().split_combined(data)
75 response = Ctrl().rem_header(response_with_header)
76 responses.append(response.decode('utf-8'))
77 return responses
78
79 def command(self, command):
80 assert self.send(command)
81 res = self.receive()
82 split_responses = []
83 for r in res:
84 split_responses.extend(r.splitlines())
85 sys.stdout.flush()
86 sys.stderr.flush()
87 return split_responses
88
89def main_interact_ctrl():
Neels Hofmeyrbe76f4d2017-12-19 13:46:57 +010090 '''
91Run CTRL commands against a given application by stdin/stdout piping.
92
93Optionally, this can launch and tear down the application with -r.
94
95For example, to start a session that allows typing CTRL commands on stdin:
96
97 osmo_interact_ctrl.py -p 4259 \\
98 -r 'osmo-hlr -c /etc/osmocom/osmo-hlr.cfg -l /tmp/hlr.db'
99
100Where 4259 is OsmoHLR's CTRL port number, see
101https://osmocom.org/projects/cellular-infrastructure/wiki/Port_Numbers
102
103If osmo-hlr is already running, this shortens to just
104
105 osmo_interact_ctrl.py -p 4259
106
107See also osmo_verify_transcript_vty.py, which allows verifying and updating
108complete CTRL session transcripts, in essence to write CTRL tests from a screen
109dump of a CTRL session.
110
111A VTY equivalent is osmo_interact_vty.py.
112'''
113 parser = common_parser(__doc__)
Neels Hofmeyr56aa4782017-12-19 14:12:16 +0100114 parser_add_run_args(parser)
115 args = parser.parse_args()
116
117 interact = InteractCtrl(args.port, args.host, verbose=False, update=False,
118 keep_ids=True)
119
120 main_run_commands(args.run_app_str, args.output_path, args.cmd_str,
121 args.cmd_files, interact)
122
123
124def main_verify_transcript_ctrl():
Neels Hofmeyrbe76f4d2017-12-19 13:46:57 +0100125 '''
126A CTRL transcript contains CTRL commands and their expected results.
127It looks like:
128
129"
130SET 1 var val
131SET_REPLY 1 var OK
132
133GET 2 var
134GET_REPLY 2 var val
135"
136
137Optionally, this can launch and tear down the application with -r.
138
139For example, if above transcript example is in file test.ctrl, you can verify
140that OsmoHLR still shows this behavior by:
141
142 osmo_interact_ctrl.py -p 4259 \\
143 -r 'osmo-hlr -c /etc/osmocom/osmo-hlr.cfg -l /tmp/hlr.db' \\
144 test.ctrl
145
146Where 4259 is OsmoHLR's CTRL port number, see
147https://osmocom.org/projects/cellular-infrastructure/wiki/Port_Numbers
148
149If osmo-hlr is already running, this shortens to just
150
151 osmo_interact_ctrl.py -p 4259 test.ctrl
152
153If osmo-hlr has changed its behavior, e.g. some reply changed, the transcript
154can be automatically updated, which overwrites the file, like:
155
156 osmo_interact_ctrl.py -p 4259 -u test.ctrl
157
158See also osmo_interact_ctrl.py, which allows piping CTRL commands to stdin.
159
160A VTY equivalent is osmo_verify_transcript_vty.py.
161'''
162 parser = common_parser(__doc__)
Neels Hofmeyr56aa4782017-12-19 14:12:16 +0100163 parser_add_verify_args(parser)
164 parser.add_argument('-i', '--keep-ids', dest='keep_ids', action='store_true',
165 help='With --update, default is to overwrite the command IDs'
166 ' so that they are consecutive numbers starting from 1.'
167 ' With --keep-ids, do not change these command IDs.')
168 args = parser.parse_args()
169
170 interact = InteractCtrl(args.port, args.host, args.verbose, args.update, args.keep_ids)
171
172 main_verify_transcripts(args.run_app_str, args.transcript_files, interact, args.verbose)
173
174# vim: tabstop=4 shiftwidth=4 expandtab nocin ai