1#
2# Copyright (c) ZeroC, Inc. All rights reserved.
3#
4
5import sys, os
6from Util import *
7from IceBoxUtil import *
8from Glacier2Util import *
9from IcePatch2Util import *
10
11class IceGridProcess:
12
13    def __init__(self, replica):
14        self.replica = replica
15
16    def getProps(self, current):
17        props = self.getParentProps(current)
18        testcase = current.testcase
19        while testcase and not isinstance(testcase, IceGridTestCase): testcase = testcase.parent
20        if self.replica is None:
21            props["Ice.Default.Locator"] = testcase.getMasterLocator(current)
22        else:
23            for r in testcase.icegridregistry:
24                # Match either the IceGridRegistrySlave object or the slave replica number
25                if self.replica in [r, r.name]:
26                    props["Ice.Default.Locator"] = r.getLocator(current)
27                    break
28        return props
29
30class IceGridServer(IceGridProcess, Server):
31
32    def __init__(self, replica=None, *args, **kargs):
33        Server.__init__(self, *args, **kargs)
34        IceGridProcess.__init__(self, replica)
35
36    getParentProps = Server.getProps # Used by IceGridProcess to get the server properties
37
38class IceGridClient(IceGridProcess, Client):
39
40    def __init__(self, replica=None, *args, **kargs):
41        Client.__init__(self, *args, **kargs)
42        IceGridProcess.__init__(self, replica)
43
44    getParentProps = Client.getProps # Used by IceGridProcess to get the client properties
45
46class IceGridAdmin(ProcessFromBinDir, ProcessIsReleaseOnly, IceGridClient):
47
48    def __init__(self, replica=None, username="admin1", password="test1", *args, **kargs):
49        IceGridClient.__init__(self, replica=replica, exe="icegridadmin", mapping=Mapping.getByName("cpp"),
50                               *args, **kargs)
51        self.username = username
52        self.password = password
53
54    def getProps(self, current):
55        props = IceGridClient.getProps(self, current)
56        props["IceGridAdmin.Username"] = self.username
57        props["IceGridAdmin.Password"] = self.password
58        return props
59
60class IceGridNode(ProcessFromBinDir, Server):
61
62    def __init__(self, name="localnode", *args, **kargs):
63
64        Server.__init__(self, "icegridnode", mapping=Mapping.getByName("cpp"), desc="IceGrid node " + name,
65                        ready="node", *args, **kargs)
66        self.name = name
67
68    def setup(self, current):
69        # Create the database directory
70        self.dbdir = os.path.join(current.testsuite.getPath(), "node-{0}".format(self.name))
71        if os.path.exists(self.dbdir):
72            shutil.rmtree(self.dbdir)
73        os.mkdir(self.dbdir)
74
75    def teardown(self, current, success):
76        Server.teardown(self, current, success)
77        # Remove the database directory tree
78        try:
79            shutil.rmtree(self.dbdir)
80        except:
81            pass
82
83    def getProps(self, current):
84        props = {
85            'IceGrid.InstanceName' : 'TestIceGrid',
86            'IceGrid.Node.Endpoints' : 'default',
87            'IceGrid.Node.WaitTime' : 240,
88            'Ice.ProgramName' : 'icegridnode',
89            'IceGrid.Node.Trace.Replica' : 0,
90            'IceGrid.Node.Trace.Activator' : 0,
91            'IceGrid.Node.Trace.Adapter' : 0,
92            'IceGrid.Node.Trace.Server' : 0,
93            'IceGrid.Node.ThreadPool.SizeWarn' : 0,
94            'IceGrid.Node.PrintServersReady' : 'node',
95            'IceGrid.Node.Name' : self.name,
96            'IceGrid.Node.Data' : '{testdir}/node-{process.name}',
97            'IceGrid.Node.PropertiesOverride' : self.getPropertiesOverride(current),
98            'Ice.Default.Locator' : current.testcase.getLocator(current),
99            'Ice.NullHandleAbort'  : 1,
100        }
101        return props
102
103    def getEnv(self, current):
104        # Add environment variable for servers based on the test case mapping.
105        return Server().getEffectiveEnv(current)
106
107    def getPropertiesOverride(self, current):
108        # Add properties for servers based on the test case mapping.
109        props = Server().getEffectiveProps(current, {})
110        return ' '.join(["{0}={1}".format(k, val(v)) for k, v in props.items()])
111
112    def shutdown(self, current):
113        current.testcase.runadmin(current, "node shutdown {0}".format(self.name))
114
115class IceGridRegistry(ProcessFromBinDir, Server):
116
117    def __init__(self, name, portnum=20, readyCount=5, *args, **kargs):
118        Server.__init__(self, "icegridregistry", mapping=Mapping.getByName("cpp"), desc="IceGrid registry " + name,
119                        readyCount=readyCount, *args, **kargs)
120        self.portnum = portnum
121        self.name = name
122
123    def setup(self, current):
124        # Create the database directory
125        self.dbdir = os.path.join(current.testsuite.getPath(), "registry-{0}".format(self.name))
126        if os.path.exists(self.dbdir):
127            shutil.rmtree(self.dbdir)
128        os.mkdir(self.dbdir)
129
130    def teardown(self, current, success):
131        Server.teardown(self, current, success)
132        # Remove the database directory tree
133        try:
134            shutil.rmtree(self.dbdir)
135        except:
136            pass
137
138    def getProps(self, current):
139        props = {
140            'IceGrid.InstanceName' : 'TestIceGrid',
141            'IceGrid.Registry.PermissionsVerifier' : 'TestIceGrid/NullPermissionsVerifier',
142            'IceGrid.Registry.AdminPermissionsVerifier' : 'TestIceGrid/NullPermissionsVerifier',
143            'IceGrid.Registry.SSLPermissionsVerifier' : 'TestIceGrid/NullSSLPermissionsVerifier',
144            'IceGrid.Registry.AdminSSLPermissionsVerifier' : 'TestIceGrid/NullSSLPermissionsVerifier',
145            'IceGrid.Registry.Server.Endpoints' : 'default',
146            'IceGrid.Registry.Internal.Endpoints' : 'default',
147            'IceGrid.Registry.Client.Endpoints' : self.getEndpoints(current),
148            'IceGrid.Registry.Discovery.Port' : current.driver.getTestPort(99),
149            'IceGrid.Registry.SessionManager.Endpoints' : 'default',
150            'IceGrid.Registry.AdminSessionManager.Endpoints' : 'default',
151            'IceGrid.Registry.SessionTimeout' : 60,
152            'IceGrid.Registry.ReplicaName' : self.name,
153            'Ice.ProgramName' : self.name,
154            'Ice.PrintAdapterReady' : 1,
155            'Ice.Warn.Connections' : 0,
156            'Ice.ThreadPool.Client.SizeWarn' : 0,
157            'IceGrid.Registry.LMDB.MapSize' : 1,
158            'IceGrid.Registry.LMDB.Path' : '{testdir}/registry-{process.name}',
159            'IceGrid.Registry.Client.ThreadPool.SizeWarn' : 0,
160            'IceGrid.Registry.DefaultTemplates' :
161                '"' + os.path.abspath(os.path.join(toplevel, "cpp", "config", "templates.xml")) + '"'
162        }
163        if not isinstance(platform, Linux):
164            props["IceGrid.Registry.Discovery.Interface"] = "::1" if current.config.ipv6 else "127.0.0.1"
165        return props
166
167    def getEndpoints(self, current):
168        return current.getTestEndpoint(self.portnum)
169
170    def getLocator(self, current):
171        return "TestIceGrid/Locator:{0}".format(self.getEndpoints(current))
172
173    def shutdown(self, current):
174        current.testcase.runadmin(current, "registry shutdown {0}".format(self.name), replica=self.name)
175
176class IceGridRegistryMaster(IceGridRegistry):
177
178    def __init__(self, portnum=20, *args, **kargs):
179        IceGridRegistry.__init__(self, "Master", portnum, *args, **kargs)
180
181class IceGridRegistrySlave(IceGridRegistry):
182
183    def __init__(self, replica=1, portnum=None, *args, **kargs):
184        IceGridRegistry.__init__(self, "Slave{0}".format(replica), (20 + replica) if portnum is None else portnum,
185                                 *args, **kargs)
186
187    def getProps(self, current):
188        props = IceGridRegistry.getProps(self, current)
189        props["Ice.Default.Locator"] = current.testcase.getMasterLocator(current)
190        return props
191
192class IceGridTestCase(TestCase):
193
194    def __init__(self, name="IceGrid", icegridregistry=None, icegridnode=None, application="application.xml",
195                 variables={}, targets=[], exevars={}, *args, **kargs):
196        TestCase.__init__(self, name, *args, **kargs)
197        if icegridnode:
198            self.icegridnode = icegridnode if isinstance(icegridnode, list) else [icegridnode]
199        else:
200            self.icegridnode = [IceGridNode()]
201
202        if icegridregistry:
203            self.icegridregistry = icegridregistry if isinstance(icegridregistry, list) else [icegridregistry]
204        else:
205            self.icegridregistry = [IceGridRegistryMaster(), IceGridRegistrySlave(1)]
206
207        self.application = application
208        self.variables = variables
209        self.targets = targets
210
211        # Variables for built executables
212        self.exevars = { "server.dir" : "server" }
213        self.exevars.update(exevars)
214
215    def init(self, mapping, testsuite):
216        TestCase.init(self, mapping, testsuite)
217
218        #
219        # Add IceGrid servers at the beginning of the server list, IceGrid needs to be
220        # started first!
221        #
222        self.servers = self.icegridregistry + self.icegridnode + self.servers
223
224    def setupClientSide(self, current):
225        if self.application:
226            javaHome = os.environ.get("JAVA_HOME", None)
227            serverProps = Server().getProps(current)
228            variables = {
229                "test.dir" : self.getPath(current),
230                "java.exe" : os.path.join(javaHome, "bin", "java") if javaHome else "java",
231                "icebox.exe" : IceBox().getCommandLine(current),
232                "icegridnode.exe" : IceGridNode().getCommandLine(current),
233                "glacier2router.exe" : Glacier2Router().getCommandLine(current),
234                "icepatch2server.exe" : IcePatch2Server().getCommandLine(current),
235                "icegridregistry.exe" : IceGridRegistryMaster().getCommandLine(current),
236                "properties-override" : self.icegridnode[0].getPropertiesOverride(current),
237            }
238
239            if platform.getDotNetExe():
240                variables["dotnet.exe"] = platform.getDotNetExe()
241
242            # Add variables that point to the directories containing the built executables
243            for (k, v) in self.exevars.items():
244                variables[k] = current.getBuildDir(v)
245
246            variables.update(self.variables)
247            varStr = " ".join(["{0}={1}".format(k, val(v)) for k,v in variables.items()])
248            targets = " ".join(self.targets)
249            application = self.application
250            if isinstance(self.mapping, CSharpMapping) and current.config.dotnetcore:
251                application = application.replace(".xml", ".netcoreapp.xml")
252            self.runadmin(current, "application add -n {0} {1} {2}".format(application, varStr, targets))
253
254    def teardownClientSide(self, current, success):
255        if self.application:
256            self.runadmin(current, "application remove Test")
257
258        for p in self.icegridnode + self.icegridregistry:
259            p.shutdown(current)
260
261    def getLocator(self, current):
262        endpoints = ":".join([s.getEndpoints(current) for s in self.servers if isinstance(s, IceGridRegistry)])
263        return "TestIceGrid/Locator:{0}".format(endpoints)
264
265    def getMasterLocator(self, current):
266        for s in self.servers:
267            if isinstance(s, IceGridRegistryMaster):
268                return "TestIceGrid/Locator:{0}".format(s.getEndpoints(current))
269
270    def runadmin(self, current, cmd, replica="Master", exitstatus=0, quiet=False):
271        admin = IceGridAdmin(args=["-r", replica, "-e", cmd], replica=replica, quiet=quiet)
272        admin.run(current, exitstatus=exitstatus)
273        return admin.getOutput(current)
274
275    def runWithDriver(self, current):
276        current.driver.runClientServerTestCase(current)
277
278    def getClientType(self):
279        return "client"
280