runnertest.py 22.2 KB
Newer Older
1
# -*- coding: utf-8 -*-
Marco Mariani's avatar
Marco Mariani committed
2
# vim: set et sts=2:
Marco Mariani's avatar
Marco Mariani committed
3
# pylint: disable-msg=W0311,C0301,C0103,C0111,R0904
Marco Mariani's avatar
Marco Mariani committed
4

5 6 7 8 9 10 11 12
#############################################
# !!! Attention !!!
# You now have to comment the last line
# in __init__py, wich starts the functiun
# run() in order to start the tests,
# or it will NOT work
#############################################

13
import argparse
14
import ConfigParser
Marco Mariani's avatar
Marco Mariani committed
15
import datetime
Marco Mariani's avatar
Marco Mariani committed
16
import hashlib
17
import json
Marco Mariani's avatar
Marco Mariani committed
18 19
import os
import shutil
20
import time
Marco Mariani's avatar
Marco Mariani committed
21 22
import unittest

23 24
from slapos.runner.utils import (getProfilePath, getRcode,
                                 getSession, isInstanceRunning,
25
                                 isSoftwareRunning, startProxy,
26 27
                                 isSoftwareReleaseReady,
                                 runSlapgridUntilSuccess,
28
                                 getBuildAndRunParams, saveBuildAndRunParams)
29
from slapos.runner.process import killRunningProcess, isRunning
Marco Mariani's avatar
Marco Mariani committed
30
from slapos.runner import views
Alain Takoudjou's avatar
Alain Takoudjou committed
31
import slapos.slap
32
from slapos.htpasswd import  HtpasswdFile
Marco Mariani's avatar
Marco Mariani committed
33

Marco Mariani's avatar
Marco Mariani committed
34

Marco Mariani's avatar
Marco Mariani committed
35 36 37 38
#Helpers
def loadJson(response):
  return json.loads(response.data)

39 40

class Config:
Marco Mariani's avatar
Marco Mariani committed
41 42 43 44 45 46
  def __init__(self):
    self.runner_workdir = None
    self.software_root = None
    self.instance_root = None
    self.configuration_file_path = None

47 48 49 50
  def setConfig(self):
    """
    Set options given by parameters.
    """
51
    self.configuration_file_path = os.path.abspath(os.environ.get('RUNNER_CONFIG'))
52 53 54 55 56 57 58

    # Load configuration file
    configuration_parser = ConfigParser.SafeConfigParser()
    configuration_parser.read(self.configuration_file_path)
    # Merges the arguments and configuration

    for section in ("slaprunner", "slapos", "slapproxy", "slapformat",
59
                    "sshkeys_authority", "gitclient"):
60 61 62 63 64
      configuration_dict = dict(configuration_parser.items(section))
      for key in configuration_dict:
        if not getattr(self, key, None):
          setattr(self, key, configuration_dict[key])

Marco Mariani's avatar
Marco Mariani committed
65

66 67 68 69 70 71 72
class SlaprunnerTestCase(unittest.TestCase):

  def setUp(self):
    """Initialize slapos webrunner here"""
    views.app.config['TESTING'] = True
    self.users = ["slapuser", "slappwd", "slaprunner@nexedi.com", "SlapOS web runner"]
    self.updateUser = ["newslapuser", "newslappwd", "slaprunner@nexedi.com", "SlapOS web runner"]
73
    self.repo = 'http://git.erp5.org/repos/slapos.git'
Marco Mariani's avatar
Marco Mariani committed
74 75
    self.software = "workspace/slapos/software/"  # relative directory fo SR
    self.project = 'slapos'  # Default project name
Alain Takoudjou's avatar
Alain Takoudjou committed
76 77
    self.template = 'template.cfg'
    self.partitionPrefix = 'slappart'
78 79 80 81
    #create slaprunner configuration
    config = Config()
    config.setConfig()
    workdir = os.path.join(config.runner_workdir, 'project')
82
    software_link = os.path.join(config.runner_workdir, 'softwareLink')
83 84
    views.app.config.update(**config.__dict__)
    #update or create all runner base directory to test_dir
85

86 87
    if not os.path.exists(workdir):
      os.mkdir(workdir)
