Browse Source

integration-tests: job summary

Mokhtar Naamani 4 years ago
parent
commit
1053cc9997
1 changed files with 53 additions and 36 deletions
  1. 53 36
      tests/network-tests/src/Scenario.ts

+ 53 - 36
tests/network-tests/src/Scenario.ts

@@ -27,49 +27,49 @@ export type FlowArgs = { api: Api; env: NodeJS.ProcessEnv; query: QueryNodeApi }
 export type Flow = (args: FlowArgs) => Promise<void>
 
 enum JobOutcome {
-  Succeeded,
-  Failed,
-  Skipped,
+  Succeeded = 'Succeeded',
+  Failed = 'Failed',
+  Skipped = 'Skipped',
 }
 
 class Job {
-  private required: Job[] = []
-  private dependencies: Job[] = []
-  private flows: Flow[]
-  private manager: FlowManager
-  private _outcome: InvertedPromise<JobOutcome>
-  private locked = false
-  private name: string
-  private debug: Debugger.Debugger
-
-  constructor(manager: FlowManager, flows: Flow[], name: string) {
-    this.name = name
-    this.manager = manager
-    this.flows = flows
+  private _required: Job[] = []
+  private _after: Job[] = []
+  private _locked = false
+  private readonly _flows: Flow[]
+  private readonly _manager: FlowManager
+  private readonly _outcome: InvertedPromise<JobOutcome>
+  private readonly _label: string
+  private readonly debug: Debugger.Debugger
+
+  constructor(manager: FlowManager, flows: Flow[], label: string) {
+    this._label = label
+    this._manager = manager
+    this._flows = flows
     this._outcome = new InvertedPromise<JobOutcome>()
-    this.manager.on('run', this.run.bind(this))
-    this.debug = Debugger(`job:${this.name}`)
+    this._manager.on('run', this.run.bind(this))
+    this.debug = Debugger(`job:${this._label}`)
   }
 
   // Depend on another job to complete successfully
   public requires(job: Job): Job {
-    if (this.locked) throw new Error('Job is locked')
+    if (this._locked) throw new Error('Job is locked')
     if (job === this) throw new Error('Job Cannot depend on itself')
     if (job.hasDependencyOn(this)) {
       throw new Error('Job Circualr dependency')
     }
-    this.required.push(job)
+    this._required.push(job)
     return this
   }
 
   // Depend on another job to complete (does not matter if it is successful)
   public after(job: Job): Job {
-    if (this.locked) throw new Error('Job is locked')
+    if (this._locked) throw new Error('Job is locked')
     if (job === this) throw new Error('Job Cannot depend on itself')
     if (job.hasDependencyOn(this)) {
       throw new Error('Job Circualr dependency')
     }
-    this.dependencies.push(job)
+    this._after.push(job)
     return this
   }
 
@@ -79,7 +79,7 @@ class Job {
   }
 
   public hasDependencyOn(job: Job): boolean {
-    return !!this.required.find((j) => j === job) || !!this.dependencies.find((j) => j === job)
+    return !!this._required.find((j) => j === job) || !!this._after.find((j) => j === job)
   }
 
   // configure to have flows run serially instead of in parallel
@@ -91,29 +91,39 @@ class Job {
     return this._outcome.promise
   }
 
+  get label(): string {
+    return this._label
+  }
+
   private async run(flowArgs: FlowArgs): Promise<void> {
     // prevent any additional changes to configuration
-    this.locked = true
+    this._locked = true
 
     // wait for all required dependencies to complete successfully
-    const requiredOutcomes = await Promise.all(this.required.map((job) => job.outcome))
+    const requiredOutcomes = await Promise.all(this._required.map((job) => job.outcome))
     if (requiredOutcomes.find((outcome) => outcome !== JobOutcome.Succeeded)) {
-      this.debug('Skipped because required jobs not successful')
+      this.debug('[Skipping] - Required jobs not successful!')
       return this._outcome.resolve(JobOutcome.Skipped)
     }
 
     // Wait for other jobs to complete, irrespective of outcome
-    await Promise.all(this.dependencies.map((job) => job.outcome))
+    await Promise.all(this._after.map((job) => job.outcome))
+
+    this.debug('Running')
+    const flowRunResults = await Promise.allSettled(this._flows.map((flow) => flow(flowArgs)))
 
-    this.debug('Running flows')
-    const flowRunResults = await Promise.allSettled(this.flows.map((flow) => flow(flowArgs)))
-    this.debug('Flow run complete')
+    flowRunResults.forEach((result, ix) => {
+      if (result.status === 'rejected') {
+        this.debug(`flow ${ix} failed:`)
+        console.error(result.reason)
+      }
+    })
 
     if (flowRunResults.find((result) => result.status === 'rejected')) {
-      this.debug('Failed')
+      this.debug('[Failed]')
       this._outcome.resolve(JobOutcome.Failed)
     } else {
-      this.debug('Succeeded')
+      this.debug('[Succeeded]')
       this._outcome.resolve(JobOutcome.Succeeded)
     }
   }
@@ -140,11 +150,18 @@ class FlowManager extends EventEmitter {
   public async run(): Promise<void> {
     this.emit('run', this.flowArgs)
 
-    const jobOutcomes = await Promise.all(this._jobs.map((job) => job.outcome))
+    const outcomes = await Promise.all(this._jobs.map((job) => job.outcome))
+
+    // summary of job results
+    console.error('Job Results:')
+    outcomes.forEach((outcome, i) => {
+      const { label } = this._jobs[i]
+      console.error(`${label}: ${outcome}`)
+    })
 
-    const someJobDidNotSucceed = jobOutcomes.find((outcome) => outcome !== JobOutcome.Succeeded)
-    if (someJobDidNotSucceed) {
-      throw new Error('Some jobs failed or skipped')
+    const failed = outcomes.find((outcome) => outcome !== JobOutcome.Succeeded)
+    if (failed) {
+      throw new Error('Scenario Failed')
     }
   }
 }