osmo-gsm-tester: Proper object-oriented structure to handle different objects
We should start using class inheritance and similar techniques to ease code maintenance for existing objects and development of new ones.
For instance, we currently have NITB or BSC+MSC, and we have to use the two differently.
We should have a Bsc abstract base class, and the same with an Msc class, which defines the APIs to implement by subclasses and provide generic helpers needed for all of them (such as bts_add()).
Then, for next generation binaries we create a OsmoBsc subclass and an OsmoMsc subclass which implements the methods of the parent abstract class. We can even support different versions of them by creating different sublcasses if needed. For NITB generation binaries, we can have an OsmoNITB class which inherits from both OsmoBsc and OsmoMsc and implements methods for both. This way we can use polymorphism and only care about the APIs defined in the abstract class when using them.
For BTSes, the same: An abstract super class called BTS, then we can have: OsmoBTSsysmo, OsmoBTStrxEttus, OsmoBTStrxSysmoCell5000, etc.
I agree to remove code duplication, but I would like to emphasize that the aim is not polymorphism per se. I have for a long time used class inheritance quite heavily, but have realized that it often creates more confusion and problems than it solves. So if having a base class indeed makes it easier to un-duplicate the code, then let's use that. But in Python we have near total freedom, and we should also consider other methods of sharing code, choosing the simpler way as we go.
Also let me note here that we are most probably not going to test the OsmoNITB for a long time, so time invested in polishing the code to have both NITB and MSC+BSC in clean non-duplicating code is most probably wasted. See also #2270
For different BTSes, this ticket remains fully valid. At first, while the implementations were in high flux, I decided to write the code by duplicating. A reasonable amount of code duplication (if it helps to show what is really happening) is also acceptable, but as the code stabilizes we may now identify common parts and unify.