Alain Takoudjou's avatar
Alain Takoudjou committed
88 89
    if not os.path.exists(software_link):
      os.mkdir(software_link)
90 91 92
    views.app.config.update(
      software_log=config.software_root.rstrip('/') + '.log',
      instance_log=config.instance_root.rstrip('/') + '.log',
Marco Mariani's avatar
Marco Mariani committed
93
      workspace=workdir,
94
      software_link=software_link,
95 96 97
      instance_profile='instance.cfg',
      software_profile='software.cfg',
      SECRET_KEY="123456",
Marco Mariani's avatar
Marco Mariani committed
98
      PERMANENT_SESSION_LIFETIME=datetime.timedelta(days=31),
99
      auto_deploy = True,
100
      autorun = False,
101
      instance_monitoring_url = 'https://[' + config.ipv6_address + ']:9684',
102 103 104 105
    )
    self.app = views.app.test_client()
    self.app.config = views.app.config
    #Create password recover code
106 107 108
    parser = ConfigParser.ConfigParser()
    parser.read(self.app.config['knowledge0_cfg'])
    self.rcode = parser.get('public', 'recovery-code')
109 110
    #Create config.json
    json_file = os.path.join(views.app.config['etc_dir'], 'config.json')
111
    if not os.path.exists(json_file):
112 113 114 115 116 117 118
      params = {
        'run_instance' : True,
        'run_software' : True,
        'max_run_instance' : 3,
        'max_run_software' : 2
      }
      open(json_file, "w").write(json.dumps(params))
119 120 121 122 123

  def tearDown(self):
    """Remove all test data"""
    project = os.path.join(self.app.config['etc_dir'], '.project')
    users = os.path.join(self.app.config['etc_dir'], '.users')
Alain Takoudjou's avatar
Alain Takoudjou committed
124

125 126 127 128 129 130 131 132 133 134
    if os.path.exists(users):
      os.unlink(users)
    if os.path.exists(project):
      os.unlink(project)
    if os.path.exists(self.app.config['workspace']):
      shutil.rmtree(self.app.config['workspace'])
    if os.path.exists(self.app.config['software_root']):
      shutil.rmtree(self.app.config['software_root'])
    if os.path.exists(self.app.config['instance_root']):
      shutil.rmtree(self.app.config['instance_root'])
Alain Takoudjou's avatar
Alain Takoudjou committed
135 136 137
    if os.path.exists(self.app.config['software_link']):
      shutil.rmtree(self.app.config['software_link'])
    #Stop process
138 139 140
    killRunningProcess('slapproxy', recursive=True)
    killRunningProcess('slapgrid-cp', recursive=True)
    killRunningProcess('slapgrid-sr', recursive=True)
141 142

  def configAccount(self, username, password, email, name, rcode):
Marco Mariani's avatar
Marco Mariani committed
143
    """Helper for configAccount"""
Marco Mariani's avatar
Marco Mariani committed
144 145 146 147 148 149 150 151 152
    return self.app.post('/configAccount',
                         data=dict(
                           username=username,
                           password=password,
                           email=email,
                           name=name,
                           rcode=rcode
                         ),
                         follow_redirects=True)
153 154 155

  def setAccount(self):
    """Initialize user account and log user in"""
Marco Mariani's avatar
Marco Mariani committed
156
    response = loadJson(self.configAccount(self.users[0], self.users[1],
157 158 159 160 161
                  self.users[2], self.users[3], self.rcode))
    self.assertEqual(response['result'], "")

  def updateAccount(self, newaccount, rcode):
    """Helper for update user account data"""
Marco Mariani's avatar
Marco Mariani committed
162 163 164 165 166 167 168 169 170
    return self.app.post('/updateAccount',
                         data=dict(
                           username=newaccount[0],
                           password=newaccount[1],
                           email=newaccount[2],
                           name=newaccount[3],
                           rcode=rcode
                         ),
                         follow_redirects=True)
171

172 173 174
  def getCurrentSR(self):
   return getProfilePath(self.app.config['etc_dir'],
                              self.app.config['software_profile'])
175 176

  def proxyStatus(self, status=True, sleep_time=0):
177
    """Helper for testslapproxy status"""
