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

--- # ------------------------------------------------------------------ # ---
Name: InstallableToTest
Extends:
  - apps:Installable

--- # ------------------------------------------------------------------ # ---

Name: ConfigurableToTest
Extends:
  - apps:Configurable

--- # ------------------------------------------------------------------ # ---

Name: SoftwareComponentToTest
Extends:
  - apps:SoftwareComponent


--- # ------------------------------------------------------------------ # ---
Name: TestSoftwareComponent
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)

  setUp:
    Body:
      - super($this, $.setUp())
      - inject(res:LinuxMuranoInstance, beginDeploy, '')
      - inject(res:LinuxMuranoInstance, endDeploy, '')
      - $server: new(res:LinuxMuranoInstance, $this.environment,
                     name => 'noop',
                     image => 'noop',
                     flavor => 'noop')
      - $provider: new(apps:TemplateServerProvider, $this.environment,
                       template => $server, serverNamePattern => 'testNode-{0}')
      - $this.group: new(apps:ServerReplicationGroup, $this.environment, provider => $provider, numItems => 5)
      - $this.group.deploy()
      - $this.reports: []
      - inject($this.environment.reporter, report, $this, report)

  testInstallReportingSequence:
    Body:
      - $cmp: new(InstallableToTest, $this.environment, testComp)
      - $cmp.install($this.group)
      - $this.assertInstallingSequence(0)

  testConfigureReportingSequence:
    Body:
      - $cmp: new(ConfigurableToTest, $this.environment, testComp)
      - $cmp.configure($this.group)
      - $this.assertConfiguringSequence(0)

  testCombinedSequence:
    Body:
      - $cmp: new(SoftwareComponentToTest, $this.environment, testComp)
      - $cmp.deployAt($this.group)
      - $this.assertProvisioningSequence(0)
      - $this.assertInstallingSequence($this.group.numItems)
      - $this.assertConfiguringSequence(3 * $this.group.numItems + 2)

  assertProvisioningSequence:
    Arguments:
      - offset:
          Contract: $.int().notNull()
    Body:
      - $this.assertEqual(
          range(1, $this.group.numItems + 1).select('Provisioning VM for Server {0}'.format($)),
          $this.reports.skip($offset).take($this.group.numItems))


  assertInstallingSequence:
    Arguments:
      - offset:
          Contract: $.int().notNull()
    Body:
      - $this.assertEqual('Installing testComp', $this.reports[$offset])
      - $nodeReports: range(0, $this.group.numItems * 2).select($this.reports[$offset + 1 + $])
      - range(1, $this.group.numItems + 1).select(
          $this.assertTrue(format('Began installing testComp on testNode-{0}', $) in $nodeReports))
      - range(1, $this.group.numItems + 1).select(
          $this.assertTrue(format('testComp is installed on testNode-{0}', $) in $nodeReports))
      - $this.assertEqual('Finished installing testComp (no errors encountered)',
          $this.reports[$offset + 2 * $this.group.numItems + 1])

  assertConfiguringSequence:
    Arguments:
      - offset:
          Contract: $.int().notNull()
    Body:
      - $this.assertEqual('Applying configuration of testComp', $this.reports[$offset])
      - $nodeReports: range(0, $this.group.numItems * 2).select($this.reports[$offset + 1 + $])
      - range(1, $this.group.numItems + 1).select(
          $this.assertTrue(format('Began configuring testComp on testNode-{0}', $) in $nodeReports))
      - range(1, $this.group.numItems + 1).select(
          $this.assertTrue(format('testComp is configured at testNode-{0}', $) in $nodeReports))
      - $this.assertEqual('Finished configuring testComp (no errors encountered)',
          $this.reports[$offset + 2 * $this.group.numItems + 1])

