Namespaces:
  =: io.murano.applications.tests
  tst: io.murano.test
  apps: io.murano.applications
  sys: io.murano.system
  res: io.murano.resources

--- # ------------------------------------------------------------------ # ---
Name: TestMockedServerFactory
Extends: tst:TestFixtureWithEnvironment

Properties:
  reports:
    Contract:
      - $.string()
    Usage: Out
    Default: []

Methods:
  report:
    Arguments:
      - server:
          Contract: $
      - message:
          Contract: $.string()
    Body:
      - $this.reports: $this.reports.append($message)

  heatPushInjection:
    Body:
      - $this.currentTemplate: $this.environment.stack.current()
      - $this.pushCalled: $this.pushCalled + 1


  heatOutputInjection:
    Body:
      # generate simulated output
      - $outputKeys: $this.currentTemplate.outputs.keys()
      - $idIndex: 1000
      - $ipIndex: 100
      - $ipPrefix: '10.0.0.'
      - $defaultNetworkName: testNetwork
      - $output: {}
      - For: key
        In: $outputKeys
        Do:
          # if output name ends with -id then it is some openstack-id of a resource
          - If: $key.endsWith('-id')
            Then:
              - $output[$key]: $idIndex
              - $idIndex: $idIndex + 1

          # if output name ends with -assigned-ips then it is some ip of a vm
          - If: $key.endsWith('-assigned-ips')
            Then:
              - $output[$key]:
                  $defaultNetworkName: list(format('{0}{1}', $ipPrefix, $ipIndex))
              - $ipIndex: $ipIndex + 1
      - Return: $output

  neutronListExtensionsInjection:
    Body:
      - Return:
           - alias: 'security-group'


  setUp:
    Body:
      - $this.currentTemplate: {}
      - inject(sys:NetworkExplorer, listNeutronExtensions, $this, neutronListExtensionsInjection)
      - inject(sys:NetworkExplorer, getDefaultRouter, '42')
      - inject(sys:NetworkExplorer, getAvailableCidr, '10.0.0.0/24')
      - super($this, $.setUp())
      - inject($this.environment.stack, push, $this, heatPushInjection)
      - inject($this.environment.stack, output, $this, heatOutputInjection)
      - inject($this.environment.stack, delete, '')
      - inject(sys:Agent, prepare, '')
      - inject($this.environment.instanceNotifier, trackCloudInstance, '')
      - inject($this.environment.instanceNotifier, untrackCloudInstance, '')
      - $this.reports: []
      - inject($this.environment.reporter, report, $this, report)
      - $this.pushCalled: 0


      - $serverTemplate:
          image: 'murano-latest'
          flavor: 't1.medium'
      - $this.provider: new(apps:TemplateServerProvider,
          template => $serverTemplate,
          serverNamePattern => 'testNode-{0}')

  testCreateSingleServer:
    Body:
      - $ssg: new(apps:ServerReplicationGroup, $this.environment,
          provider => $this.provider)
      - $ssg.deploy()
      - $this.assertServerCount(1)

  testServersHaveProperName:
    Body:
      - $model:
          apps:ServerReplicationGroup:
            numItems: 2
            provider:
              apps:TemplateServerProvider:
                template: $this.provider.template
                serverNamePattern: 'testNode-{0}'
          name: testGroup
      - $namedSsg: new($model, $this.environment)
      - $namedSsg.deploy()
      - $this.assertEqual('Server 1 (testGroup)', name($namedSsg.items[0]))
      - $this.assertEqual('Server 2 (testGroup)', name($namedSsg.items[1]))


  testCreateMultipleServers:
    Body:
      - $ssg: new(apps:ServerReplicationGroup, $this.environment,
          provider => $this.provider, numItems => 5)
      - $ssg.deploy()
      - $this.assertServerCount(5)

  testCreateScaleUp:
    Body:
      - $ssg: new(apps:ServerReplicationGroup, $this.environment,
          provider => $this.provider, numItems => 3)
      - $ssg.deploy()
      - $this.assertServerCount(3)
      - $ssg.scale(4)
      - $ssg.deploy()
      - $this.assertServerCount(7)

  testCreateScaleDown:
    Body:
      - $ssg: new(apps:ServerReplicationGroup, $this.environment, provider => $this.provider, numItems => 3)
      - $ssg.deploy()
      - $this.assertServerCount(3)
      - $ssg.scale(-2)
      - $ssg.deploy()
      - $this.assertServerCount(1)

  testMultipleServersReporting:
    Body:
      - $ssg: new(apps:ServerReplicationGroup, $this.environment, TestGroup,
          provider => $this.provider, numItems => 3)
      - $ssg.deploy()
      - $this.assertEqual('Creating 3 servers for TestGroup', $this.reports[0])
      - $ssg.scale(-2)
      - $this.assertEqual('Removing 2 servers from TestGroup', $this.reports[4])

  testMultipleServersReportingNoGroupName:
    Body:
      - $ssg: new(apps:ServerReplicationGroup, $this.environment, null,
          provider => $this.provider, numItems => 3)
      - $ssg.deploy()
      - $this.assertEqual('Creating 3 servers', $this.reports[0])
      - $ssg.scale(-2)
      - $this.assertEqual('Removing 2 servers', $this.reports[4])

  testNoReportingIfSingleServer:
    Body:
      - $ssg: new(apps:ServerReplicationGroup, $this.environment, TestGroup,
          provider => $this.provider, numItems => 1)
      - $ssg.deploy()
      - $this.assertEqual(1, len($this.reports))


  assertServerCount:
    Arguments:
      - count:
          Contract: $.int()
    Body:
      - $this.assertEqual($count, $this.currentTemplate.resources.values().where(
        $.type = 'OS::Nova::Server').len())