178 179 180 181
    proxy = isRunning('slapproxy')
    if proxy != status and sleep_time != 0:
      time.sleep(sleep_time)
      proxy = isRunning('slapproxy')
182 183
    self.assertEqual(proxy, status)

Alain Takoudjou's avatar
Alain Takoudjou committed
184
  def setupProjectFolder(self, withSoftware=False):
Marco Mariani's avatar
Marco Mariani committed
185
    """Helper to create a project folder as for slapos.git"""
Alain Takoudjou's avatar
Alain Takoudjou committed
186 187 188 189 190 191 192 193 194 195 196
    base = os.path.join(self.app.config['workspace'], 'slapos')
    software = os.path.join(base, 'software')
    os.mkdir(base)
    os.mkdir(software)
    if withSoftware:
      testSoftware = os.path.join(software, 'slaprunner-test')
      sr = "[buildout]\n\n"
      sr += "parts = command\n\nunzip = true\nnetworkcache-section = networkcache\n\n"
      sr += "find-links += http://www.nexedi.org/static/packages/source/slapos.buildout/\n\n"
      sr += "[networkcache]\ndownload-cache-url = http://www.shacache.org/shacache"
      sr += "\ndownload-dir-url = http://www.shacache.org/shadir\n\n"
197
      sr += "[command]\nrecipe = zc.recipe.egg\neggs = plone.recipe.command\n  zc.buildout\n\n"
Alain Takoudjou's avatar
Alain Takoudjou committed
198 199 200 201 202
      os.mkdir(testSoftware)
      open(os.path.join(testSoftware, self.app.config['software_profile']),
                          'w').write(sr)

  def setupSoftwareFolder(self):
Marco Mariani's avatar
Marco Mariani committed
203
    """Helper to setup compiled software release dir"""
Alain Takoudjou's avatar
Alain Takoudjou committed
204 205
    self.setupProjectFolder(withSoftware=True)
    md5 = hashlib.md5(os.path.join(self.app.config['workspace'],
Marco Mariani's avatar
Marco Mariani committed
206 207 208
                                   "slapos/software/slaprunner-test",
                                   self.app.config['software_profile'])
                      ).hexdigest()
Alain Takoudjou's avatar
Alain Takoudjou committed
209 210 211 212 213
    base = os.path.join(self.app.config['software_root'], md5)
    template = os.path.join(base, self.template)
    content = "[buildout]\n"
    content += "parts = \n  create-file\n\n"
    content += "eggs-directory = %s\n" % os.path.join(base, 'eggs')
Marco Mariani's avatar
Marco Mariani committed
214
    content += "develop-eggs-directory = %s\n\n" % os.path.join(base, 'develop-eggs')
Alain Takoudjou's avatar
Alain Takoudjou committed
215 216 217 218 219 220 221
    content += "[create-file]\nrecipe = plone.recipe.command\n"
    content += "filename = ${buildout:directory}/etc\n"
    content += "command = mkdir ${:filename} && echo 'simple file' > ${:filename}/testfile\n"
    os.mkdir(self.app.config['software_root'])
    os.mkdir(base)
    open(template, "w").write(content)

222 223
  def stopSlapproxy(self):
    """Kill slapproxy process"""
224
    killRunningProcess('slapproxy', recursive=True)
Alain Takoudjou's avatar
Alain Takoudjou committed
225

226 227 228 229
  def test_configAccount(self):
    """For the first lauch of slaprunner user need do create first account"""
    result = self.configAccount(self.users[0], self.users[1], self.users[2],
                  self.users[3], self.rcode)
Marco Mariani's avatar
Marco Mariani committed
230
    response = loadJson(result)
231 232 233 234 235
    self.assertEqual(response['code'], 1)
    account = getSession(self.app.config)
    self.assertEqual(account, self.users)

  def test_updateAccount(self):
Marco Mariani's avatar
Marco Mariani committed
236
    """test Update accound, this needs the user to log in"""
237
    self.setAccount()
238 239
    htpasswd = os.path.join(self.app.config['etc_dir'], '.htpasswd')
    assert self.users[0] in open(htpasswd).read()
Marco Mariani's avatar
Marco Mariani committed
240
    response = loadJson(self.updateAccount(self.updateUser, self.rcode))
