This is an automated email from the ASF dual-hosted git repository.

wilfreds pushed a commit to branch branch-1.7
in repository https://gitbox.apache.org/repos/asf/yunikorn-web.git


The following commit(s) were added to refs/heads/branch-1.7 by this push:
     new 0e4d6fb  [YUNIKORN-3076] WebUI fails to load apps that are in 'New' 
(#233)
0e4d6fb is described below

commit 0e4d6fb4eb7e7c005868feaf08e7bf68a955c186
Author: Mit Desai <[email protected]>
AuthorDate: Tue May 27 10:00:06 2025 +1000

    [YUNIKORN-3076] WebUI fails to load apps that are in 'New' (#233)
    
    When an application is reported to be in a 'New' state by the scheduler, it
    does not have a stateLog object. On the web UI side, there are currently no
    checks to handle the absence of the stateLog object. As a result, when the
    application list contains an application in the 'New' state and the
    stateLog is missing, the code attempts to access this.stateLog, leading to
    a failure and preventing the page from loading any applications.
    
    Closes: #233
    
    Signed-off-by: Wilfred Spiegelenburg <[email protected]>
    (cherry picked from commit 541135b7f28c9e63155d76ec730bfd36dcafa27b)
---
 .../apps-view/apps-view.component.spec.ts          | 45 +++++++++++++++++++++-
 src/app/models/app-info.model.ts                   |  9 ++++-
 2 files changed, 51 insertions(+), 3 deletions(-)

diff --git a/src/app/components/apps-view/apps-view.component.spec.ts 
b/src/app/components/apps-view/apps-view.component.spec.ts
index 951b932..0679bdc 100644
--- a/src/app/components/apps-view/apps-view.component.spec.ts
+++ b/src/app/components/apps-view/apps-view.component.spec.ts
@@ -30,7 +30,7 @@ import { MatTooltipModule } from '@angular/material/tooltip';
 import { By, HAMMER_LOADER } from '@angular/platform-browser';
 import { NoopAnimationsModule } from '@angular/platform-browser/animations';
 import { RouterTestingModule } from '@angular/router/testing';
-import { AppInfo } from '@app/models/app-info.model';
+import { AppInfo, StateLog } from '@app/models/app-info.model';
 import { SchedulerService } from '@app/services/scheduler/scheduler.service';
 import { MockNgxSpinnerService, MockSchedulerService } from 
'@app/testing/mocks';
 import { NgxSpinnerService } from 'ngx-spinner';
@@ -108,4 +108,47 @@ describe('AppsViewComponent', () => {
     copyButton.triggerEventHandler('click', null);
     expect(copyButtonSpy).toHaveBeenCalled();
   });
+
+  it('should set lastStateChangeTime to the latest time in stateLog', () => {
+    const stateLogs = [
+      new StateLog(100, 'SUBMITTED'),
+      new StateLog(200, 'RUNNING'),
+      new StateLog(300, 'FINISHED')
+    ];
+    const appInfo = new AppInfo(
+      'app-test',
+      'Memory: 10.0 MB, CPU: 1, pods: 1',
+      'Memory: 0.0 bytes, CPU: 0, pods: n/a',
+      '',
+      123,
+      null,
+      stateLogs,
+      null,
+      'FINISHED',
+      []
+    );
+
+    appInfo.setLastStateChangeTime();
+
+    expect(appInfo.lastStateChangeTime).toBe(300);
+  });
+
+  it('should set lastStateChangeTime to 0 if stateLog is empty', () => {
+    const appInfo = new AppInfo(
+      'app-empty',
+      'Memory: 10.0 MB, CPU: 1, pods: 1',
+      'Memory: 0.0 bytes, CPU: 0, pods: n/a',
+      '',
+      123,
+      null,
+      [],
+      null,
+      'SUBMITTED',
+      []
+    );
+
+    appInfo.setLastStateChangeTime();
+
+    expect(appInfo.lastStateChangeTime).toBe(0);
+  });
 });
diff --git a/src/app/models/app-info.model.ts b/src/app/models/app-info.model.ts
index 3e3c1a0..76055a5 100644
--- a/src/app/models/app-info.model.ts
+++ b/src/app/models/app-info.model.ts
@@ -30,11 +30,16 @@ export class AppInfo {
     public maxUsedResource: string,
     public submissionTime: number,
     public finishedTime: null | number,
-    public stateLog: Array<StateLog>,
+    public stateLog: Array<StateLog> = [], // Default to empty array
     public lastStateChangeTime: null | number,
     public applicationState: string,
     public allocations: AllocationInfo[] | null
-  ) {}
+  ) {
+    // Ensure stateLog is always an array
+    if (!Array.isArray(this.stateLog)) {
+      this.stateLog = [];
+    }
+  }
 
   get formattedSubmissionTime() {
     const millisecs = Math.round(this.submissionTime / (1000 * 1000));


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to