241
    self.assertEqual(response['code'], 1)
242 243 244
    encode = HtpasswdFile(htpasswd, False)
    encode.update(self.updateUser[0], self.updateUser[1])
    assert self.updateUser[0] in open(htpasswd).read()
245

246 247
  def test_startProxy(self):
    """Test slapproxy"""
Alain Takoudjou's avatar
Alain Takoudjou committed
248
    self.proxyStatus(False)
249 250 251
    startProxy(self.app.config)
    self.proxyStatus(True)
    self.stopSlapproxy()
252
    self.proxyStatus(False, sleep_time=1)
253 254 255 256 257

  def test_cloneProject(self):
    """Start scenario 1 for deploying SR: Clone a project from git repository"""
    self.setAccount()
    folder = 'workspace/' + self.project
Marco Mariani's avatar
Marco Mariani committed
258 259 260 261 262 263
    data = {
      'repo': self.repo,
      'user': 'Slaprunner test',
      'email': 'slaprunner@nexedi.com',
      'name': folder
    }
Marco Mariani's avatar
Marco Mariani committed
264
    response = loadJson(self.app.post('/cloneRepository', data=data,
265 266
                    follow_redirects=True))
    self.assertEqual(response['result'], "")
Marco Mariani's avatar
Marco Mariani committed
267
    # Get realpath of create project
268
    path_data = dict(file=folder)
Marco Mariani's avatar
Marco Mariani committed
269
    response = loadJson(self.app.post('/getPath', data=path_data,
270 271 272 273
                    follow_redirects=True))
    self.assertEqual(response['code'], 1)
    realFolder = response['result'].split('#')[0]
    #Check git configuration
274
    config = open(os.path.join(realFolder, '.git/config')).read()
275
    assert "slaprunner@nexedi.com" in config and "Slaprunner test" in config
Marco Mariani's avatar
Marco Mariani committed
276 277

    # Checkout to slaprunner branch, this supposes that branch slaprunner exit
Marco Mariani's avatar
Marco Mariani committed
278 279 280 281 282 283 284
    response = loadJson(self.app.post('/newBranch',
                                      data=dict(
                                        project=folder,
                                        create='0',
                                        name='slaprunner'
                                      ),
                                      follow_redirects=True))
285 286 287 288
    self.assertEqual(response['result'], "")

  def test_createSR(self):
    """Scenario 2: Create a new software release"""
Alain Takoudjou's avatar
Alain Takoudjou committed
289 290 291
    self.setAccount()
    #setup project directory
    self.setupProjectFolder()
292
    newSoftware = os.path.join(self.software, 'slaprunner-test')
Marco Mariani's avatar
Marco Mariani committed
293
    response = loadJson(self.app.post('/createSoftware',
Marco Mariani's avatar
Marco Mariani committed
294 295
                                      data=dict(folder=newSoftware),
                                      follow_redirects=True))
296 297 298 299 300 301 302
    self.assertEqual(response['result'], "")
    currentSR = self.getCurrentSR()
    assert newSoftware in currentSR

  def test_openSR(self):
    """Scenario 3: Open software release"""
    self.test_cloneProject()
Marco Mariani's avatar
Marco Mariani committed
303
    software = os.path.join(self.software, 'drupal')  # Drupal SR must exist in SR folder
Marco Mariani's avatar
Marco Mariani committed
304
    response = loadJson(self.app.post('/setCurrentProject',
Marco Mariani's avatar
Marco Mariani committed
305 306
                                      data=dict(path=software),
                                      follow_redirects=True))
307 308 309 310 311
    self.assertEqual(response['result'], "")
    currentSR = self.getCurrentSR()
    assert software in currentSR
    self.assertFalse(isInstanceRunning(self.app.config))
    self.assertFalse(isSoftwareRunning(self.app.config))
Marco Mariani's avatar
Marco Mariani committed
312 313 314

    # Slapproxy process is supposed to be started
    # newSoftware = os.path.join(self.software, 'slaprunner-test')
Alain Takoudjou's avatar
Alain Takoudjou committed
315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331
    self.proxyStatus(True)
    self.stopSlapproxy()

  def test_runSoftware(self):
    """Scenario 4: CReate empty SR and save software.cfg file
      then run slapgrid-sr
    """
    #Call config account
    #call create software Release
    self.test_createSR()
    newSoftware = self.getCurrentSR()
    softwareRelease = "[buildout]\n\nparts =\n  test-application\n"
    softwareRelease += "#Test download git web repos éè@: utf-8 caracters\n"
    softwareRelease += "[test-application]\nrecipe = hexagonit.recipe.download\n"
    softwareRelease += "url = http://git.erp5.org/gitweb/slapos.git\n"
    softwareRelease += "filename = slapos.git\n"
    softwareRelease += "download-only = true\n"
Alain Takoudjou's avatar
Alain Takoudjou committed
332
    response = loadJson(self.app.post('/saveFileContent',
Marco Mariani's avatar
Marco Mariani committed
333 334 335
                                      data=dict(file=newSoftware,
                                                content=softwareRelease),
                                      follow_redirects=True))
Alain Takoudjou's avatar
Alain Takoudjou committed
336
    self.assertEqual(response['result'], "")
Marco Mariani's avatar
Marco Mariani committed
337 338 339

    # Compile software and wait until slapgrid ends
    # this is supposed to use current SR
340 341 342
    while self.app.get('/isSRReady').data == "2":
      time.sleep(2)
    self.assertEqual(self.app.get('/isSRReady').data, "1")
Alain Takoudjou's avatar
Alain Takoudjou committed
343 344
    self.assertTrue(os.path.exists(self.app.config['software_root']))
    self.assertTrue(os.path.exists(self.app.config['software_log']))
345
    assert "test-application" in open(self.app.config['software_log']).read()
Alain Takoudjou's avatar
Alain Takoudjou committed
346 347 348 349 350 351 352 353 354 355 356 357 358 359
    sr_dir = os.listdir(self.app.config['software_root'])
    self.assertEqual(len(sr_dir), 1)
    createdFile = os.path.join(self.app.config['software_root'], sr_dir[0],
                              'parts', 'test-application', 'slapos.git')
    self.assertTrue(os.path.exists(createdFile))
    self.proxyStatus(True)
    self.stopSlapproxy()

  def test_updateInstanceParameter(self):
    """Scenarion 5: Update parameters of current sofware profile"""
    self.setAccount()
    self.setupSoftwareFolder()
    #Set current projet and run Slapgrid-cp
    software = os.path.join(self.software, 'slaprunner-test')
Alain Takoudjou's avatar
Alain Takoudjou committed
360
    response = loadJson(self.app.post('/setCurrentProject',
Marco Mariani's avatar
Marco Mariani committed
361 362
                                      data=dict(path=software),
                                      follow_redirects=True))
Alain Takoudjou's avatar
Alain Takoudjou committed
363 364 365 366 367 368 369 370
    self.assertEqual(response['result'], "")
    self.proxyStatus(True)
    #Send paramters for the instance
    parameterDict = dict(appname='slaprunnerTest', cacountry='France')
    parameterXml = '<?xml version="1.0" encoding="utf-8"?>\n<instance>'
    parameterXml += '<parameter id="appname">slaprunnerTest</parameter>\n'
    parameterXml += '<parameter id="cacountry">France</parameter>\n</instance>'
    software_type = 'production'
Alain Takoudjou's avatar
Alain Takoudjou committed
371
    response = loadJson(self.app.post('/saveParameterXml',
Marco Mariani's avatar
Marco Mariani committed
372 373 374
                                      data=dict(parameter=parameterXml,
                                                software_type=software_type),
                                      follow_redirects=True))
Alain Takoudjou's avatar
Alain Takoudjou committed
375 376 377 378 379 380 381 382
    self.assertEqual(response['result'], "")
    slap = slapos.slap.slap()
    slap.initializeConnection(self.app.config['master_url'])
    computer = slap.registerComputer(self.app.config['computer_id'])
    partitionList = computer.getComputerPartitionList()
    self.assertNotEqual(partitionList, [])
    #Assume that the requested partition is partition 0
    slapParameterDict = partitionList[0].getInstanceParameterDict()
Marco Mariani's avatar
Marco Mariani committed
383 384
    self.assertTrue('appname' in slapParameterDict)
    self.assertTrue('cacountry' in slapParameterDict)
Alain Takoudjou's avatar
Alain Takoudjou committed
385 386 387 388 389
    self.assertEqual(slapParameterDict['appname'], 'slaprunnerTest')
    self.assertEqual(slapParameterDict['cacountry'], 'France')
    self.assertEqual(slapParameterDict['slap_software_type'], 'production')

    #test getParameterXml for webrunner UI
Alain Takoudjou's avatar
Alain Takoudjou committed
390
    response = loadJson(self.app.get('/getParameterXml/xml'))
Alain Takoudjou's avatar
Alain Takoudjou committed
391
    self.assertEqual(parameterXml, response['result'])
Alain Takoudjou's avatar
Alain Takoudjou committed
392
    response = loadJson(self.app.get('/getParameterXml/dict'))
Alain Takoudjou's avatar
Alain Takoudjou committed
393 394 395 396 397 398
    self.assertEqual(parameterDict, response['result']['instance'])
    self.stopSlapproxy()

  def test_requestInstance(self):
    """Scenarion 6: request software instance"""
    self.test_updateInstanceParameter()
399
    self.proxyStatus(False, sleep_time=1)
Alain Takoudjou's avatar
Alain Takoudjou committed
400
    #run Software profile
Alain Takoudjou's avatar
Alain Takoudjou committed
401
    response = loadJson(self.app.post('/runSoftwareProfile',
Marco Mariani's avatar
Marco Mariani committed
402 403
                                      data=dict(),
                                      follow_redirects=True))
404 405 406
    while self.app.get('/isSRReady').data == "2":
      time.sleep(2)
    self.assertEqual(self.app.get('/isSRReady').data, "1")
Alain Takoudjou's avatar
Alain Takoudjou committed
407
    #run instance profile
Alain Takoudjou's avatar
Alain Takoudjou committed
408
    response = loadJson(self.app.post('/runInstanceProfile',
Marco Mariani's avatar
Marco Mariani committed
409 410
                                      data=dict(),
                                      follow_redirects=True))
Alain Takoudjou's avatar
Alain Takoudjou committed
411
    self.assertTrue(response['result'])
412 413
    # lets some time to the Instance to be deployed
    time.sleep(5)
Alain Takoudjou's avatar
Alain Takoudjou committed
414
    #Check that all partitions has been created
415
    assert "create-file" in open(self.app.config['instance_log']).read()
Alain Takoudjou's avatar
Alain Takoudjou committed
416 417 418 419 420 421 422 423 424 425 426 427
    instanceDir = os.listdir(self.app.config['instance_root'])
    for num in range(int(self.app.config['partition_amount'])):
      partition = os.path.join(self.app.config['instance_root'],
                    self.partitionPrefix + str(num))
      self.assertTrue(os.path.exists(partition))

    #Go to partition 0
    instancePath = os.path.join(self.app.config['instance_root'],
                         self.partitionPrefix + '0')
    createdFile = os.path.join(instancePath, 'etc', 'testfile')
    self.assertTrue(os.path.exists(createdFile))
    assert 'simple file' in open(createdFile).read()
428 429
    self.proxyStatus(True)
    self.stopSlapproxy()
430

431 432 433 434 435 436 437
  def test_safeAutoDeploy(self):
    """Scenario 7: isSRReady won't overwrite the existing
    Sofware Instance if it has been deployed yet"""
    # Test that SR won't be deployed with auto_deploy=False
    self.app.config['auto_deploy'] = False
    project = open(os.path.join(self.app.config['etc_dir'],
                  '.project'), "w")
438
    project.write(self.software + 'slaprunner-test')
439 440 441 442 443 444 445 446 447 448 449
    project.close()
    response = isSoftwareReleaseReady(self.app.config)
    self.assertEqual(response, "0")
    # Test if auto_deploy parameter starts the deployment of SR
    self.app.config['auto_deploy'] = True
    self.setupSoftwareFolder()
    response = isSoftwareReleaseReady(self.app.config)
    self.assertEqual(response, "2")
    # Test that the new call to isSoftwareReleaseReady
    # doesn't overwrite the previous installed one
    completed_path = os.path.join(self.app.config['runner_workdir'],
450
        'softwareLink', 'slaprunner-test', '.completed')
451 452 453 454 455 456 457
    completed_text = ".completed file: test"
    completed = open(completed_path, "w")
    completed.write(completed_text)
    completed.close()
    response = isSoftwareReleaseReady(self.app.config)
    self.assertEqual(response, "1")
    assert completed_text in open(completed_path).read()
Marco Mariani's avatar
Marco Mariani committed
458

459 460 461 462 463 464 465
  def test_maximumRunOfSlapgrid(self):
    """Scenario 8: runSlapgridUntilSucces run until a defined maximum of time
    slapgrid-sr and slapgrid-cp if it fails. It can also run only one or both
    of them if it is defined so
    We directly calls runSlapgridUntilSuccess, because we want
    to test the return code of the function"""
    # Installs a wrong buildout which will fail
466 467
    MAX_RUN_SOFTWARE = getBuildAndRunParams(self.app.config)['max_run_software']
    MAX_RUN_INSTANCE = getBuildAndRunParams(self.app.config)['max_run_instance']
468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510
    self.test_createSR()
    newSoftware = self.getCurrentSR()
    softwareRelease = "[buildout]\n\nparts =\n  test-application\n"
    softwareRelease += "#Test download git web repos éè@: utf-8 caracters\n"
    softwareRelease += "[test-application]\nrecipe = slapos.cookbook:mkdirectory\n"
    softwareRelease += "test = /root/test\n"
    response = loadJson(self.app.post('/saveFileContent',
                                      data=dict(file=newSoftware,
                                                content=softwareRelease),
                                      follow_redirects=True))
    response = runSlapgridUntilSuccess(self.app.config, 'software')
    self.assertEqual(response, MAX_RUN_SOFTWARE)
    # clean folders for other tests
    workdir = os.path.join(self.app.config['runner_workdir'], 'project')
    git_repo = os.path.join(workdir, 'slapos')
    if os.path.exists(git_repo):
      shutil.rmtree(git_repo)
    # Installs a software which deploys, but fails while instanciating
    # preparation
    base = os.path.join(self.app.config['workspace'], 'slapos')
    software = os.path.join(base, 'software')
    testSoftware = os.path.join(software, 'slaprunner-test')
    if not os.path.exists(testSoftware):
      os.makedirs(testSoftware)
    software_cfg = os.path.join(testSoftware, 'software.cfg')
    instance_cfg = os.path.join(testSoftware, 'instance.cfg')
    # software.cfg
    softwareRelease = "[buildout]\n\nparts =\n  failing-template\n\n"
    softwareRelease += "[failing-template]\nrecipe = hexagonit.recipe.download\n"
    softwareRelease += "url = %s\n" % (instance_cfg)
    softwareRelease += "destination = ${buildout:directory}\n"
    softwareRelease += "download-only = true\n"
    open(software_cfg, 'w+').write(softwareRelease)
    # instance.cfg
    content = "[buildout]\n\nparts =\n fail\n"
    content += "[fail]\nrecipe=plone.recipe.command\n"
    content += "command = exit 1"
    open(instance_cfg, 'w+').write(content)
    project = open(os.path.join(self.app.config['etc_dir'],
                  '.project'), "w")
    project.write(self.software + 'slaprunner-test')
    project.close()
    # Build and Run
511
    parameters = getBuildAndRunParams(self.app.config)
512
    parameters['run_instance'] = False
513
    saveBuildAndRunParams(self.app.config, parameters)
514 515 516
    response = runSlapgridUntilSuccess(self.app.config, 'software')
    self.assertEqual(response, 1)
    parameters['run_instance'] = True
517
    saveBuildAndRunParams(self.app.config, parameters)
518 519 520 521
    response = runSlapgridUntilSuccess(self.app.config, 'software')
    self.assertEqual(response, (1, MAX_RUN_INSTANCE))


522
def main():
523 524 525
  # Empty parser for now - so that erp5testnode is happy when doing --help
  parser = argparse.ArgumentParser()
  parser.parse_args()
526
  unittest.main(module=__name__)
527 528

if __name__ == '__main__':
Marco Mariani's avatar
Marco Mariani committed
529
  main()