diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 89fca01428..c55235665f 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -78,7 +78,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v3 with: - node-version: '16' + node-version: '21' - name: Docker login (ghcr) uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 0079dd9e75..0ac6bb4a93 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -122,13 +122,13 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v3 with: - node-version: '16' + node-version: '21' - name: get needs object run: echo "${{toJson(needs)}}" - name: Install dependencies - run: npm install + run: npm install --legacy-peer-deps - name: Run ESLint run: | diff --git a/.storybook/main.js b/.storybook/main.mjs similarity index 77% rename from .storybook/main.js rename to .storybook/main.mjs index e37d482385..c90b1ac53b 100644 --- a/.storybook/main.js +++ b/.storybook/main.mjs @@ -17,17 +17,17 @@ illegal under applicable law, and the grant of the foregoing license under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ -const path = require('path') -module.exports = { - babel: async options => { - options.plugins.push('babel-plugin-inline-react-svg') - return options +const config = { + framework: { + name: '@storybook/react-vite', + options: {} }, stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'], - addons: [ - '@storybook/addon-links', - '@storybook/addon-essentials', - '@storybook/preset-scss' - ] + addons: ['@storybook/addon-links', '@storybook/preset-scss', '@storybook/addon-docs'], + core: { + builder: '@storybook/builder-vite' + } } + +export default config diff --git a/.stylelintrc.json b/.stylelintrc.json index ddee2a574c..6b6282220c 100644 --- a/.stylelintrc.json +++ b/.stylelintrc.json @@ -1,10 +1,40 @@ { - "extends": ["stylelint-config-standard", "stylelint-config-rational-order"], + "extends": ["stylelint-config-standard", "stylelint-config-standard-scss", "stylelint-config-rational-order"], "plugins": [ "stylelint-scss" ], "rules": { "at-rule-no-unknown": null, - "scss/at-rule-no-unknown": true + "selector-no-vendor-prefix": null, + "scss/at-mixin-argumentless-call-parentheses": null, + "scss/dollar-variable-empty-line-before": null, + "scss/at-rule-no-unknown": true, + "media-feature-range-notation": null, + "property-no-vendor-prefix": null, + "selector-class-pattern": [ + "^[a-z0-9]+(?:-[a-z0-9]+)*(?:__(?:[a-z0-9]+(?:-[a-z0-9]+)*))*(?:_(?:[a-z0-9]+(?:-[a-z0-9]+)*)(?:_[a-z0-9]+(?:-[a-z0-9]+)*)?)?$", + { + "resolveNestedSelectors": true, + "message": "Expected kebab-case or BEM: block-name, block-name__elem-name(__sub-elem…), block-name_mod-name[_mod-val], block-name__elem-name_mod-name[_mod-val]" + } + ], + "scss/at-mixin-pattern": [ + "^(?:[a-z][a-z0-9]*(?:-[a-z0-9]+)*|[a-z][a-z0-9]*(?:[A-Z][a-z0-9]*)*)$", + { + "message": "Expected mixin name to be kebab-case (my-mixin) or camelCase (myMixin)" + } + ], + "custom-property-pattern": [ + "^(?:[a-z][a-z0-9]*(?:-[a-z0-9]+)*|[a-z][a-z0-9]*(?:[A-Z][a-z0-9]*)*)$", + { + "message": "Expected variable name to be kebab-case (my-variable) or camelCase (myVariable)" + } + ], + "scss/dollar-variable-pattern": [ + "^(?:[a-z][a-z0-9]*(?:-[a-z0-9]+)*|[a-z][a-z0-9]*(?:[A-Z][a-z0-9]*)*)$", + { + "message": "Expected variable name to be kebab-case (my-variable) or camelCase (myVariable)" + } + ] } } diff --git a/config/paths.js b/config/paths.js index b17443273e..ea07637455 100644 --- a/config/paths.js +++ b/config/paths.js @@ -83,7 +83,6 @@ module.exports = { appJsConfig: resolveApp('jsconfig.json'), yarnLockFile: resolveApp('yarn.lock'), testsSetup: resolveModule(resolveApp, 'src/setupTests'), - proxySetup: resolveApp('src/setupProxy.js'), appNodeModules: resolveApp('node_modules'), appWebpackCache: resolveApp('node_modules/.cache'), appTsBuildInfoFile: resolveApp('node_modules/.cache/tsconfig.tsbuildinfo'), diff --git a/eslint.config.mjs b/eslint.config.mjs index 5fbdd6a2a6..da24470c03 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -3,6 +3,7 @@ import globals from 'globals' import js from '@eslint/js' import react from 'eslint-plugin-react' import reactHooks from 'eslint-plugin-react-hooks' +import eslintPluginImport from 'eslint-plugin-import' export default [ { ignores: ['dist'] }, @@ -12,7 +13,11 @@ export default [ files: ['**/*.{js,jsx,ts,tsx}'], languageOptions: { ecmaVersion: 2021, - globals: globals.browser, + globals: { + ...globals.browser, + ...globals.jest, + ...globals.node + }, parserOptions: { ecmaFeatures: { jsx: true @@ -21,7 +26,8 @@ export default [ }, plugins: { react: react, - 'react-hooks': reactHooks + 'react-hooks': reactHooks, + import: eslintPluginImport }, settings: { react: { @@ -34,6 +40,7 @@ export default [ 'react/react-in-jsx-scope': 'off', 'react/no-unescaped-entities': 'off', 'import/no-anonymous-default-export': 'off', + 'import/named': process.env.NODE_ENV === 'production' ? 2 : 1, 'no-unused-vars': process.env.NODE_ENV === 'production' ? 2 : 1, 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 1, 'no-console': process.env.NODE_ENV === 'production' ? 2 : 1, diff --git a/package.json b/package.json index fadad6e468..af141ee1c3 100644 --- a/package.json +++ b/package.json @@ -4,16 +4,16 @@ "private": true, "homepage": "/mlrun", "dependencies": { + "@dagrejs/dagre": "^1.1.5", "@monaco-editor/react": "^4.7.0", "@reduxjs/toolkit": "^1.9.5", - "axios": "1.8.2", + "axios": "1.12.2", "bfj": "^7.0.2", "camelcase": "^6.3.0", "chart.js": "^4.4.2", "classnames": "^2.5.1", "concurrently": "^6.4.2", "cronstrue": "^2.49.0", - "dagre": "^0.8.5", "dotenv": "^10.0.0", "dotenv-expand": "^5.1.0", "file-saver": "^2.0.5", @@ -21,7 +21,7 @@ "final-form-arrays": "^3.1.0", "fs-extra": "^10.0.0", "identity-obj-proxy": "^3.0.0", - "iguazio.dashboard-react-controls": "3.0.3", + "iguazio.dashboard-react-controls": "3.2.2", "is-wsl": "^1.1.0", "js-base64": "^2.6.4", "js-yaml": "^4.1.0", @@ -32,14 +32,14 @@ "prompts": "^2.4.2", "prop-types": "^15.8.1", "qs": "^6.9.6", - "react": "^18.2.0", - "react-dom": "^18.2.0", + "react": "^19.2.0", + "react-dom": "^19.2.0", "react-final-form": "^6.5.9", "react-final-form-arrays": "^3.1.4", "react-modal-promise": "^1.0.2", "react-redux": "^7.2.9", "react-refresh": "^0.11.0", - "react-router-dom": "6.22.3", + "react-router-dom": "7.9.4", "react-text-mask": "^5.4.3", "react-transition-group": "^4.4.5", "reactflow": "^11.11.1", @@ -57,102 +57,99 @@ "start": "vite", "build": "vite build", "lint": "eslint .", + "stylelint": "stylelint '**/*.{css,scss}'", "preview": "vite preview", "preinstall": "npx force-resolutions", "test:coverage": "npm run test -- --coverage --watchAll=false", "docker": "docker build -t ${MLRUN_DOCKER_REGISTRY}${MLRUN_DOCKER_REPO:-mlrun}/mlrun-ui:${MLRUN_DOCKER_TAG:-latest} --build-arg COMMIT_HASH=\"`git rev-parse --short HEAD`\" --build-arg DATE=\"`date -u`\" -f Dockerfile .", "generate-rn": "./generate-release-notes.js ${MLRUN_OLD_VERSION} ${MLRUN_VERSION} ${MLRUN_RELEASE_BRANCH} ${MLRUN_RELEASE_TYPE}", - "storybook": "start-storybook -p 6006", + "storybook": "storybook dev -p 6006", "build-storybook": "build-storybook", "mock-server": "node scripts/mockServer.js", "mock-server:dev": "nodemon --watch tests/mockServer scripts/mockServer.js", + "test": "vitest", "test:ui": "node scripts/testui.js", + "test:watch": "vitest --watch", "report": "node tests/report.js", "test:regression": "npm run test:ui && npm run report", "start:regression": "concurrently \"npm:mock-server\" \"npm:start\" \"npm:test:regression\"", - "ui-steps": "export BABEL_ENV=test; export NODE_ENV=test; npx -p @babel/core -p @babel/node babel-node --presets @babel/preset-env scripts/collectUITestsSteps.js", + "ui-steps": "cross-env BABEL_ENV=test; cross-env NODE_ENV=test; npx -p @babel/core -p @babel/node babel-node --presets @babel/preset-env scripts/collectUITestsSteps.js", "nli": "npm link iguazio.dashboard-react-controls", "nui": "npm unlink iguazio.dashboard-react-controls" }, "devDependencies": { - "@babel/core": "^7.16.0", - "@babel/eslint-parser": "^7.24.1", - "@babel/node": "^7.14.9", - "@babel/plugin-proposal-logical-assignment-operators": "^7.12.1", + "@babel/core": "^7.28.4", + "@babel/node": "^7.28.0", + "@babel/plugin-transform-logical-assignment-operators": "^7.27.1", "@babel/polyfill": "^7.12.1", - "@babel/preset-env": "^7.13.12", - "@babel/register": "^7.13.14", + "@babel/preset-env": "^7.28.3", + "@babel/preset-react": "^7.27.1", + "@babel/register": "^7.28.3", "@cucumber/cucumber": "^10.3.1", "@d4c/numjs": "^0.17.34", - "@eslint/js": "^9.19.0", - "@storybook/addon-actions": "^8.0.1", - "@storybook/addon-essentials": "^8.0.1", - "@storybook/addon-links": "^8.0.1", + "@eslint/js": "^9.37.0", + "@storybook/addon-docs": "9.1.10", + "@storybook/addon-links": "^9.1.10", + "@storybook/builder-vite": "^9.1.10", "@storybook/preset-scss": "^1.0.3", + "@storybook/react-vite": "^9.1.10", + "@testing-library/dom": "^10.4.1", + "@testing-library/react": "^16.3.0", "@storybook/react": "^8.0.1", - "@testing-library/react": "^11.0.2", + "@testing-library/jest-dom": "^6.9.1", + "@testing-library/user-event": "^14.6.1", "@vitejs/plugin-react": "^4.3.4", "@vitejs/plugin-react-swc": "^3.8.0", - "acorn": "^7.4.1", - "babel-jest": "^29.7.0", - "babel-loader": "^8.2.3", + "acorn": "^8.15.0", + "babel-jest": "^30.2.0", "babel-node": "0.0.1-security", - "babel-plugin-inline-react-svg": "^2.0.1", - "babel-plugin-jest-hoist": "^26.2.0", - "babel-plugin-named-asset-import": "^0.3.8", - "babel-plugin-prismjs": "^2.1.0", - "babel-plugin-react-remove-properties": "^0.3.0", - "babel-preset-react-app": "^10.0.1", + "babel-plugin-inline-react-svg": "^2.0.2", + "babel-plugin-jest-hoist": "^30.0.1", "babel-runtime": "^6.26.0", - "body-parser": "^1.19.0", + "body-parser": "^2.2.0", "chai": "^4.3.4", - "chromedriver": "^136.0.0", - "cross-env": "^7.0.3", - "css-loader": "^6.5.1", - "cucumber-html-reporter": "^5.3.0", - "eslint": "^9.13.0", - "eslint-config-prettier": "^9.1.0", + "chromedriver": "^142.0.4", + "cross-env": "^10.0.0", + "cucumber-html-reporter": "^7.2.0", + "eslint": "^9.37.0", + "eslint-config-prettier": "^10.1.8", "eslint-plugin-babel": "^5.3.1", - "eslint-plugin-prettier": "^5.1.3", - "eslint-plugin-react": "^7.37.4", - "eslint-plugin-react-hooks": "^5.1.0", - "eslint-plugin-react-refresh": "^0.4.14", - "express": "^4.17.1", - "file-loader": "^6.2.0", - "geckodriver": "^3.0.1", - "globals": "^15.14.0", - "http-proxy-middleware": "^2.0.3", - "mime-types": "^2.1.35", + "eslint-plugin-import": "^2.32.0", + "eslint-plugin-prettier": "^5.5.4", + "eslint-plugin-react": "^7.37.5", + "eslint-plugin-react-hooks": "^7.0.0", + "eslint-plugin-react-refresh": "^0.4.23", + "eslint-plugin-storybook": "9.1.10", + "express": "^5.1.0", + "geckodriver": "^6.0.1", + "globals": "^16.4.0", + "jsdom": "^27.2.0", + "mime-types": "^3.0.1", "node": "^21.6.2", - "nodemon": "^3.1.2", + "nodemon": "^3.1.10", "pandas-js": "^0.2.4", - "postcss": "^8.4.36", - "postcss-flexbugs-fixes": "^5.0.2", - "postcss-normalize": "^10.0.1", - "postcss-preset-env": "^9.5.2", - "postcss-safe-parser": "7.0.0", - "prettier": "^3.3.3", + "prettier": "^3.6.2", "randexp": "^0.5.3", "react-app-polyfill": "^3.0.0", "react-dev-utils": "^12.0.1", - "sass": "^1.72.0", - "sass-loader": "^12.3.2", - "selenium-webdriver": "^4.0.0-beta.2", - "source-map-loader": "^5.0.0", - "stylelint": "^13.3.3", + "sass": "^1.93.2", + "selenium-webdriver": "^4.35.0", + "stylelint": "^16.24.0", "stylelint-config-rational-order": "^0.1.2", - "stylelint-config-standard": "^20.0.0", - "stylelint-order": "^4.0.0", - "stylelint-scss": "^3.17.2", + "stylelint-config-standard": "^39.0.0", + "stylelint-config-standard-scss": "^16.0.0", + "stylelint-order": "^7.0.0", + "stylelint-scss": "^6.12.1", "url-loader": "4.1.1", - "vite": "^6.2.0", + "vite": "^6.3.6", "vite-plugin-commonjs": "^0.10.4", "vite-plugin-eslint": "^1.8.1", - "vite-plugin-svgr": "^4.3.0" + "vite-plugin-svgr": "^4.5.0", + "vitest": "^4.0.10" }, "babel": { "plugins": [ - "@babel/plugin-proposal-logical-assignment-operators" + "@babel/plugin-transform-logical-assignment-operators" ], "presets": [ [ @@ -161,6 +158,10 @@ "useBuiltIns": "usage", "corejs": "^3.23.3" } + ], + [ + "@babel/preset-react", + {} ] ] } diff --git a/src/App.jsx b/src/App.jsx index c4d80186ab..84ead1754b 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -33,14 +33,15 @@ import 'prismjs/components/prism-yaml.min.js' import 'prismjs/components/prism-json.min.js' import 'prismjs/components/prism-python.min.js' +import { LoaderForSuspenseFallback } from 'igz-controls/components' import Header from './layout/Header/Header' -import LoaderForSuspenseFallback from './common/Loader/LoaderForSuspenseFallback' import Notifications from './common/Notifications/Notifications' import localStorageService from './utils/localStorageService' import { lazyRetry } from './lazyWithRetry' import { useMode } from './hooks/mode.hook' import { useNuclioMode } from './hooks/nuclioMode.hook' +import wrapComponentForNavbarNavigationTracking from './utils/wrapComponentForNavbarNavigationTracking' import { ALERTS_PAGE_PATH, @@ -124,6 +125,9 @@ const WorkflowsMonitoring = lazyRetry( ) const Documents = lazyRetry(() => import('./components/Documents/Documents')) const LLMPrompts = lazyRetry(() => import('./components/LLMPrompts/LLMPrompts')) +const ApplicationMetrics = lazyRetry( + () => import('./components/ApplicationMetrics/ApplicationMetrics') +) const MonitoringApplicationsPage = lazyRetry( () => import('./components/MonitoringApplicationsPage/MonitoringApplicationsPage') @@ -145,6 +149,13 @@ const App = () => { const isHeaderShown = localStorageService.getStorageValue('mlrunUi.headerHidden') !== 'true' const mlAppContainerClasses = classNames('ml-app-container', isHeaderShown && 'has-header') + const FilesComponent = wrapComponentForNavbarNavigationTracking(Files) + const DatasetsComponent = wrapComponentForNavbarNavigationTracking(Datasets) + const DocumentsComponent = wrapComponentForNavbarNavigationTracking(Documents) + const LLMPromptsComponent = wrapComponentForNavbarNavigationTracking(LLMPrompts) + const FunctionsOldComponent = wrapComponentForNavbarNavigationTracking(FunctionsOld) + const FunctionsComponent = wrapComponentForNavbarNavigationTracking(Functions) + const router = createBrowserRouter( createRoutesFromElements( <> @@ -252,7 +263,7 @@ const App = () => { } + element={} /> )) @@ -262,7 +273,7 @@ const App = () => { 'projects/:projectName/functions/:funcName/:tag/:tab' ].map((path, index) => ( - } /> + } /> ))} {[ @@ -272,7 +283,7 @@ const App = () => { `projects/:projectName/datasets/:artifactName/${ALL_VERSIONS_PATH}/:id/:tab` ].map((path, index) => ( - } /> + } /> ))} { `projects/:projectName/files/:artifactName/${ALL_VERSIONS_PATH}/:id/:tab` ].map((path, index) => ( - } /> + } /> + + ))} + {[ + `projects/:projectName/monitoring-app/:appName/${MODEL_ENDPOINTS_TAB}`, + `projects/:projectName/monitoring-app/:appName/${MODEL_ENDPOINTS_TAB}/:id` + ].map((path, index) => ( + + } /> ))} { `projects/:projectName/documents/:artifactName/${ALL_VERSIONS_PATH}/:id/:tab` ].map((path, index) => ( - } /> + } /> ))} {[ @@ -365,7 +384,7 @@ const App = () => { `projects/:projectName/llm-prompts/:artifactName/${ALL_VERSIONS_PATH}/:id/:tab` ].map((path, index) => ( - } /> + } /> ))} } /> diff --git a/src/App.test.js b/src/App.test.js index 720bf81e06..eb8e8bec16 100755 --- a/src/App.test.js +++ b/src/App.test.js @@ -18,11 +18,11 @@ under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ import React from 'react' -import ReactDOM from 'react-dom' +import { createRoot } from 'react-dom/client' import App from './App' it('renders without crashing', () => { - const div = document.createElement('div') - ReactDOM.render(, div) - ReactDOM.unmountComponentAtNode(div) + const root = createRoot(document.getElementById('root')) + root.render() + root.unmount() }) diff --git a/src/api/artifacts-api.js b/src/api/artifacts-api.js index 0e9f581fc9..17edeba249 100644 --- a/src/api/artifacts-api.js +++ b/src/api/artifacts-api.js @@ -23,7 +23,9 @@ import { ARTIFACT_OTHER_TYPE, DATASET_TYPE, DOCUMENT_TYPE, - // LLM_PROMPT_TYPE, + LLM_PROMPT_TYPE, + MODEL_NAME_FILTER, + MODEL_TAG_FILTER, MODEL_TYPE, SHOW_ITERATIONS, TAG_FILTER_ALL_ITEMS, @@ -56,6 +58,10 @@ const fetchArtifacts = (project, filters, config = {}, withLatestTag, withExactN params.tree = filters.tree } + if (filters?.[MODEL_NAME_FILTER]) { + params.parent = `${filters[MODEL_NAME_FILTER]}${filters[MODEL_TAG_FILTER] ? `:${filters[MODEL_TAG_FILTER]}` : ''}` + } + return mainHttpClientV2.get(`/projects/${project}/artifacts`, { ...config, params: { ...config.params, ...params } @@ -146,7 +152,7 @@ const artifactsApi = { }, getArtifact: (projectName, artifactName, uid, tree, tag, iter) => { const newConfig = { - params: { tree, uid } + params: { tree, 'object-uid': uid } } if (tag) { @@ -186,99 +192,13 @@ const artifactsApi = { return fetchArtifacts(project, filters, newConfig, true) }, - getLLMPrompts: () => { - // const newConfig = { - // ...config, - // params: { ...config.params, category: LLM_PROMPT_TYPE } - // } - - // return fetchArtifacts(project, filters, newConfig, true) - return Promise.resolve({ - data: { - artifacts: [ - { - kind: 'dataset', - metadata: { - key: 'test3', - project: 'default', - tree: '3c9a5fe2-1ffc-4c4c-864b-a712a8899fe0', - description: '', - iter: null, - uid: 'c4dc3113a581a11ed69ef09258fdc0584d590f74', - updated: '2025-05-06 08:50:01.714000+00:00', - created: '2025-05-06 08:50:01.714000+00:00', - tag: 'latest' - }, - status: {}, - project: 'default', - spec: { - producer: { - kind: 'api', - name: 'UI', - uri: 'dashboard.default-tenant.app.vmdev63.lab.iguazeng.com' - }, - db_key: 'test3', - target_path: 'v3io:///asd/asd' - } - }, - { - kind: 'dataset', - metadata: { - key: 'test2', - project: 'default', - tree: '31fc16e0-ce4d-4076-baf3-53e29553bf44', - description: '', - iter: null, - uid: '28ac191a940dcada5f2c09117416db06c21f0b4a', - updated: '2025-05-06 08:49:15.869000+00:00', - created: '2025-05-06 08:49:15.869000+00:00', - tag: 'latest' - }, - status: {}, - project: 'default', - spec: { - producer: { - kind: 'api', - name: 'UI', - uri: 'dashboard.default-tenant.app.vmdev63.lab.iguazeng.com' - }, - db_key: 'test2', - target_path: 'v3io:///hj/b' - } - }, - { - kind: 'dataset', - metadata: { - key: 'test', - project: 'default', - tree: '10b8405b-366b-428f-a84a-ac1e3caf52e1', - description: '', - iter: null, - uid: '7ef62fca9189261fa2443bd3fd0ebef5f03f182d', - updated: '2025-04-24 09:53:08.584000+00:00', - created: '2025-04-24 09:53:08.584000+00:00', - tag: 'latest' - }, - status: {}, - project: 'default', - spec: { - producer: { - kind: 'api', - name: 'UI', - uri: 'localhost:3000' - }, - db_key: 'test', - target_path: 's3://dfg/fg' - } - } - ], - pagination: { - page: 1, - 'page-size': 1000, - 'page-token': null - } - } - }) + getLLMPrompts: (project, filters, config = {}) => { + const newConfig = { + ...config, + params: { ...config.params, category: LLM_PROMPT_TYPE } + } + + return fetchArtifacts(project, filters, newConfig, true) }, getModels: (project, filters, config = {}) => { const newConfig = { diff --git a/src/api/jobs-api.js b/src/api/jobs-api.js index da3d482806..34da1baddc 100644 --- a/src/api/jobs-api.js +++ b/src/api/jobs-api.js @@ -68,10 +68,19 @@ const jobsApi = { return mainHttpClient.get(`/projects/${project}/runs/${jobId}`, { params }) }, - getJobLogs: (id, project) => - fetch(`${mainBaseUrl}/projects/${project}/logs/${id}`, { - method: 'get' - }), + getJobLogs: (id, project, attempt, signal) => { + let params = '' + + // if attempt === 0 or empty BE return logs for the last attempt + if (attempt > 0) { + params = `?attempt=${attempt}` + } + + return fetch(`${mainBaseUrl}/projects/${project}/logs/${id}${params}`, { + method: 'get', + signal + }) + }, getScheduledJobs: (project, newConfig) => { return mainHttpClient.get(`/projects/${project}/schedules`, newConfig) }, diff --git a/src/api/modelEndpoints-api.js b/src/api/modelEndpoints-api.js index eac2ab097c..34ca0b436a 100644 --- a/src/api/modelEndpoints-api.js +++ b/src/api/modelEndpoints-api.js @@ -18,13 +18,18 @@ under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ import { mainHttpClient } from '../httpClient' +import { BATCH_FILTER, FILTER_ALL_ITEMS, ME_MODE_FILTER, REAL_TIME_FILTER } from '../constants' const modelEndpointsApi = { getModelEndpoint: (project, name, uid) => mainHttpClient.get( - `/projects/${project}/model-endpoints/${name}?endpoint_id=${uid}&feature_analysis=true` + `/projects/${project}/model-endpoints/${name}?endpoint-id=${uid}&feature-analysis=true` ), getModelEndpoints: (project, filters, config = {}, params = {}) => { + const modesMap = { + [REAL_TIME_FILTER]: 0, + [BATCH_FILTER]: 1 + } const newConfig = { ...config, params @@ -34,6 +39,10 @@ const modelEndpointsApi = { newConfig.params.label = filters.labels?.split(',') } + if (filters[ME_MODE_FILTER] && filters[ME_MODE_FILTER] !== FILTER_ALL_ITEMS) { + newConfig.params.mode = modesMap[filters[ME_MODE_FILTER]] + } + return mainHttpClient.get(`/projects/${project}/model-endpoints`, newConfig) }, getModelEndpointMetrics: (project, uid, type = 'all') => diff --git a/src/api/monitoringApplications-api.js b/src/api/monitoringApplications-api.js index 07cf703503..74c34aa548 100644 --- a/src/api/monitoringApplications-api.js +++ b/src/api/monitoringApplications-api.js @@ -20,11 +20,19 @@ such restriction. import { mainHttpClient } from '../httpClient' const monitoringApplications = { + getMEPWithDetections: (project, params) => + mainHttpClient.get(`projects/${project}/model-monitoring/drift-over-time`, { + params + }), getMonitoringApplication: (project, functionName, params) => - mainHttpClient.get(`projects/${project}/model-monitoring/function-summary/${functionName}`, { params }), + mainHttpClient.get(`projects/${project}/model-monitoring/function-summaries/${functionName}`, { + params + }), getMonitoringApplications: (project, params) => - mainHttpClient.get(`projects/${project}/model-monitoring/function-summaries`, { params }), - getMonitoringApplicationsSummary: project => mainHttpClient.get(`project-summary/${project}`) + mainHttpClient.get(`projects/${project}/model-monitoring/function-summaries`, { + params + }), + getMonitoringApplicationsSummary: project => mainHttpClient.get(`project-summaries/${project}`) } export default monitoringApplications diff --git a/src/api/projects-iguazio-api.js b/src/api/projects-iguazio-api.js index 614475ace2..edc7d3c702 100644 --- a/src/api/projects-iguazio-api.js +++ b/src/api/projects-iguazio-api.js @@ -49,6 +49,15 @@ const projectsIguazioApi = { } }) }, + getProjectWorkflowsUpdateAuthorization: project => { + return iguazioHttpClient.get(`/projects/__name__/${project}/authorization`, { + params: { + action: 'update', + sub_resource: 'workflow' + } + }) + }, + updateProjectMembers: data => { return iguazioHttpClient.post('/async_transactions', data) }, diff --git a/src/api/workflow-api.js b/src/api/workflow-api.js index 0d5db970a6..09b412947d 100644 --- a/src/api/workflow-api.js +++ b/src/api/workflow-api.js @@ -20,7 +20,7 @@ such restriction. import { capitalize, set } from 'lodash' import { mainHttpClient } from '../httpClient' -import { GROUP_BY_WORKFLOW, FILTER_ALL_ITEMS } from '../constants' +import { GROUP_BY_WORKFLOW, FILTER_ALL_ITEMS, COMPLETED_STATE } from '../constants' const generateQueryParams = (project, filter) => { // Generating encoded JSON query string to send as a value to the filter query param @@ -56,7 +56,9 @@ const generateQueryParams = (project, filter) => { key: 'status', op: 8, string_values: { - values: stateFilter.map(state => (state === 'completed' ? 'Succeeded' : capitalize(state))) + values: stateFilter.map(state => + state === COMPLETED_STATE ? 'Succeeded' : capitalize(state) + ) } }) } @@ -111,6 +113,9 @@ const workflowsApi = { }, rerunWorkflow: (project, workflowId) => { return mainHttpClient.post(`projects/${project}/pipelines/${workflowId}/retry`) + }, + terminateWorkflow: (project, workflowId) => { + return mainHttpClient.post(`/projects/${project}/pipelines/${workflowId}/terminate`) } } diff --git a/src/common/ActionsMenu/ActionsMenu.jsx b/src/common/ActionsMenu/ActionsMenu.jsx deleted file mode 100644 index 320ae74d35..0000000000 --- a/src/common/ActionsMenu/ActionsMenu.jsx +++ /dev/null @@ -1,191 +0,0 @@ -/* -Copyright 2019 Iguazio Systems Ltd. - -Licensed under the Apache License, Version 2.0 (the "License") with -an addition restriction as set forth herein. You may not use this -file except in compliance with the License. You may obtain a copy of -the License at http://www.apache.org/licenses/LICENSE-2.0. - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -implied. See the License for the specific language governing -permissions and limitations under the License. - -In addition, you may not use the software for any purposes that are -illegal under applicable law, and the grant of the foregoing license -under the Apache 2.0 license is conditioned upon your compliance with -such restriction. -*/ -import React, { useCallback, useEffect, useRef, useState } from 'react' -import PropTypes from 'prop-types' -import { isEmpty } from 'lodash' -import classnames from 'classnames' - -import ActionsMenuItem from '../../elements/ActionMenuItem/ActionsMenuItem' -import { PopUpDialog, RoundedIcon } from 'igz-controls/components' - -import { ACTIONS_MENU } from '../../types' - -import ActionMenuIcon from 'igz-controls/images/elipsis.svg?react' - -import './actionsMenu.scss' - -const ActionsMenu = ({ - dataItem = {}, - menu, - menuPosition = '', - time = 100, - withQuickActions = false -}) => { - const [actionMenu, setActionMenu] = useState(menu) - const [isIconDisplayed, setIsIconDisplayed] = useState(false) - const [isShowMenu, setIsShowMenu] = useState(false) - const actionMenuRef = useRef() - const actionMenuBtnRef = useRef() - const dropDownMenuRef = useRef() - const mainActionsWrapperRef = useRef() - - let idTimeout = null - - const actionMenuClassNames = classnames( - 'actions-menu__container', - withQuickActions && 'actions-menu__container_extended', - isShowMenu && 'actions-menu__container-active' - ) - - const clickHandler = useCallback( - event => { - if (!event.target.closest('.actions-menu-button')) { - setIsShowMenu(false) - } - }, - [setIsShowMenu] - ) - - const scrollHandler = useCallback( - event => { - if (!event.target.closest('.actions-menu__body')) { - setIsShowMenu(false) - } - }, - [setIsShowMenu] - ) - - const onMouseOut = () => { - if (isShowMenu) { - idTimeout = setTimeout(() => { - setIsShowMenu(false) - }, time) - } - } - - const handleMouseOver = event => { - if (mainActionsWrapperRef.current?.contains(event.target)) { - setIsShowMenu(false) - } - - if (idTimeout) clearTimeout(idTimeout) - } - - useEffect(() => { - if (!isEmpty(dataItem)) { - setActionMenu(typeof menu === 'function' ? menu(dataItem, menuPosition) : menu) - } - }, [dataItem, menu, menuPosition]) - - useEffect(() => { - setIsIconDisplayed(actionMenu[0]?.some(menuItem => menuItem.icon)) - }, [actionMenu]) - - useEffect(() => { - window.addEventListener('click', clickHandler) - window.addEventListener('scroll', scrollHandler, true) - - return () => { - window.removeEventListener('click', clickHandler) - window.removeEventListener('scroll', scrollHandler, true) - } - }, [clickHandler, scrollHandler]) - - return ( -
- {withQuickActions && ( -
- {actionMenu[1].map( - mainAction => - !mainAction.hidden && ( - mainAction.onClick(dataItem)} - tooltipText={mainAction.label} - key={mainAction.label} - > - {mainAction.icon} - - ) - )} -
- )} - {actionMenu[0].length > 0 && ( -
- { - setIsShowMenu(prevValue => !prevValue) - }} - ref={actionMenuBtnRef} - tooltipText="More actions" - > - - - {isShowMenu && ( - -
    - {actionMenu[0].map( - (menuItem, idx) => - !menuItem.hidden && ( - - ) - )} -
-
- )} -
- )} -
- ) -} - -ActionsMenu.propTypes = { - dataItem: PropTypes.oneOfType([PropTypes.object, PropTypes.string]), - menu: ACTIONS_MENU.isRequired, - menuPosition: PropTypes.string, - time: PropTypes.number, - withQuickActions: PropTypes.bool -} - -export default ActionsMenu diff --git a/src/common/ActionsMenu/actionsMenu.scss b/src/common/ActionsMenu/actionsMenu.scss deleted file mode 100644 index 067f576d6b..0000000000 --- a/src/common/ActionsMenu/actionsMenu.scss +++ /dev/null @@ -1,60 +0,0 @@ -@use 'igz-controls/scss/colors'; - -.actions-menu { - position: relative; - - &__container { - position: relative; - display: none; - - &_extended { - position: absolute; - right: 0; - display: none; - align-items: center; - justify-content: center; - background-color: colors.$ghostWhite; - height: 100%; - - &:before { - content: ''; - width: 30px; - height: 100%; - position: absolute; - display: block; - left: -30px; - background: linear-gradient(90deg, rgba(255, 255, 255, 0) 0%, rgba(245, 247, 255, 1) 100%); - } - - .actions-menu { - padding: 0 5px 0 0; - } - } - - &-active { - display: flex; - } - } - - &__main-actions-wrapper { - display: flex; - align-items: center; - justify-content: center; - } - - &__body { - min-width: 150px; - max-width: 250px; - - .pop-up-dialog { - width: 100%; - padding: 0; - } - } - - &__list { - list-style-type: none; - margin: 0; - padding: 0; - } -} diff --git a/src/common/BlockerSpy/BlockerSpy.jsx b/src/common/BlockerSpy/BlockerSpy.jsx deleted file mode 100644 index db1028d710..0000000000 --- a/src/common/BlockerSpy/BlockerSpy.jsx +++ /dev/null @@ -1,39 +0,0 @@ -/* -Copyright 2019 Iguazio Systems Ltd. - -Licensed under the Apache License, Version 2.0 (the "License") with -an addition restriction as set forth herein. You may not use this -file except in compliance with the License. You may obtain a copy of -the License at http://www.apache.org/licenses/LICENSE-2.0. - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -implied. See the License for the specific language governing -permissions and limitations under the License. - -In addition, you may not use the software for any purposes that are -illegal under applicable law, and the grant of the foregoing license -under the Apache 2.0 license is conditioned upon your compliance with -such restriction. -*/ -import React, { useEffect } from 'react' -import PropTypes from 'prop-types' -import { useBlocker } from 'react-router-dom' - -const BlockerSpy = ({ setBlocker, shouldBlock }) => { - const blocker = useBlocker(shouldBlock) - - useEffect(() => { - setBlocker(blocker) - }, [setBlocker, blocker]) - - return <> -} - -BlockerSpy.propTypes = { - setBlocker: PropTypes.func.isRequired, - shouldBlock: PropTypes.func.isRequired -} - -export default BlockerSpy diff --git a/src/common/Breadcrumbs/Breadcrumbs.jsx b/src/common/Breadcrumbs/Breadcrumbs.jsx index a9087d2431..44e48643a8 100644 --- a/src/common/Breadcrumbs/Breadcrumbs.jsx +++ b/src/common/Breadcrumbs/Breadcrumbs.jsx @@ -24,9 +24,8 @@ import { useSelector } from 'react-redux' import BreadcrumbsStep from './BreadcrumbsStep/BreadcrumbsStep' -import { useMode } from '../../hooks/mode.hook' import { generateMlrunScreens, generateTabsList } from './breadcrumbs.util' -import { PROJECTS_PAGE_PATH } from '../../constants' +import { MONITORING_APP_PAGE, PROJECTS_PAGE_PATH } from '../../constants' import { generateProjectsList } from '../../utils/projects' import './breadcrumbs.scss' @@ -35,7 +34,6 @@ const Breadcrumbs = ({ onClick = () => {} }) => { const [searchValue, setSearchValue] = useState('') const [showScreensList, setShowScreensList] = useState(false) const [showProjectsList, setShowProjectsList] = useState(false) - const { isDemoMode } = useMode() const breadcrumbsRef = useRef() const params = useParams() const location = useLocation() @@ -47,8 +45,8 @@ const Breadcrumbs = ({ onClick = () => {} }) => { }, [projectStore.projectsNames.data]) const mlrunScreens = useMemo(() => { - return generateMlrunScreens(params, isDemoMode) - }, [isDemoMode, params]) + return generateMlrunScreens(params) + }, [params]) const projectTabs = useMemo(() => { return generateTabsList() }, []) @@ -57,13 +55,17 @@ const Breadcrumbs = ({ onClick = () => {} }) => { if (params.projectName) { const [projects, projectName, screenName] = location.pathname.split('/').slice(1, 4) const screen = mlrunScreens.find(screen => screen.id === screenName) - const tab = projectTabs.find(tab => + let tab = projectTabs.find(tab => location.pathname .split('/') .slice(3) .find(pathItem => pathItem === tab.id) ) + if (screen.id === MONITORING_APP_PAGE) { + tab = {} + } + return { pathItems: [projects, projectName, screen?.label || screenName], screen, diff --git a/src/common/Breadcrumbs/breadcrumbs.util.js b/src/common/Breadcrumbs/breadcrumbs.util.js index 5b92da86b1..2349ce1112 100644 --- a/src/common/Breadcrumbs/breadcrumbs.util.js +++ b/src/common/Breadcrumbs/breadcrumbs.util.js @@ -39,7 +39,7 @@ import { } from '../../constants' import { generateNuclioLink } from '../../utils' -export const generateMlrunScreens = (params, isDemo) => +export const generateMlrunScreens = params => params.projectName ? [ { @@ -48,15 +48,16 @@ export const generateMlrunScreens = (params, isDemo) => }, { label: 'Quick actions', - id: PROJECT_QUICK_ACTIONS_PAGE + id: PROJECT_QUICK_ACTIONS_PAGE, + hidden: true }, { label: 'Feature store', id: 'feature-store' }, { label: 'Datasets', id: 'datasets' }, { label: 'Documents', id: DOCUMENTS_PAGE }, - { label: 'LLM prompts', id: LLM_PROMPTS_PAGE, hidden: !isDemo }, + { label: 'LLM prompts', id: LLM_PROMPTS_PAGE }, { label: 'Artifacts', id: 'files' }, { label: 'Models', id: 'models' }, - { label: 'Monitoring app', id: MONITORING_APP_PAGE, hidden: !isDemo }, + { label: 'Monitoring app', id: MONITORING_APP_PAGE }, { label: 'Jobs and workflows', id: 'jobs' }, { label: 'ML functions', id: 'functions' }, { diff --git a/src/common/Chip/Chip.jsx b/src/common/Chip/Chip.jsx deleted file mode 100644 index d8a62dd96a..0000000000 --- a/src/common/Chip/Chip.jsx +++ /dev/null @@ -1,201 +0,0 @@ -/* -Copyright 2019 Iguazio Systems Ltd. - -Licensed under the Apache License, Version 2.0 (the "License") with -an addition restriction as set forth herein. You may not use this -file except in compliance with the License. You may obtain a copy of -the License at http://www.apache.org/licenses/LICENSE-2.0. - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -implied. See the License for the specific language governing -permissions and limitations under the License. - -In addition, you may not use the software for any purposes that are -illegal under applicable law, and the grant of the foregoing license -under the Apache 2.0 license is conditioned upon your compliance with -such restriction. -*/ -import React, { useCallback, useEffect, useLayoutEffect, useState } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import { useSelector } from 'react-redux' -import { isEmpty } from 'lodash' - -import ChipForm from '../ChipForm/ChipForm' - -import Close from 'igz-controls/images/close.svg?react' - -import { getChipLabelAndValue } from '../../utils/getChipLabelAndValue' -import { CHIP, CHIP_OPTIONS } from '../../types' - -import './chip.scss' - -const Chip = React.forwardRef( - ( - { - chip, - chipIndex = null, - chipOptions, - className, - editConfig = {}, - handleEditChip = () => {}, - handleIsEdit = () => {}, - handleRemoveChip = () => {}, - hiddenChips = false, - isDeleteMode = false, - isEditMode = false, - onClick = null, - setChipsSizes = () => {}, - setEditConfig = () => {}, - setValidation = null, - shortChip = false, - showChips, - textOverflowEllipsis = false - }, - { chipsCellRef, hiddenChipsCounterRef } - ) => { - const [validationRules, setValidationRules] = useState([]) - const frontendSpec = useSelector(store => store.appStore.frontendSpec) - const chipRef = React.useRef() - const { chipLabel, chipValue } = getChipLabelAndValue(chip) - const { background, boldValue, borderColor, density, font, borderRadius } = chipOptions - - const chipClassNames = classnames( - 'chip', - 'chip__content', - (textOverflowEllipsis || isEditMode) && 'data-ellipsis', - shortChip && 'chip_short', - hiddenChips && 'chip_hidden', - density && `chip-density_${density}`, - borderRadius && `chip-border_${borderRadius}`, - background && `chip-background_${background}`, - borderColor && `chip-border_${borderColor}`, - font && `chip-font_${font}`, - isEditMode && 'editable', - (showChips || isEditMode) && 'chip_visible', - className - ) - const chipLabelClassNames = classnames( - 'chip__label', - (textOverflowEllipsis || isEditMode) && 'data-ellipsis', - !isEmpty(validationRules) && 'chip__label_invalid' - ) - const chipValueClassNames = classnames( - 'chip__value', - (textOverflowEllipsis || isEditMode) && 'data-ellipsis', - boldValue && 'chip-value_bold' - ) - - const checkValidation = useCallback( - chipKey => { - if (frontendSpec.internal_labels.includes(chipKey)) { - setValidationRules([ - { name: 'internal label', label: 'System-defined labels cannot be modified.' } - ]) - - return setValidation && setValidation(false) - } - - setValidationRules([]) - setValidation && setValidation(true) - }, - [frontendSpec.internal_labels, setValidation] - ) - - useEffect(() => { - if (setValidation) { - checkValidation(chip.value.match(/^(?|.+?):\s?(?|.+?)$/)?.groups?.key) - } - }, [checkValidation, chip, setValidation]) - - useLayoutEffect(() => { - if (chipRef.current && setChipsSizes) { - const { marginLeft, marginRight } = getComputedStyle(chipRef.current) - - setChipsSizes(state => ({ - ...state, - [chipIndex]: - (chipRef.current?.getBoundingClientRect?.()?.width ?? 0) + - parseFloat(marginLeft) + - parseFloat(marginRight) - })) - } - }, [chipIndex, setChipsSizes]) - - if (!chip.value.match(/^\+ [\d]+/g)) { - return isEditMode && chipIndex === editConfig.chipIndex ? ( - |.+?):\s?(?|.+?)$/)?.groups} - validationRules={validationRules} - checkValidation={checkValidation} - /> - ) : ( -
handleIsEdit(event, chipIndex)} - > - {chipLabel &&
{chipLabel}
} - {chipValue && ( - <> -
{chip.delimiter ?? ':'}
-
{chipValue}
- - )} - {(isEditMode || isDeleteMode) && ( - - )} -
- ) - } - - return ( - - {chip.value} - - ) - } -) - -Chip.displayName = 'Chip' - -Chip.propTypes = { - chip: CHIP.isRequired, - chipIndex: PropTypes.number, - chipOptions: CHIP_OPTIONS.isRequired, - className: PropTypes.string, - editConfig: PropTypes.object, - handleEditChip: PropTypes.func, - handleIsEdit: PropTypes.func, - handleRemoveChip: PropTypes.func, - hiddenChips: PropTypes.bool, - isDeleteMode: PropTypes.bool, - isEditMode: PropTypes.bool, - onClick: PropTypes.func, - setChipsSizes: PropTypes.func, - setEditConfig: PropTypes.func, - setValidation: PropTypes.func, - shortChip: PropTypes.bool, - showChips: PropTypes.bool.isRequired, - textOverflowEllipsis: PropTypes.bool -} - -export default React.memo(Chip) diff --git a/src/common/Chip/Chip.stories.js b/src/common/Chip/Chip.stories.js deleted file mode 100644 index f28e0c1c38..0000000000 --- a/src/common/Chip/Chip.stories.js +++ /dev/null @@ -1,288 +0,0 @@ -/* -Copyright 2019 Iguazio Systems Ltd. - -Licensed under the Apache License, Version 2.0 (the "License") with -an addition restriction as set forth herein. You may not use this -file except in compliance with the License. You may obtain a copy of -the License at http://www.apache.org/licenses/LICENSE-2.0. - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -implied. See the License for the specific language governing -permissions and limitations under the License. - -In addition, you may not use the software for any purposes that are -illegal under applicable law, and the grant of the foregoing license -under the Apache 2.0 license is conditioned upon your compliance with -such restriction. -*/ -import React from 'react' - -import Chip from './Chip' - -export default { - title: 'Example/Chip', - component: Chip -} - -const commonArgs = { - chip: { value: 'Key: Value' }, - chipOptions: { - background: 'purple', - boldValue: false, - borderRadius: 'primary', - borderColor: 'transparent', - density: 'dense', - font: 'purple' - } -} - -const Template = args => - -export const LabelChip = Template.bind({}) -LabelChip.args = { - ...commonArgs, - chipOptions: { - background: 'purple', - boldValue: false, - borderRadius: 'primary', - borderColor: 'transparent', - density: 'dense', - font: 'purple' - } -} - -export const MetricsChip = Template.bind({}) -MetricsChip.args = { - ...commonArgs, - chipOptions: { - background: 'grey', - boldValue: false, - borderColor: 'transparent', - borderRadius: 'primary', - density: 'dense', - font: 'primary' - } -} - -export const ParametersChip = Template.bind({}) -ParametersChip.args = { - ...commonArgs, - chipOptions: { - background: 'orange', - boldValue: false, - borderColor: 'transparent', - borderRadius: 'primary', - density: 'dense', - font: 'orange' - } -} - -export const GreenChip = Template.bind({}) -GreenChip.args = { - ...commonArgs, - chipOptions: { - background: 'green', - boldValue: false, - borderColor: 'transparent', - borderRadius: 'primary', - density: 'dense', - font: 'green' - } -} - -export const DensePurpleChip = Template.bind({}) -DensePurpleChip.args = { - ...commonArgs, - chipOptions: { - background: 'purple', - boldValue: true, - borderRadius: 'primary', - borderColor: 'purple', - density: 'dense', - font: 'purple' - } -} - -export const DenseGreyChip = Template.bind({}) -DenseGreyChip.args = { - ...commonArgs, - chipOptions: { - background: 'grey', - boldValue: true, - borderColor: 'grey', - borderRadius: 'primary', - density: 'dense', - font: 'primary' - } -} - -export const DenseOrangeChip = Template.bind({}) -DenseOrangeChip.args = { - ...commonArgs, - chipOptions: { - background: 'orange', - boldValue: true, - borderColor: 'orange', - borderRadius: 'primary', - density: 'dense', - font: 'orange' - } -} - -export const DenseGreenChip = Template.bind({}) -DenseGreenChip.args = { - ...commonArgs, - chipOptions: { - background: 'green', - boldValue: true, - borderColor: 'green', - borderRadius: 'primary', - density: 'dense', - font: 'green' - } -} - -export const DenseAmethystChip = Template.bind({}) -DenseAmethystChip.args = { - ...commonArgs, - chipOptions: { - background: 'amethyst', - boldValue: false, - borderColor: 'transparent', - borderRadius: 'primary', - density: 'dense', - font: 'white' - } -} - -export const DenseJavaChip = Template.bind({}) -DenseJavaChip.args = { - ...commonArgs, - chipOptions: { - background: 'java', - boldValue: false, - borderColor: 'transparent', - borderRadius: 'primary', - density: 'dense', - font: 'white' - } -} - -export const DenseSorbusChip = Template.bind({}) -DenseSorbusChip.args = { - ...commonArgs, - chipOptions: { - background: 'sorbus', - boldValue: false, - borderColor: 'transparent', - borderRadius: 'primary', - density: 'dense', - font: 'white' - } -} - -export const LabelChipNormal = Template.bind({}) -LabelChipNormal.args = { - ...commonArgs, - chipOptions: { - background: 'none', - boldValue: false, - borderRadius: 'secondary', - borderColor: 'purple', - density: 'normal', - font: 'purple' - } -} - -export const MetricsChipNormal = Template.bind({}) -MetricsChipNormal.args = { - ...commonArgs, - chipOptions: { - background: 'none', - boldValue: false, - borderColor: 'grey', - borderRadius: 'secondary', - density: 'normal', - font: 'primary' - } -} - -export const ParametersChipNormal = Template.bind({}) -ParametersChipNormal.args = { - ...commonArgs, - chipOptions: { - background: 'none', - boldValue: false, - borderColor: 'orange', - borderRadius: 'secondary', - density: 'normal', - font: 'orange' - } -} - -export const GreenChipNormal = Template.bind({}) -GreenChipNormal.args = { - ...commonArgs, - chipOptions: { - background: 'none', - boldValue: false, - borderColor: 'green', - borderRadius: 'secondary', - density: 'normal', - font: 'green' - } -} - -export const LabelChipMedium = Template.bind({}) -LabelChipMedium.args = { - ...commonArgs, - chipOptions: { - background: 'purple', - boldValue: true, - borderRadius: 'secondary', - borderColor: 'purple', - density: 'medium', - font: 'purple' - } -} - -export const MetricsChipMedium = Template.bind({}) -MetricsChipMedium.args = { - ...commonArgs, - chipOptions: { - background: 'grey', - boldValue: true, - borderColor: 'grey', - borderRadius: 'secondary', - density: 'medium', - font: 'primary' - } -} - -export const ParametersChipMedium = Template.bind({}) -ParametersChipMedium.args = { - ...commonArgs, - chipOptions: { - background: 'orange', - boldValue: true, - borderColor: 'orange', - borderRadius: 'secondary', - density: 'medium', - font: 'orange' - } -} - -export const GreenChipMedium = Template.bind({}) -GreenChipMedium.args = { - ...commonArgs, - chipOptions: { - background: 'green', - boldValue: true, - borderColor: 'green', - borderRadius: 'secondary', - density: 'medium', - font: 'green' - } -} diff --git a/src/common/Chip/chip.scss b/src/common/Chip/chip.scss deleted file mode 100644 index bd6ea09937..0000000000 --- a/src/common/Chip/chip.scss +++ /dev/null @@ -1,80 +0,0 @@ -@use 'igz-controls/scss/variables'; -@use 'igz-controls/scss/colors'; -@use 'igz-controls/scss/borders'; -@use 'igz-controls/scss/mixins'; - -.chip { - position: relative; - margin: 2px 8px 2px 0; - padding: 4px 8px; - font-size: 14px; - line-height: 16px; - visibility: hidden; - cursor: default; - - &_visible { - visibility: visible; - } - - &__content { - display: flex; - align-items: center; - } - - &__delimiter { - display: flex; - align-items: center; - margin: 0 4px; - } - - &__label { - &_invalid { - color: colors.$amaranth; - } - } - - &__value { - min-width: 10px; - } - - &.editable { - cursor: pointer; - } - - &.chips_button { - padding: 8px 7px; - } - - .item-icon-close { - display: flex; - align-items: center; - justify-content: center; - margin-left: 5px; - padding: 0; - - svg { - transform: scale(0.7); - } - } - - &-background { - @include mixins.chipBackground(false); - } - - &-border { - @include mixins.chipBorder(); - } - - &-density { - @include mixins.chipDensity(false, false); - } - - &-font { - @include mixins.chipsFont(Chip); - } - - &-value_bold { - font-weight: 700; - font-size: 15px; - } -} diff --git a/src/common/ChipCell/ChipCell.jsx b/src/common/ChipCell/ChipCell.jsx deleted file mode 100644 index 9c613c1ef4..0000000000 --- a/src/common/ChipCell/ChipCell.jsx +++ /dev/null @@ -1,244 +0,0 @@ -/* -Copyright 2019 Iguazio Systems Ltd. - -Licensed under the Apache License, Version 2.0 (the "License") with -an addition restriction as set forth herein. You may not use this -file except in compliance with the License. You may obtain a copy of -the License at http://www.apache.org/licenses/LICENSE-2.0. - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -implied. See the License for the specific language governing -permissions and limitations under the License. - -In addition, you may not use the software for any purposes that are -illegal under applicable law, and the grant of the foregoing license -under the Apache 2.0 license is conditioned upon your compliance with -such restriction. -*/ -import React, { useState, useCallback, useMemo } from 'react' -import PropTypes from 'prop-types' - -import ChipCellView from './ChipCellView' - -import { CHIP_OPTIONS } from '../../types' -import { CLICK, TAB, TAB_SHIFT } from 'igz-controls/constants' -import { cutChips } from '../../utils/cutChips' -import { useChipCell } from 'igz-controls/hooks' - -const ChipCell = ({ - addChip = () => {}, - chipOptions = { - background: 'purple', - boldValue: false, - borderRadius: 'primary', - borderColor: 'transparent', - density: 'dense', - font: 'purple' - }, - className, - delimiter = null, - editChip = () => {}, - elements = [], - isEditMode = false, - onClick = () => {}, - removeChip = () => {}, - shortChips = false, - setValidation = null, - visibleChipsMaxLength = null -}) => { - const { - chipsCellRef, - chipsWrapperRef, - handleShowElements, - hiddenChipsCounterRef, - hiddenChipsPopUpRef, - setChipsSizes, - setShowHiddenChips, - showChips, - showHiddenChips, - visibleChipsCount - } = useChipCell(isEditMode, visibleChipsMaxLength) - const [editConfig, setEditConfig] = useState({ - chipIndex: null, - isEdit: false, - isKeyFocused: true, - isValueFocused: false, - isNewChip: false - }) - - let chips = useMemo(() => { - return (isEditMode && !visibleChipsMaxLength) || visibleChipsMaxLength === 'all' - ? { - visibleChips: elements.map(chip => ({ - value: chip, - delimiter - })) - } - : cutChips( - elements, - visibleChipsMaxLength ? visibleChipsMaxLength : visibleChipsCount, - delimiter - ) - }, [delimiter, elements, isEditMode, visibleChipsCount, visibleChipsMaxLength]) - - const handleAddNewChip = useCallback( - (event, chip) => { - event.preventDefault() - - if (!editConfig.isEdit && !editConfig.chipIndex) { - addChip(chip, elements) - } - - if (showHiddenChips) { - setShowHiddenChips(false) - } - - setEditConfig({ - chipIndex: elements.length, - isEdit: true, - isKeyFocused: true, - isValueFocused: false, - isNewChip: true - }) - }, - [ - editConfig.isEdit, - editConfig.chipIndex, - showHiddenChips, - elements, - addChip, - setShowHiddenChips - ] - ) - - const handleRemoveChip = useCallback( - (event, chipIndex) => { - event.stopPropagation() - - const newChips = elements.filter((value, index) => index !== chipIndex) - - removeChip(newChips) - }, - [elements, removeChip] - ) - - const handleEditChip = useCallback( - (event, chip, nameEvent) => { - event.preventDefault() - const isChipNotEmpty = !!(chip.key && chip.value && chip.key?.trim() && chip.value?.trim()) - - if (isChipNotEmpty) { - const newChips = [...elements] - newChips[editConfig.chipIndex] = `${chip.key}: ${chip.value}` - - editChip(newChips) - } - - if (nameEvent === CLICK) { - if (editConfig.isNewChip && !isChipNotEmpty) { - handleRemoveChip(event, editConfig.chipIndex) - } - - setEditConfig({ - chipIndex: null, - isEdit: false, - isKeyFocused: true, - isValueFocused: false, - isNewChip: false - }) - } else if (nameEvent === TAB) { - if (editConfig.isNewChip && !isChipNotEmpty) { - handleRemoveChip(event, editConfig.chipIndex) - } - - setEditConfig(prevState => { - const isNextChipIndexExists = prevState.chipIndex + 1 > elements.length - 1 - - return { - chipIndex: isNextChipIndexExists ? null : prevState.chipIndex + 1, - isEdit: !isNextChipIndexExists, - isKeyFocused: true, - isValueFocused: false, - isNewChip: false - } - }) - } else if (nameEvent === TAB_SHIFT) { - if (editConfig.isNewChip && !isChipNotEmpty) { - handleRemoveChip(event, editConfig.chipIndex) - } - - setEditConfig(prevState => { - const isPrevChipIndexExists = prevState.chipIndex - 1 < 0 - - return { - chipIndex: isPrevChipIndexExists ? null : prevState.chipIndex - 1, - isEdit: !isPrevChipIndexExists, - isKeyFocused: isPrevChipIndexExists, - isValueFocused: !isPrevChipIndexExists, - isNewChip: false - } - }) - } - }, - [elements, editConfig.chipIndex, editConfig.isNewChip, editChip, handleRemoveChip] - ) - - const handleIsEdit = useCallback( - (event, index) => { - if (isEditMode) { - event.stopPropagation() - - setEditConfig({ - chipIndex: index, - isEdit: true, - isKeyFocused: true, - isValueFocused: false - }) - } - - onClick && onClick() - }, - [isEditMode, onClick] - ) - - return ( - - ) -} - -ChipCell.propTypes = { - addChip: PropTypes.func, - chipOptions: CHIP_OPTIONS, - className: PropTypes.string, - delimiter: PropTypes.oneOfType([PropTypes.string, PropTypes.element]), - editChip: PropTypes.func, - elements: PropTypes.arrayOf(PropTypes.string), - isEditMode: PropTypes.bool, - onClick: PropTypes.func, - removeChip: PropTypes.func, - setValidation: PropTypes.func, - shortChips: PropTypes.bool, - visibleChipsMaxLength: PropTypes.oneOfType([PropTypes.string, PropTypes.number]) -} - -export default React.memo(ChipCell) diff --git a/src/common/ChipCell/ChipCellView.jsx b/src/common/ChipCell/ChipCellView.jsx deleted file mode 100644 index 0020e224d4..0000000000 --- a/src/common/ChipCell/ChipCellView.jsx +++ /dev/null @@ -1,148 +0,0 @@ -/* -Copyright 2019 Iguazio Systems Ltd. - -Licensed under the Apache License, Version 2.0 (the "License") with -an addition restriction as set forth herein. You may not use this -file except in compliance with the License. You may obtain a copy of -the License at http://www.apache.org/licenses/LICENSE-2.0. - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -implied. See the License for the specific language governing -permissions and limitations under the License. - -In addition, you may not use the software for any purposes that are -illegal under applicable law, and the grant of the foregoing license -under the Apache 2.0 license is conditioned upon your compliance with -such restriction. -*/ -import React from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' - -import Chip from '../Chip/Chip' -import ChipTooltip from './ChipTooltip/ChipTooltip' -import HiddenChipsBlock from './HiddenChipsBlock/HiddenChipsBlock' - -import { CHIP_OPTIONS, CHIPS } from '../../types' -import { isEveryObjectValueEmpty } from '../../utils/isEveryObjectValueEmpty' - -import Add from 'igz-controls/images/add.svg?react' - -import './chipCell.scss' - -const ChipCellView = React.forwardRef( - ( - { - chips = {}, - chipOptions, - className = '', - editConfig = {}, - handleAddNewChip = () => {}, - handleEditChip, - handleIsEdit = () => {}, - handleRemoveChip, - handleShowElements = () => {}, - isEditMode = false, - setChipsSizes = () => {}, - setEditConfig = () => {}, - setValidation = null, - shortChips, - showChips = false, - showHiddenChips - }, - { chipsCellRef, chipsWrapperRef, hiddenChipsCounterRef, hiddenChipsPopUpRef } - ) => { - const buttonAddClassNames = classnames( - 'button-add', - className, - chipOptions.background && `button-add-background_${chipOptions.background}`, - chipOptions.borderColor && `button-add-border_${chipOptions.borderColor}`, - chipOptions.font && `button-add-font_${chipOptions.font}`, - chipOptions.density && `button-add-density_${chipOptions.density}` - ) - const wrapperClassNames = classnames('chips-wrapper', isEditMode && 'fixed-max-width') - - return ( - (isEditMode || !isEveryObjectValueEmpty(chips)) && ( -
-
- {chips.visibleChips.map((chip, index) => { - return ( -
- - - - {chips.visibleChips.length - 1 === index && showHiddenChips && ( - - )} -
- ) - })} - {isEditMode && ( - - )} -
-
- ) - ) - } -) - -ChipCellView.displayName = 'ChipCellView' - -ChipCellView.propTypes = { - chips: PropTypes.shape({ visibleChips: CHIPS, hiddenChips: CHIPS }), - chipOptions: CHIP_OPTIONS.isRequired, - className: PropTypes.string, - editConfig: PropTypes.object, - handleAddNewChip: PropTypes.func, - handleEditChip: PropTypes.func, - handleIsEdit: PropTypes.func, - handleRemoveChip: PropTypes.func, - handleShowElements: PropTypes.func, - isEditMode: PropTypes.bool, - setChipsSizes: PropTypes.func, - setEditConfig: PropTypes.func, - setValidation: PropTypes.func, - shortChips: PropTypes.bool, - showChips: PropTypes.bool.isRequired, - showHiddenChips: PropTypes.bool.isRequired -} - -export default ChipCellView diff --git a/src/common/ChipCell/ChipTooltip/ChipTooltip.jsx b/src/common/ChipCell/ChipTooltip/ChipTooltip.jsx deleted file mode 100644 index f9d87e4ced..0000000000 --- a/src/common/ChipCell/ChipTooltip/ChipTooltip.jsx +++ /dev/null @@ -1,61 +0,0 @@ -/* -Copyright 2019 Iguazio Systems Ltd. - -Licensed under the Apache License, Version 2.0 (the "License") with -an addition restriction as set forth herein. You may not use this -file except in compliance with the License. You may obtain a copy of -the License at http://www.apache.org/licenses/LICENSE-2.0. - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -implied. See the License for the specific language governing -permissions and limitations under the License. - -In addition, you may not use the software for any purposes that are -illegal under applicable law, and the grant of the foregoing license -under the Apache 2.0 license is conditioned upon your compliance with -such restriction. -*/ -import React, { useMemo } from 'react' -import PropTypes from 'prop-types' - -import { Tooltip, TextTooltipTemplate } from 'igz-controls/components' - -import { getChipLabelAndValue } from '../../../utils/getChipLabelAndValue' -import { CHIP } from '../../../types' - -const ChipTooltip = ({ children, chip, editConfig = {} }) => { - const { chipLabel, chipValue } = useMemo(() => getChipLabelAndValue(chip), [chip]) - - return ( - - ) -} - -ChipTooltip.propTypes = { - children: PropTypes.node.isRequired, - chip: CHIP, - editConfig: PropTypes.object -} - -export default ChipTooltip diff --git a/src/common/ChipCell/HiddenChipsBlock/HiddenChipsBlock.jsx b/src/common/ChipCell/HiddenChipsBlock/HiddenChipsBlock.jsx deleted file mode 100644 index c87864e150..0000000000 --- a/src/common/ChipCell/HiddenChipsBlock/HiddenChipsBlock.jsx +++ /dev/null @@ -1,106 +0,0 @@ -/* -Copyright 2019 Iguazio Systems Ltd. - -Licensed under the Apache License, Version 2.0 (the "License") with -an addition restriction as set forth herein. You may not use this -file except in compliance with the License. You may obtain a copy of -the License at http://www.apache.org/licenses/LICENSE-2.0. - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -implied. See the License for the specific language governing -permissions and limitations under the License. - -In addition, you may not use the software for any purposes that are -illegal under applicable law, and the grant of the foregoing license -under the Apache 2.0 license is conditioned upon your compliance with -such restriction. -*/ -import React, { useEffect } from 'react' -import PropTypes from 'prop-types' -import { createPortal } from 'react-dom' - -import Chip from '../../Chip/Chip' -import ChipTooltip from '../ChipTooltip/ChipTooltip' - -import { CHIP_OPTIONS, CHIPS } from '../../../types' -import { useHiddenChipsBlock } from 'igz-controls/hooks' - -const HiddenChipsBlock = React.forwardRef( - ( - { - chips = [], - chipIndex = 0, - chipOptions, - className, - editConfig = {}, - handleEditChip, - handleIsEdit = () => {}, - handleRemoveChip, - handleShowElements, - isEditMode = false, - setEditConfig = () => {} - }, - { hiddenChipsCounterRef, hiddenChipsPopUpRef } - ) => { - const { hiddenChipsBlockClassNames } = useHiddenChipsBlock( - hiddenChipsCounterRef, - hiddenChipsPopUpRef - ) - - useEffect(() => { - if (chips.length === 0) { - handleShowElements() - } - }) - - return createPortal( -
-
- {chips?.map((element, index) => { - return ( - - - - ) - })} -
-
, - document.getElementById('overlay_container') - ) - } -) - -HiddenChipsBlock.displayName = 'HiddenChipsBlock' - -HiddenChipsBlock.propTypes = { - className: PropTypes.string, - chips: CHIPS, - chipOptions: CHIP_OPTIONS.isRequired, - chipIndex: PropTypes.number, - editConfig: PropTypes.object, - handleEditChip: PropTypes.func, - handleIsEdit: PropTypes.func, - handleRemoveChip: PropTypes.func, - handleShowElements: PropTypes.func.isRequired, - isEditMode: PropTypes.bool, - setEditConfig: PropTypes.func -} - -export default HiddenChipsBlock diff --git a/src/common/ChipCell/SizeChips.js b/src/common/ChipCell/SizeChips.js deleted file mode 100644 index 99a0b770ca..0000000000 --- a/src/common/ChipCell/SizeChips.js +++ /dev/null @@ -1,34 +0,0 @@ -/* -Copyright 2019 Iguazio Systems Ltd. - -Licensed under the Apache License, Version 2.0 (the "License") with -an addition restriction as set forth herein. You may not use this -file except in compliance with the License. You may obtain a copy of -the License at http://www.apache.org/licenses/LICENSE-2.0. - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -implied. See the License for the specific language governing -permissions and limitations under the License. - -In addition, you may not use the software for any purposes that are -illegal under applicable law, and the grant of the foregoing license -under the Apache 2.0 license is conditioned upon your compliance with -such restriction. -*/ -import { cutChips } from '../../utils/cutChips' - -export const sizeChips = { - 1000: (elements, delimiter) => cutChips(elements, 8, delimiter), - 900: (elements, delimiter) => cutChips(elements, 7, delimiter), - 800: (elements, delimiter) => cutChips(elements, 6, delimiter), - 700: (elements, delimiter) => cutChips(elements, 6, delimiter), - 600: (elements, delimiter) => cutChips(elements, 5, delimiter), - 500: (elements, delimiter) => cutChips(elements, 4, delimiter), - 400: (elements, delimiter) => cutChips(elements, 3, delimiter), - 300: (elements, delimiter) => cutChips(elements, 2, delimiter), - 200: (elements, delimiter) => cutChips(elements, 1, delimiter), - 100: (elements, delimiter) => cutChips(elements, 0, delimiter), - 0: (elements, delimiter) => cutChips(elements, 0, delimiter) -} diff --git a/src/common/ChipCell/chipCell.scss b/src/common/ChipCell/chipCell.scss deleted file mode 100644 index ae970f419b..0000000000 --- a/src/common/ChipCell/chipCell.scss +++ /dev/null @@ -1,53 +0,0 @@ -@use 'igz-controls/scss/colors'; -@use 'igz-controls/scss/borders'; -@use 'igz-controls/scss/mixins'; - -.chips { - &-wrapper { - display: flex; - align-items: center; - max-width: 100%; - } - - &-cell { - display: flex; - flex: 1; - align-items: center; - max-width: 100%; - - .fixed-max-width { - max-width: 100%; - } - - .chip { - &-block { - position: relative; - max-width: 100%; - } - } - - .button-add { - display: flex; - align-items: center; - justify-content: center; - margin: 2px 0 2px 0; - border-radius: 32px; - - &-background { - @include mixins.chipBackground(true); - } - - &_border { - @include mixins.chipBorder(); - } - - &-density { - @include mixins.chipDensity(false, true); - } - - &-font { - @include mixins.chipsFont(ButtonAddChip); - } - } - } -} diff --git a/src/common/ChipForm/ChipForm.jsx b/src/common/ChipForm/ChipForm.jsx deleted file mode 100644 index 47ce465c1c..0000000000 --- a/src/common/ChipForm/ChipForm.jsx +++ /dev/null @@ -1,290 +0,0 @@ -/* -Copyright 2019 Iguazio Systems Ltd. - -Licensed under the Apache License, Version 2.0 (the "License") with -an addition restriction as set forth herein. You may not use this -file except in compliance with the License. You may obtain a copy of -the License at http://www.apache.org/licenses/LICENSE-2.0. - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -implied. See the License for the specific language governing -permissions and limitations under the License. - -In addition, you may not use the software for any purposes that are -illegal under applicable law, and the grant of the foregoing license -under the Apache 2.0 license is conditioned upon your compliance with -such restriction. -*/ -import React, { useState, useCallback, useEffect, useLayoutEffect, useMemo, useRef } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import { isEmpty } from 'lodash' - -import { OptionsMenu, ValidationTemplate } from 'igz-controls/elements' - -import { TAB, TAB_SHIFT } from 'igz-controls/constants' -import { CHIP_OPTIONS } from '../../types' - -import './chipForm.scss' - -const ChipForm = React.forwardRef( - ( - { - checkValidation = null, - chipOptions, - className = '', - editConfig, - onChange, - setEditConfig, - validationRules = [], - value - }, - ref - ) => { - const [chip, setChip] = useState({ - ...value, - keyFieldWidth: 0, - valueFieldWidth: 0 - }) - const maxWidthInput = useMemo(() => { - return ref.current?.clientWidth - 50 - }, [ref]) - const { background, borderColor, density, font, borderRadius } = chipOptions - const minWidthInput = 25 - const minWidthValueInput = 35 - - const refInputKey = useRef() - const refInputValue = useRef() - const refInputContainer = useRef() - - const labelKeyClassName = classnames( - className, - !editConfig.isKeyFocused && 'item_edited', - !isEmpty(validationRules) && 'item_edited_invalid' - ) - const labelContainerClassName = classnames( - 'edit-chip-container', - background && `edit-chip-container-background_${background}`, - borderColor && `edit-chip-container-border_${borderColor}`, - font && `edit-chip-container-font_${font}`, - density && `edit-chip-container-density_${density}`, - borderRadius && `edit-chip-container-border_${borderRadius}`, - (editConfig.isEdit || editConfig.isNewChip) && 'edit-chip-container_edited' - ) - const labelValueClassName = classnames( - 'input-label-value', - !editConfig.isValueFocused && 'item_edited' - ) - - useLayoutEffect(() => { - if (!chip.keyFieldWidth && !chip.valueFieldWidth) { - const currentWidthKeyInput = refInputKey.current.scrollWidth + 1 - const currentWidthValueInput = refInputValue.current.scrollWidth + 1 - - if (chip.key && chip.value) { - setChip(prevState => ({ - ...prevState, - keyFieldWidth: - currentWidthKeyInput >= maxWidthInput ? maxWidthInput : currentWidthKeyInput, - valueFieldWidth: - currentWidthValueInput >= maxWidthInput ? maxWidthInput : currentWidthValueInput - })) - } else { - setChip(prevState => ({ - ...prevState, - keyFieldWidth: minWidthInput, - valueFieldWidth: minWidthValueInput - })) - } - } - }, [ - chip.key, - chip.keyFieldWidth, - chip.value, - chip.valueFieldWidth, - maxWidthInput, - refInputKey, - refInputValue - ]) - - useEffect(() => { - if (editConfig.isKeyFocused) { - refInputKey.current.focus() - } else if (editConfig.isValueFocused) { - refInputValue.current.focus() - } - }, [editConfig.isKeyFocused, editConfig.isValueFocused, refInputKey, refInputValue]) - - const outsideClick = useCallback( - event => { - event.stopPropagation() - const elementPath = event.path ?? event.composedPath?.() - - if (!elementPath.includes(refInputContainer.current)) { - onChange(event, chip, 'Click') - } - }, - [chip, onChange, refInputContainer] - ) - - useEffect(() => { - if (editConfig.isEdit) { - document.addEventListener('click', outsideClick, true) - - return () => { - document.removeEventListener('click', outsideClick, true) - } - } - }, [outsideClick, editConfig.isEdit]) - - const focusChip = useCallback( - event => { - event.stopPropagation() - - if (!event.shiftKey && event.key === TAB && editConfig.isValueFocused) { - onChange(event, chip, TAB) - } else if (event.shiftKey && event.key === TAB && editConfig.isKeyFocused) { - onChange(event, chip, TAB_SHIFT) - } - - if (event.key === 'Backspace' || event.key === 'Delete') { - setChip(prevState => ({ - ...prevState, - keyFieldWidth: editConfig.isKeyFocused ? minWidthInput : prevState.keyFieldWidth, - valueFieldWidth: editConfig.isValueFocused - ? minWidthValueInput - : prevState.valueFieldWidth - })) - } - }, - [editConfig, onChange, chip] - ) - - const handleOnFocus = useCallback( - event => { - if (event.target.name === 'key') { - refInputKey.current.selectionStart = refInputKey.current.selectionEnd - - setEditConfig(prevState => ({ - ...prevState, - isKeyFocused: true, - isValueFocused: false - })) - } else { - refInputValue.current.selectionStart = refInputValue.current.selectionEnd - - setEditConfig(prevState => ({ - ...prevState, - isKeyFocused: false, - isValueFocused: true - })) - } - }, - [refInputKey, refInputValue, setEditConfig] - ) - - const handleOnChange = useCallback( - event => { - event.preventDefault() - - if (event.target.name === 'key') { - const currentWidthKeyInput = refInputKey.current.scrollWidth - checkValidation && checkValidation(refInputKey.current.value) - - setChip(prevState => ({ - ...prevState, - key: refInputKey.current.value, - keyFieldWidth: - refInputKey.current.value.length <= 1 - ? minWidthInput - : currentWidthKeyInput >= maxWidthInput - ? maxWidthInput - : currentWidthKeyInput > minWidthInput - ? currentWidthKeyInput + 2 - : minWidthInput - })) - } else { - const currentWidthValueInput = refInputValue.current.scrollWidth - - setChip(prevState => ({ - ...prevState, - value: refInputValue.current.value, - valueFieldWidth: - refInputValue.current.value.length <= 1 - ? minWidthValueInput - : currentWidthValueInput >= maxWidthInput - ? maxWidthInput - : currentWidthValueInput > minWidthValueInput - ? currentWidthValueInput + 2 - : minWidthValueInput - })) - } - }, - [checkValidation, maxWidthInput, refInputKey, refInputValue] - ) - - const getValidationRules = useCallback(() => { - return validationRules.map(({ isValid = false, label, name }) => { - return - }) - }, [validationRules]) - - return ( - <> -
editConfig.isEdit && focusChip(event)} - > - -
:
- -
- {validationRules.length > 0 && ( - 0} ref={{ refInputContainer }}> - {getValidationRules()} - - )} - - ) - } -) - -ChipForm.displayName = 'ChipForm' - -ChipForm.propTypes = { - checkValidation: PropTypes.func, - chipOptions: CHIP_OPTIONS.isRequired, - className: PropTypes.string, - editConfig: PropTypes.object.isRequired, - onChange: PropTypes.func.isRequired, - setEditConfig: PropTypes.func.isRequired, - validationRules: PropTypes.array, - value: PropTypes.object.isRequired -} - -export default ChipForm diff --git a/src/common/ChipForm/chipForm.scss b/src/common/ChipForm/chipForm.scss deleted file mode 100644 index 5cd3267412..0000000000 --- a/src/common/ChipForm/chipForm.scss +++ /dev/null @@ -1,66 +0,0 @@ -@use 'igz-controls/scss/colors'; -@use 'igz-controls/scss/borders'; -@use 'igz-controls/scss/mixins'; - -.edit-chip { - &-container { - display: inline-flex; - max-width: 100%; - margin: 2px 8px 2px 0; - padding: 0 8px; - font-size: 14px; - line-height: 22px; - - input { - display: flex; - padding: 0; - font-size: 14px; - background-color: transparent; - border: none; - - &.item_edited { - &::placeholder { - color: colors.$spunPearl; - } - - &_invalid { - color: colors.$amaranth; - } - } - - &::placeholder { - color: colors.$primary; - } - } - - &-background { - @include mixins.chipBackground(false); - } - - &-border { - @include mixins.chipBorder(); - } - - &-density { - @include mixins.chipDensity(true, false); - } - - &-font { - @include mixins.chipsFont(EditableChip); - } - } - - &-separator { - margin-right: 5px; - } - - &__icon-close { - display: flex; - align-items: center; - justify-content: center; - - svg { - transform: scale(0.7); - } - } -} diff --git a/src/common/ChipInput/ChipInput.jsx b/src/common/ChipInput/ChipInput.jsx index a432eca53a..f731d5e550 100644 --- a/src/common/ChipInput/ChipInput.jsx +++ b/src/common/ChipInput/ChipInput.jsx @@ -21,10 +21,9 @@ import React, { useCallback, useEffect, useRef, useState } from 'react' import PropTypes from 'prop-types' import classnames from 'classnames' -import Chip from '../Chip/Chip' - -import { deleteUnsafeHtml } from '../../utils' -import { CHIP_INPUT_LIST, CHIP_OPTIONS } from '../../types' +import { Chip } from 'igz-controls/components' +import { deleteUnsafeHtml } from 'igz-controls/utils/string.util' +import { CHIP_INPUT_LIST, CHIP_OPTIONS } from 'igz-controls/types' import './chipInput.scss' diff --git a/src/common/ChipInput/chipInput.scss b/src/common/ChipInput/chipInput.scss index 564960b6b2..b467c79301 100644 --- a/src/common/ChipInput/chipInput.scss +++ b/src/common/ChipInput/chipInput.scss @@ -19,11 +19,11 @@ left: 0; z-index: 5; width: 100%; + max-height: 200px; + overflow-y: auto; background-color: colors.$white; border: borders.$primaryBorder; border-radius: variables.$mainBorderRadius; - max-height: 200px; - overflow-y: auto; .suggestion-row { display: flex; diff --git a/src/common/CodeBlock/Button.stories.js b/src/common/CodeBlock/CodeBlock.stories.jsx similarity index 96% rename from src/common/CodeBlock/Button.stories.js rename to src/common/CodeBlock/CodeBlock.stories.jsx index b976ff22e6..586dd32928 100644 --- a/src/common/CodeBlock/Button.stories.js +++ b/src/common/CodeBlock/CodeBlock.stories.jsx @@ -21,6 +21,8 @@ import React from 'react' import CodeBlock from './CodeBlock' +import 'prismjs/components/prism-json' + export default { title: 'Example/CodeBlock', component: CodeBlock diff --git a/src/common/CodeBlock/codeBlock.scss b/src/common/CodeBlock/codeBlock.scss index 20f43fb612..2595b8e4d3 100644 --- a/src/common/CodeBlock/codeBlock.scss +++ b/src/common/CodeBlock/codeBlock.scss @@ -5,10 +5,10 @@ .code-block { width: 100%; height: 200px; + padding: 18px 16px; overflow: auto; border: borders.$primaryBorder; border-radius: variables.$mainBorderRadius; - padding: 18px 16px; &__label { margin-bottom: 5px; diff --git a/src/common/Combobox/combobox.scss b/src/common/Combobox/combobox.scss index c5540b2cc9..48622ec1c2 100644 --- a/src/common/Combobox/combobox.scss +++ b/src/common/Combobox/combobox.scss @@ -12,8 +12,8 @@ border-radius: 4px; &_disabled { - cursor: not-allowed; border-color: colors.$spunPearl; + cursor: not-allowed; } &_invalid { @@ -22,10 +22,10 @@ &-list { min-width: 140px; - margin: 0; - list-style-type: none; max-height: 300px; + margin: 0; overflow: auto; + list-style-type: none; &__option { padding: 8px 15px; @@ -90,8 +90,8 @@ top: 100%; z-index: 5; display: none; - margin-top: 5px; max-width: 220px; + margin-top: 5px; background-color: colors.$white; box-shadow: shadows.$previewBoxShadow; @@ -167,8 +167,8 @@ } &:disabled { - background-color: transparent; color: colors.$spunPearl; + background-color: transparent; } } diff --git a/src/common/CopyToClipboard/CopyToClipboard.jsx b/src/common/CopyToClipboard/CopyToClipboard.jsx deleted file mode 100644 index 95ec2ee0e8..0000000000 --- a/src/common/CopyToClipboard/CopyToClipboard.jsx +++ /dev/null @@ -1,85 +0,0 @@ -/* -Copyright 2019 Iguazio Systems Ltd. - -Licensed under the Apache License, Version 2.0 (the "License") with -an addition restriction as set forth herein. You may not use this -file except in compliance with the License. You may obtain a copy of -the License at http://www.apache.org/licenses/LICENSE-2.0. - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -implied. See the License for the specific language governing -permissions and limitations under the License. - -In addition, you may not use the software for any purposes that are -illegal under applicable law, and the grant of the foregoing license -under the Apache 2.0 license is conditioned upon your compliance with -such restriction. -*/ -import PropTypes from 'prop-types' -import { useMemo } from 'react' -import { useDispatch } from 'react-redux' - -import { Tooltip, TextTooltipTemplate, RoundedIcon } from 'igz-controls/components' - -import { setNotification } from '../../reducers/notificationReducer' -import { showErrorNotification } from '../../utils/notifications.util' - -import Copy from 'igz-controls/images/copy-to-clipboard-icon.svg?react' - -const CopyToClipboard = ({ - children = null, - className = '', - disabled = false, - textToCopy = '', - tooltipText -}) => { - const dispatch = useDispatch() - const copyIsDisabled = useMemo(() => disabled || !textToCopy, [disabled, textToCopy]) - - const copyToClipboard = textToCopy => { - navigator.clipboard - .writeText(textToCopy) - .then(() => { - dispatch( - setNotification({ - status: 200, - id: Math.random(), - message: 'Copied to clipboard successfully' - }) - ) - }) - .catch(error => { - showErrorNotification(dispatch, error, '', 'Copy to clipboard failed') - }) - } - - return ( -
- {children ? ( - } textShow> - copyToClipboard(textToCopy)}>{children} - - ) : ( - copyToClipboard(textToCopy)} - disabled={copyIsDisabled} - > - - - )} -
- ) -} - -CopyToClipboard.propTypes = { - children: PropTypes.string, - className: PropTypes.string, - disabled: PropTypes.bool, - textToCopy: PropTypes.string, - tooltipText: PropTypes.string.isRequired -} - -export default CopyToClipboard diff --git a/src/common/DatePicker/DatePicker.jsx b/src/common/DatePicker/DatePicker.jsx index 8dd8806962..70e2a9d874 100644 --- a/src/common/DatePicker/DatePicker.jsx +++ b/src/common/DatePicker/DatePicker.jsx @@ -116,8 +116,7 @@ const DatePicker = ({ ).filter( option => option.timeFrameMilliseconds <= timeFrameLimit && - (!excludeCustomRange || - option.id !== CUSTOM_RANGE_DATE_OPTION) + (!excludeCustomRange || option.id !== CUSTOM_RANGE_DATE_OPTION) ) }, [customOptions, excludeCustomRange, hasFutureOptions, timeFrameLimit]) @@ -205,6 +204,8 @@ const DatePicker = ({ const validateTimeRange = useCallback( ([dateFrom, dateTo]) => { + const timeFrameLimitRoundedUp = + timeFrameLimit === Infinity ? Infinity : roundSeconds(timeFrameLimit, true).getTime() let timeRangeInvalidMessage = '' let isTimeRangeInvalid = false let timeRangeIsNegative = false @@ -214,12 +215,12 @@ const DatePicker = ({ timeRangeInvalidMessage = '“To” must be later than “From”' timeRangeIsNegative = true isTimeRangeInvalid = true - } else if (dateTo.getTime() - dateFrom.getTime() > timeFrameLimit) { + } else if (dateTo.getTime() - dateFrom.getTime() > timeFrameLimitRoundedUp) { timeRangeInvalidMessage = getTimeFrameWarningMsg(timeFrameLimit) isTimeRangeInvalid = true } } else if (!isRange && dateFrom) { - if (Date.now() - dateFrom.getTime() > timeFrameLimit) { + if (Date.now() - dateFrom.getTime() > timeFrameLimitRoundedUp) { timeRangeInvalidMessage = getTimeFrameWarningMsg(timeFrameLimit) isTimeRangeInvalid = true } @@ -307,7 +308,7 @@ const DatePicker = ({ payload: new Date( datePickerState[configId].visibleDate.getFullYear(), datePickerState[configId].visibleDate.getMonth() + 1, - datePickerState[configId].visibleDate.getDate() + 1 ) }) } @@ -320,7 +321,7 @@ const DatePicker = ({ payload: new Date( datePickerState[configId].visibleDate.getFullYear(), datePickerState[configId].visibleDate.getMonth() - 1, - datePickerState[configId].visibleDate.getDate() + 1 ) }) } diff --git a/src/common/DatePicker/DatePicker.stories.js b/src/common/DatePicker/DatePicker.stories.jsx similarity index 100% rename from src/common/DatePicker/DatePicker.stories.js rename to src/common/DatePicker/DatePicker.stories.jsx diff --git a/src/common/DatePicker/DatePickerView.jsx b/src/common/DatePicker/DatePickerView.jsx index 2579a9a203..663151720c 100644 --- a/src/common/DatePicker/DatePickerView.jsx +++ b/src/common/DatePicker/DatePickerView.jsx @@ -23,9 +23,15 @@ import MaskedInput from 'react-text-mask' import classnames from 'classnames' import { isEmpty } from 'lodash' -import ErrorMessage from '../ErrorMessage/ErrorMessage' import TimePicker from '../TimePicker/TimePicker' -import { Button, Tip, Tooltip, TextTooltipTemplate, PopUpDialog } from 'igz-controls/components' +import { + Button, + Tip, + Tooltip, + TextTooltipTemplate, + PopUpDialog, + ErrorMessage +} from 'igz-controls/components' import { SelectOption } from 'igz-controls/elements' import { PRIMARY_BUTTON } from 'igz-controls/constants' @@ -98,13 +104,10 @@ const DatePickerView = React.forwardRef( isInputInvalid && 'input_invalid' ) const inputLabelClassNames = classnames('input__label', label && 'active-label') + const { datePickerRef, datePickerViewRef } = ref return ( -
+
-
+
{datePickerOptions.map(option => ( -
+
{config.map(item => (
diff --git a/src/common/Download/DownloadContainer.jsx b/src/common/Download/DownloadContainer.jsx index 171db576a8..61cbb5594c 100644 --- a/src/common/Download/DownloadContainer.jsx +++ b/src/common/Download/DownloadContainer.jsx @@ -74,8 +74,8 @@ const DownloadContainer = () => {
- {downloadStore.downloadList.map((downloadItem, index) => { - return + {downloadStore.downloadList.map((downloadItem) => { + return })}
diff --git a/src/common/Download/DownloadItem.jsx b/src/common/Download/DownloadItem.jsx index 7b02b79581..e5b89d3cfa 100644 --- a/src/common/Download/DownloadItem.jsx +++ b/src/common/Download/DownloadItem.jsx @@ -180,7 +180,11 @@ const DownloadItem = ({ downloadItem }) => { return (
- }> + } + > {file}
diff --git a/src/common/Download/downloadContainer.scss b/src/common/Download/downloadContainer.scss index 365f2af2c9..f1e8093ff8 100644 --- a/src/common/Download/downloadContainer.scss +++ b/src/common/Download/downloadContainer.scss @@ -1,21 +1,25 @@ @use 'igz-controls/scss/colors'; @use 'igz-controls/scss/shadows'; +.tooltip.download-item__filename-tooltip { + z-index: 10; +} + .download-container { position: relative; z-index: 10; align-self: flex-end; - opacity: 0; width: 220px; min-height: 90px; max-height: 200px; + margin-right: 24px; + margin-bottom: 10px; padding: 15px; color: colors.$white; background-color: colors.$darkPurple; border-radius: 5px; box-shadow: shadows.$tooltipShadow; - margin-right: 24px; - margin-bottom: 10px; + opacity: 0; &__header { margin-bottom: 15px; @@ -25,7 +29,8 @@ display: flex; flex-direction: column; max-height: 140px; - overflow-y: scroll; + overflow-x: hidden; + overflow-y: auto; .download-item { display: flex; @@ -48,8 +53,12 @@ } } + &__status { + margin-left: auto; + } + &__buttons { - min-width: 20px; + min-width: 10px; .round-icon-cp__circle { width: 20px; diff --git a/src/common/ErrorMessage/ErrorMessage.jsx b/src/common/ErrorMessage/ErrorMessage.jsx deleted file mode 100644 index 0cab05011c..0000000000 --- a/src/common/ErrorMessage/ErrorMessage.jsx +++ /dev/null @@ -1,55 +0,0 @@ -/* -Copyright 2019 Iguazio Systems Ltd. - -Licensed under the Apache License, Version 2.0 (the "License") with -an addition restriction as set forth herein. You may not use this -file except in compliance with the License. You may obtain a copy of -the License at http://www.apache.org/licenses/LICENSE-2.0. - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -implied. See the License for the specific language governing -permissions and limitations under the License. - -In addition, you may not use the software for any purposes that are -illegal under applicable law, and the grant of the foregoing license -under the Apache 2.0 license is conditioned upon your compliance with -such restriction. -*/ -import React from 'react' -import PropTypes from 'prop-types' - -import { Tooltip, TextTooltipTemplate } from 'igz-controls/components' - -import UnsuccessAlert from 'igz-controls/images/unsuccess_alert.svg?react' -import Close from 'igz-controls/images/close.svg?react' - -import './errorMessage.scss' - -const ErrorMessage = ({ closeError = null, message }) => { - return ( -
-
-
- -
-
{message}
-
- {closeError && ( - - )} -
- ) -} - -ErrorMessage.propTypes = { - closeError: PropTypes.func, - message: PropTypes.string.isRequired -} - -export default ErrorMessage diff --git a/src/common/ErrorMessage/ErrorMessage.test.js b/src/common/ErrorMessage/ErrorMessage.test.js deleted file mode 100644 index 376a8756c0..0000000000 --- a/src/common/ErrorMessage/ErrorMessage.test.js +++ /dev/null @@ -1,61 +0,0 @@ -/* -Copyright 2019 Iguazio Systems Ltd. - -Licensed under the Apache License, Version 2.0 (the "License") with -an addition restriction as set forth herein. You may not use this -file except in compliance with the License. You may obtain a copy of -the License at http://www.apache.org/licenses/LICENSE-2.0. - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -implied. See the License for the specific language governing -permissions and limitations under the License. - -In addition, you may not use the software for any purposes that are -illegal under applicable law, and the grant of the foregoing license -under the Apache 2.0 license is conditioned upon your compliance with -such restriction. -*/ -import { cleanup, fireEvent, render } from '@testing-library/react' -import React from 'react' -import ErrorMessage from './ErrorMessage' - -jest.mock('igz-controls/images/unsuccess_alert.svg', () => ({ - ReactComponent: 'unsuccess_alert-icon' -})) - -jest.mock('igz-controls/images/close.svg', () => ({ - ReactComponent: 'close-icon' -})) - -describe('ErrorMessage component', () => { - let wrapper - let mockCloseError = jest.fn() - - beforeEach(() => { - const props = { - message: 'Something went wrong', - closeError: mockCloseError - } - wrapper = render() - }) - - afterEach(cleanup) - - it('renders without crashing', () => { - expect(wrapper.queryByTestId('error-message')).not.toBeNull() - }) - - it('should display message if it not empty', () => { - const message = wrapper.getByText(/Something went wrong/i) - expect(message.textContent).toEqual('Something went wrong') - }) - - it('should call "closeError" handler', () => { - const closeIcon = wrapper.queryByTestId('close') - fireEvent.click(closeIcon) - - expect(mockCloseError).toHaveBeenCalled() - }) -}) diff --git a/src/common/ErrorMessage/errorMessage.scss b/src/common/ErrorMessage/errorMessage.scss deleted file mode 100644 index d7aca13451..0000000000 --- a/src/common/ErrorMessage/errorMessage.scss +++ /dev/null @@ -1,30 +0,0 @@ -@use 'igz-controls/scss/borders'; -@use 'igz-controls/scss/colors'; - -.error { - display: flex; - justify-content: space-between; - padding: 10px 14px; - color: colors.$amaranth; - background-color: rgba(colors.$amaranth, 0.1); - border: borders.$errorBorder; - - &__data { - display: flex; - align-items: center; - } - - &__message { - margin-right: 10px; - word-break: break-word; - } - - &__icon { - width: 22px; - height: 22px; - margin-right: 10px; - padding: 5px; - background-color: colors.$burntSienna; - border-radius: 50%; - } -} diff --git a/src/common/ExpandableText/ExpandableText.jsx b/src/common/ExpandableText/ExpandableText.jsx new file mode 100644 index 0000000000..fce738e0ae --- /dev/null +++ b/src/common/ExpandableText/ExpandableText.jsx @@ -0,0 +1,92 @@ +/* +Copyright 2019 Iguazio Systems Ltd. + +Licensed under the Apache License, Version 2.0 (the "License") with +an addition restriction as set forth herein. You may not use this +file except in compliance with the License. You may obtain a copy of +the License at http://www.apache.org/licenses/LICENSE-2.0. + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +In addition, you may not use the software for any purposes that are +illegal under applicable law, and the grant of the foregoing license +under the Apache 2.0 license is conditioned upon your compliance with +such restriction. +*/ +import { useState, useRef, useEffect, useContext } from 'react' +import PropTypes from 'prop-types' + +import './expandableText.scss' + +const ExpandableText = ({ + children, + context = null, + collapsedHeight = 95, + forceExpand = false +}) => { + const [expanded, setExpanded] = useState(false) + const [isOverflowing, setIsOverflowing] = useState(false) + const contentRef = useRef(null) + const { contextForceExpand } = useContext(context) + + useEffect(() => { + if (forceExpand || contextForceExpand) { + queueMicrotask(() => { + setExpanded(forceExpand || contextForceExpand) + }) + } + }, [contextForceExpand, forceExpand]) + + useEffect(() => { + const element = contentRef.current + + if (element) { + setIsOverflowing(element.scrollHeight > collapsedHeight + 1) + } + }, [children, collapsedHeight]) + + return ( +
+
+ {children} +
+ {!expanded && isOverflowing && ( + <> +
+
+ ... + +
+ + )} + {expanded && isOverflowing && ( +
+ +
+ )} +
+ ) +} + +ExpandableText.propTypes = { + children: PropTypes.node.isRequired, + context: PropTypes.object, + collapsedHeight: PropTypes.number, + forceExpand: PropTypes.bool +} + +export default ExpandableText diff --git a/src/common/ExpandableText/expandableText.scss b/src/common/ExpandableText/expandableText.scss new file mode 100644 index 0000000000..4b29b9fb39 --- /dev/null +++ b/src/common/ExpandableText/expandableText.scss @@ -0,0 +1,54 @@ +@use 'igz-controls/scss/colors'; + +.expandable-wrapper { + position: relative; +} + +.expandable-text { + position: relative; + display: block; + overflow: hidden; + transition: max-height 0.3s ease; +} + +.fade-overlay { + position: absolute; + right: 0; + bottom: 0; + left: 0; + height: 40px; + background: linear-gradient(to bottom, rgb(255 255 255 / 0%), #fff); + content: ''; + pointer-events: none; +} + +.see-more-button-overlay { + position: absolute; + right: 0; + bottom: 4px; + display: flex; + gap: 4px; + align-items: center; + padding-left: 8px; + background: white; +} + +.dots { + color: colors.$doveGrayTwo; + font-weight: bold; +} + +.see-more-button, +.see-less-button { + padding: 0; + color: colors.$cornflowerBlue; + font-size: 14px; + background: none; + border: none; + cursor: pointer; +} + +.see-less-container { + margin-top: 4px; + text-align: right; +} diff --git a/src/common/HistoryBackLink/historyBackLink.jsx b/src/common/HistoryBackLink/historyBackLink.jsx index de62891317..c48e2358de 100644 --- a/src/common/HistoryBackLink/historyBackLink.jsx +++ b/src/common/HistoryBackLink/historyBackLink.jsx @@ -28,7 +28,7 @@ import HistoryIcon from 'igz-controls/images/history.svg?react' import './historyBackLink.scss' -const HistoryBackLink = ({ itemName, link }) => { +const HistoryBackLink = ({ itemName, link, customText = '', customIcon = null }) => { return (
@@ -37,9 +37,9 @@ const HistoryBackLink = ({ itemName, link }) => {
- + {customIcon ? customIcon : }
- Version history:{' '} + {`${customText || 'Version history'}: `}
}>{itemName}
@@ -48,6 +48,8 @@ const HistoryBackLink = ({ itemName, link }) => { } HistoryBackLink.propTypes = { + customIcon: PropTypes.element, + customText: PropTypes.string, itemName: PropTypes.string.isRequired, link: PropTypes.string.isRequired } diff --git a/src/common/Input/Input.jsx b/src/common/Input/Input.jsx index 639da14141..4566217434 100644 --- a/src/common/Input/Input.jsx +++ b/src/common/Input/Input.jsx @@ -27,7 +27,7 @@ import { OptionsMenu, ValidationTemplate } from 'igz-controls/elements' import { Tip, Tooltip, TextTooltipTemplate } from 'igz-controls/components' import { checkPatternsValidity } from 'igz-controls/utils/validation.util' import { useDetectOutsideClick } from 'igz-controls/hooks' -import { DENSITY_OPTIONS } from '../../types' +import { DENSITY_OPTIONS } from 'igz-controls/types' import ExclamationMarkIcon from 'igz-controls/images/exclamation-mark.svg?react' import WarningIcon from 'igz-controls/images/warning.svg?react' diff --git a/src/common/Input/Input.stories.js b/src/common/Input/Input.stories.jsx similarity index 92% rename from src/common/Input/Input.stories.js rename to src/common/Input/Input.stories.jsx index 081e5ce056..8fdcc35de3 100644 --- a/src/common/Input/Input.stories.js +++ b/src/common/Input/Input.stories.jsx @@ -98,8 +98,8 @@ ChunkyMandatory.args = { requiredText: 'Field is required' } -export const withValidationRules = Template.bind({}) -withValidationRules.args = { +export const WithValidationRules = Template.bind({}) +WithValidationRules.args = { ...commonArgs, density: 'chunky', invalid: true, @@ -110,8 +110,8 @@ withValidationRules.args = { value: ' test#2!' } -export const withStaticLink = Template.bind({}) -withStaticLink.args = { +export const WithStaticLink = Template.bind({}) +WithStaticLink.args = { ...commonArgs, label: 'label with static link', link: { @@ -121,9 +121,9 @@ withStaticLink.args = { value: 'test' } -export const withDynamicLink = Template.bind({}) +export const WithDynamicLink = Template.bind({}) const value = 'some text' -withDynamicLink.args = { +WithDynamicLink.args = { ...commonArgs, label: 'label with dynamic link', link: { diff --git a/src/common/Input/input.scss b/src/common/Input/input.scss index b167982abf..85380f874e 100644 --- a/src/common/Input/input.scss +++ b/src/common/Input/input.scss @@ -50,10 +50,10 @@ } &__warning { - z-index: 2; position: absolute; top: 50%; right: 10px; + z-index: 2; display: block; transform: translateY(-45%); cursor: pointer; @@ -139,8 +139,8 @@ } &-mandatory { - color: colors.$amaranth; margin-left: 2px; + color: colors.$amaranth; &_disabled { color: colors.$spunPearl; diff --git a/src/common/LoadButton/LoadButton.jsx b/src/common/LoadButton/LoadButton.jsx deleted file mode 100644 index ab3491d72e..0000000000 --- a/src/common/LoadButton/LoadButton.jsx +++ /dev/null @@ -1,48 +0,0 @@ -/* -Copyright 2019 Iguazio Systems Ltd. - -Licensed under the Apache License, Version 2.0 (the "License") with -an addition restriction as set forth herein. You may not use this -file except in compliance with the License. You may obtain a copy of -the License at http://www.apache.org/licenses/LICENSE-2.0. - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -implied. See the License for the specific language governing -permissions and limitations under the License. - -In addition, you may not use the software for any purposes that are -illegal under applicable law, and the grant of the foregoing license -under the Apache 2.0 license is conditioned upon your compliance with -such restriction. -*/ -import React from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { PRIMARY_BUTTON, SECONDARY_BUTTON, TERTIARY_BUTTON } from 'igz-controls/constants' - -import './loadButton.scss' - -const LoadButton = React.forwardRef( - ({ className = '', label = 'Load button', variant = TERTIARY_BUTTON, ...restProps }, ref) => { - const buttonClassName = classNames('btn-load', `btn-load-${variant}`, className) - - return ( - - ) - } -) - -LoadButton.displayName = 'LoadButton' - -LoadButton.propTypes = { - className: PropTypes.string, - label: PropTypes.oneOfType([PropTypes.string, PropTypes.element]), - variant: PropTypes.PropTypes.oneOf([PRIMARY_BUTTON, SECONDARY_BUTTON, TERTIARY_BUTTON]).isRequired -} - -export default LoadButton diff --git a/src/common/LoadButton/LoadButton.stories.js b/src/common/LoadButton/LoadButton.stories.js deleted file mode 100644 index ed3b1cc244..0000000000 --- a/src/common/LoadButton/LoadButton.stories.js +++ /dev/null @@ -1,56 +0,0 @@ -/* -Copyright 2019 Iguazio Systems Ltd. - -Licensed under the Apache License, Version 2.0 (the "License") with -an addition restriction as set forth herein. You may not use this -file except in compliance with the License. You may obtain a copy of -the License at http://www.apache.org/licenses/LICENSE-2.0. - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -implied. See the License for the specific language governing -permissions and limitations under the License. - -In addition, you may not use the software for any purposes that are -illegal under applicable law, and the grant of the foregoing license -under the Apache 2.0 license is conditioned upon your compliance with -such restriction. -*/ -import React from 'react' - -import LoadButton from './LoadButton' - -import { PRIMARY_BUTTON, SECONDARY_BUTTON, TERTIARY_BUTTON } from 'igz-controls/constants' - -export default { - title: 'Example/LoadButton', - component: LoadButton -} - -const commonArgs = { - disabled: false -} - -const Template = args => - -export const PrimaryLoader = Template.bind({}) -PrimaryLoader.args = { - ...commonArgs, - label: 'Primary loader', - variant: PRIMARY_BUTTON -} - -export const SecondaryLoader = Template.bind({}) -SecondaryLoader.args = { - ...commonArgs, - label: 'Secondary loader', - variant: SECONDARY_BUTTON -} - -export const TertiaryLoader = Template.bind({}) -TertiaryLoader.args = { - ...commonArgs, - label: 'Tertiary loader', - variant: TERTIARY_BUTTON -} diff --git a/src/common/LoadButton/loadButton.scss b/src/common/LoadButton/loadButton.scss deleted file mode 100644 index c0f8c0d3ba..0000000000 --- a/src/common/LoadButton/loadButton.scss +++ /dev/null @@ -1,80 +0,0 @@ -@use 'igz-controls/scss/variables'; -@use 'igz-controls/scss/colors'; -@use 'igz-controls/scss/borders'; - -.btn-load { - display: flex; - align-items: center; - justify-content: center; - min-width: 90px; - height: 40px; - padding: 0 16px; - color: colors.$primary; - font-weight: 500; - font-size: 14px; - font-style: normal; - line-height: 16px; - background: colors.$white; - border: borders.$primaryBorder; - border-radius: variables.$mainBorderRadius; - - svg { - path { - fill: colors.$white; - } - } - - &:active { - background: colors.$gallery; - } - - &:hover { - background: colors.$alabaster; - } - - &:disabled { - color: colors.$spunPearl; - background: colors.$white; - cursor: not-allowed; - - svg { - path { - fill: colors.$alto; - } - } - } - - :first-child { - margin-right: 5px; - } - - &-primary { - border-bottom: borders.$applyBtnBorder; - - &:disabled { - border-bottom: 4px solid colors.$hummingBird; - } - } - - &-secondary { - border-bottom: 4px solid colors.$malibu; - - &:disabled { - border-bottom: 4px solid colors.$titanWhite; - } - } - - &-tertiary { - border-bottom: 4px solid colors.$spunPearl; - - svg { - path { - fill: colors.$primary; - } - } - - &:disabled { - border-bottom: 4px solid colors.$athensGray; - } - } -} diff --git a/src/common/Loader/Loader.jsx b/src/common/Loader/Loader.jsx deleted file mode 100644 index 32cf9dcfbb..0000000000 --- a/src/common/Loader/Loader.jsx +++ /dev/null @@ -1,47 +0,0 @@ -/* -Copyright 2019 Iguazio Systems Ltd. - -Licensed under the Apache License, Version 2.0 (the "License") with -an addition restriction as set forth herein. You may not use this -file except in compliance with the License. You may obtain a copy of -the License at http://www.apache.org/licenses/LICENSE-2.0. - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -implied. See the License for the specific language governing -permissions and limitations under the License. - -In addition, you may not use the software for any purposes that are -illegal under applicable law, and the grant of the foregoing license -under the Apache 2.0 license is conditioned upon your compliance with -such restriction. -*/ -import React from 'react' -import classnames from 'classnames' -import PropTypes from 'prop-types' - -import './loader.scss' - -const Loader = ({ secondary = false, section = false, small = false }) => { - const wrapperClassNames = classnames( - 'loader-wrapper', - section && 'section-loader', - small && 'small-loader', - secondary && 'secondary-loader' - ) - - return ( -
-
-
- ) -} - -Loader.propTypes = { - secondary: PropTypes.bool, - section: PropTypes.bool, - small: PropTypes.bool -} - -export default React.memo(Loader) diff --git a/src/common/Loader/LoaderForSuspenseFallback.jsx b/src/common/Loader/LoaderForSuspenseFallback.jsx deleted file mode 100644 index 9e5511e80f..0000000000 --- a/src/common/Loader/LoaderForSuspenseFallback.jsx +++ /dev/null @@ -1,38 +0,0 @@ -/* -Copyright 2019 Iguazio Systems Ltd. - -Licensed under the Apache License, Version 2.0 (the "License") with -an addition restriction as set forth herein. You may not use this -file except in compliance with the License. You may obtain a copy of -the License at http://www.apache.org/licenses/LICENSE-2.0. - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -implied. See the License for the specific language governing -permissions and limitations under the License. - -In addition, you may not use the software for any purposes that are -illegal under applicable law, and the grant of the foregoing license -under the Apache 2.0 license is conditioned upon your compliance with -such restriction. -*/ -import React, { useLayoutEffect } from 'react' -import Loader from './Loader' - -const LoaderForSuspenseFallback = () => { - useLayoutEffect(() => { - const overlayContainer = document.getElementById('overlay_container') - const savedVisibilityStyle = overlayContainer ? overlayContainer.style.visibility : 'visible' - - if (overlayContainer) overlayContainer.style.visibility = 'hidden' - - return () => { - if (overlayContainer) overlayContainer.style.visibility = savedVisibilityStyle - } - }, []) - - return -} - -export default React.memo(LoaderForSuspenseFallback) diff --git a/src/common/Loader/loader.scss b/src/common/Loader/loader.scss deleted file mode 100644 index dde643b8bb..0000000000 --- a/src/common/Loader/loader.scss +++ /dev/null @@ -1,59 +0,0 @@ -@use 'igz-controls/scss/colors'; - -.loader-wrapper { - position: fixed; - top: 0; - left: 0; - z-index: 10; - display: flex; - align-items: center; - justify-content: center; - width: 100%; - height: 100%; - background-color: rgba(colors.$black, 0.16); - - .loader { - display: flex; - - &::after { - display: block; - width: 64px; - height: 64px; - border: 6px solid colors.$cornflowerBlue; - border-color: colors.$cornflowerBlue transparent colors.$cornflowerBlue transparent; - border-radius: 50%; - animation: rotate 1.5s linear infinite; - content: ' '; - } - } - - &.section-loader { - position: relative; - z-index: 2; - background-color: transparent; - } - - &.small-loader { - .loader { - &::after { - width: 20px; - height: 20px; - border-width: 2px; - } - } - } - - &.secondary-loader { - .loader { - &::after { - border-color: colors.$spunPearl transparent colors.$spunPearl transparent; - } - } - } -} - -@keyframes rotate { - 100% { - transform: rotate(360deg); - } -} diff --git a/src/common/MlChart/HistogramChart/HistogramChart.jsx b/src/common/MlChart/HistogramChart/HistogramChart.jsx index a064bdc3d5..7d3c9c1828 100644 --- a/src/common/MlChart/HistogramChart/HistogramChart.jsx +++ b/src/common/MlChart/HistogramChart/HistogramChart.jsx @@ -22,8 +22,6 @@ import PropTypes from 'prop-types' import MlChart from '../MlChart' -import './histogramChart.scss' - const HistogramChart = ({ config, showLoader = true }) => { const chartConfig = useMemo(() => { const pythonInfinity = 'e+308' diff --git a/src/common/MlChart/MetricChart/MetricChart.jsx b/src/common/MlChart/MetricChart/MetricChart.jsx index de2c9d5b4c..e49bfc4bc7 100644 --- a/src/common/MlChart/MetricChart/MetricChart.jsx +++ b/src/common/MlChart/MetricChart/MetricChart.jsx @@ -26,7 +26,7 @@ import { setChartGradient } from './metricChart.util' import './metricChart.scss' -const MetricChart = ({ config, isInvocationCardExpanded = false }) => { +const MetricChart = ({ config, isInvocationCardExpanded = false, isInvocationChart = false }) => { const chartRef = useRef(null) const contextRef = useRef(null) @@ -76,7 +76,7 @@ const MetricChart = ({ config, isInvocationCardExpanded = false }) => { ) useEffect(() => { - if (chartRef?.current) { + if (chartRef?.current && isInvocationChart) { if (chartRef.current.options.scales.x.grid.display !== isInvocationCardExpanded) { chartRef.current.options.scales.x.grid.display = isInvocationCardExpanded chartRef.current.options.scales.y.grid.display = isInvocationCardExpanded @@ -92,7 +92,7 @@ const MetricChart = ({ config, isInvocationCardExpanded = false }) => { chartRef.current.update() } - }, [backgroundColor, config.gradient, isInvocationCardExpanded]) + }, [backgroundColor, config.gradient, isInvocationCardExpanded, isInvocationChart]) return ( { MetricChart.propTypes = { config: PropTypes.object.isRequired, isInvocationCardExpanded: PropTypes.bool, + isInvocationChart: PropTypes.bool } export default memo(MetricChart) diff --git a/src/common/MlChart/MlChart.jsx b/src/common/MlChart/MlChart.jsx index 19636499c7..ddae2ab2be 100644 --- a/src/common/MlChart/MlChart.jsx +++ b/src/common/MlChart/MlChart.jsx @@ -19,10 +19,13 @@ such restriction. */ import React, { useState, useRef, useEffect } from 'react' import PropTypes from 'prop-types' -import { Chart } from 'chart.js/auto' -import Loader from '../Loader/Loader' +import Chart from 'chart.js/auto' import classnames from 'classnames' +import { Loader } from 'igz-controls/components' + +import './mlChart.scss' + const defaultOnChartCreated = () => {} const MlChart = ({ @@ -55,11 +58,11 @@ const MlChart = ({ ...config.options, animation: { ...config.options.animation, - onComplete: () => { + onComplete: (...args) => { showLoader && setIsLoading(false) if (config?.options?.animation?.onComplete) { - config.options.animation.onComplete() + config.options.animation.onComplete(...args) } } } diff --git a/src/common/MlChart/HistogramChart/histogramChart.scss b/src/common/MlChart/mlChart.scss similarity index 88% rename from src/common/MlChart/HistogramChart/histogramChart.scss rename to src/common/MlChart/mlChart.scss index e65e6c17dc..c792ca5be8 100644 --- a/src/common/MlChart/HistogramChart/histogramChart.scss +++ b/src/common/MlChart/mlChart.scss @@ -1,5 +1,3 @@ -@use 'igz-controls/scss/colors'; - .chart-container { display: flex; align-items: center; diff --git a/src/common/StatusFilter/StatusFilter.jsx b/src/common/MultiSelectFilter/MultiSelectFilter.jsx similarity index 66% rename from src/common/StatusFilter/StatusFilter.jsx rename to src/common/MultiSelectFilter/MultiSelectFilter.jsx index 9ad186e76b..595ffa43e5 100644 --- a/src/common/StatusFilter/StatusFilter.jsx +++ b/src/common/MultiSelectFilter/MultiSelectFilter.jsx @@ -21,23 +21,23 @@ import { isEmpty, capitalize } from 'lodash' import { FormOnChange, FormSelect } from 'igz-controls/components' import { FILTER_ALL_ITEMS } from '../../constants' -import { STATUS_LIST } from '../../types' +import { OPTIONS_LIST } from '../../types' -// TODO: Rename component from StatusFilter to a more generic name -const StatusFilter = ({ statusList, name }) => { +// TODO: Rename component from MultiSelectFilter to a more generic name +const MultiSelectFilter = ({ optionsList, name }) => { const { input } = useField(name) const { change } = useForm() - const mappedStatusList = useMemo(() => { - const isAllStatusSelected = input.value?.includes?.(FILTER_ALL_ITEMS) - return isAllStatusSelected - ? statusList.map(status => - status.id === FILTER_ALL_ITEMS ? { ...status, disabled: true } : status - ) - : statusList - }, [input.value, statusList]) + const mappedOptionsList = useMemo(() => { + const isAllOptionsSelected = input.value?.includes?.(FILTER_ALL_ITEMS) + return isAllOptionsSelected + ? optionsList.map(option => + option.id === FILTER_ALL_ITEMS ? { ...option, disabled: true } : option + ) + : optionsList + }, [input.value, optionsList]) - const handleFilterStateChange = (selectedValue, currentValue) => { + const handleFilterOptionChange = (selectedValue, currentValue) => { if ( selectedValue.length > 1 && selectedValue.includes(FILTER_ALL_ITEMS) && @@ -52,8 +52,8 @@ const StatusFilter = ({ statusList, name }) => { (!currentValue.includes(FILTER_ALL_ITEMS) && selectedValue.includes(FILTER_ALL_ITEMS) && selectedValue.indexOf(FILTER_ALL_ITEMS) > 0) || - mappedStatusList.filter(option => option.id !== FILTER_ALL_ITEMS).length === - selectedValue.length + mappedOptionsList.filter(option => option.id !== FILTER_ALL_ITEMS && !option.hidden).length === + selectedValue.length ) { change(name, [FILTER_ALL_ITEMS]) } @@ -61,15 +61,15 @@ const StatusFilter = ({ statusList, name }) => { return ( <> - - handleFilterStateChange(value, some)} name={name} /> + + handleFilterOptionChange(value, some)} name={name} /> ) } -StatusFilter.propTypes = { +MultiSelectFilter.propTypes = { name: PropTypes.string.isRequired, - statusList: STATUS_LIST.isRequired + optionsList: OPTIONS_LIST.isRequired } -export default memo(StatusFilter) +export default memo(MultiSelectFilter) diff --git a/src/common/NoData/noData.scss b/src/common/NoData/noData.scss index 489c58fafc..27c8a6623e 100644 --- a/src/common/NoData/noData.scss +++ b/src/common/NoData/noData.scss @@ -6,6 +6,6 @@ width: 100%; height: 100%; min-height: 150px; - word-break: break-word; text-align: center; + word-break: break-word; } diff --git a/src/common/Notifications/Notification.jsx b/src/common/Notifications/Notification.jsx index 44dfef1896..bbd754e08c 100644 --- a/src/common/Notifications/Notification.jsx +++ b/src/common/Notifications/Notification.jsx @@ -26,7 +26,7 @@ import classnames from 'classnames' import { useTimeout } from '../../hooks/useTimeout' -import { removeNotification } from '../../reducers/notificationReducer' +import { removeNotification } from 'igz-controls/reducers/notificationReducer' import { NOTIFICATION_DURATION } from '../../constants' @@ -42,7 +42,7 @@ const Notification = ({ notification, timeoutMs = 10000, ...rest }) => { const nodeRef = useRef() const { pauseTimeout, resumeTimeout, cancelTimeout } = useTimeout( - () => handleRemoveNotification(notification.id), + () => dispatch(removeNotification(notification.id)), timeoutMs ) diff --git a/src/common/Notifications/notifications.scss b/src/common/Notifications/notifications.scss index 33858b5642..592ea52400 100644 --- a/src/common/Notifications/notifications.scss +++ b/src/common/Notifications/notifications.scss @@ -1,10 +1,10 @@ .notifications-wrapper { position: absolute; right: 1.5em; - margin-left: 1.5em; bottom: 1em; display: flex; flex: 1 1; flex-direction: column; max-height: 90vh; + margin-left: 1.5em; } diff --git a/src/common/Pagination/Pagination.jsx b/src/common/Pagination/Pagination.jsx index 301674ba73..1e32ce34af 100644 --- a/src/common/Pagination/Pagination.jsx +++ b/src/common/Pagination/Pagination.jsx @@ -17,7 +17,7 @@ illegal under applicable law, and the grant of the foregoing license under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ -import React, { useCallback, useMemo, useRef } from 'react' +import React, { useCallback, useEffect, useMemo, useRef } from 'react' import PropTypes from 'prop-types' import classnames from 'classnames' import { useNavigate, useSearchParams } from 'react-router-dom' @@ -35,6 +35,7 @@ import { ITEMS_COUNT_END, ITEMS_COUNT_START } from '../../constants' +import { MAIN_TABLE_ID } from 'igz-controls/constants' import { PAGINATION_CONFIG } from '../../types' import { getCloseDetailsLink } from '../../utils/link-helper.util' @@ -49,13 +50,13 @@ const Pagination = ({ closeParamName = '', disableNextDoubleBtn = false, disabledNextDoubleBtnTooltip = '', - paginationConfig + paginationConfig, + selectedItemName = '', + tableId = MAIN_TABLE_ID }) => { - const [, setSearchParams] = useSearchParams() + const [searchParams, setSearchParams] = useSearchParams() const navigate = useNavigate() const paginationPagesRef = useRef() - const leftSideRef = useRef(0) - const rightSideRef = useRef(0) // Total pages are now calculated based on start and end pages const totalPagesCount = useMemo( @@ -84,9 +85,9 @@ const Pagination = ({ const handlePageChange = useCallback(() => { if (closeParamName) { - navigate(getCloseDetailsLink(closeParamName, true), { replace: true }) + navigate(getCloseDetailsLink(closeParamName, true, selectedItemName), { replace: true }) } - }, [closeParamName, navigate]) + }, [closeParamName, navigate, selectedItemName]) const paginationItems = useMemo(() => { if (!paginationConfig[FE_PAGE]) return [] @@ -117,9 +118,6 @@ const Pagination = ({ leftSide = lastPage - 4 } - rightSideRef.current = rightSide - leftSideRef.current = leftSide - if (leftSide > firstPage + 1) { items.push(threeDotsString) } @@ -219,6 +217,18 @@ const Pagination = ({ [paginationConfig] ) + useEffect(() => { + if (parseInt(searchParams.get(FE_PAGE)) !== paginationConfig[FE_PAGE]) { + const tableElement = document.getElementById(tableId) + + if (tableElement) { + tableElement.scrollTo({ + top: 0 + }) + } + } + }, [paginationConfig, searchParams, tableId]) + return (
{paginationConfig.isNewResponse && ( @@ -319,7 +329,9 @@ Pagination.propTypes = { closeParamName: PropTypes.string, disableNextDoubleBtn: PropTypes.bool, disabledNextDoubleBtnTooltip: PropTypes.string, - paginationConfig: PAGINATION_CONFIG.isRequired + paginationConfig: PAGINATION_CONFIG.isRequired, + selectedItemName: PropTypes.string, + tableId: PropTypes.string } export default Pagination diff --git a/src/common/Pagination/pagination.scss b/src/common/Pagination/pagination.scss index 69966f57cb..dfbf2e1a40 100644 --- a/src/common/Pagination/pagination.scss +++ b/src/common/Pagination/pagination.scss @@ -2,11 +2,11 @@ @use 'igz-controls/scss/variables'; .pagination { + z-index: 1; display: flex; - justify-content: space-between; align-items: center; + justify-content: space-between; padding: 10px 4px 4px; - z-index: 1; .pagination-items-count, .pagination-items-selector { @@ -19,8 +19,8 @@ } .pagination-navigation { - flex-grow: 1; display: flex; + flex-grow: 1; justify-content: center; } @@ -30,18 +30,18 @@ } .pagination-btn { - color: colors.$primary; - cursor: default; - box-sizing: border-box; display: flex; justify-content: center; - border: none; - padding: 4px 5px; + box-sizing: border-box; margin: 0 2px; - font-size: 14px; + padding: 4px 5px; + color: colors.$primary; font-weight: normal; + font-size: 14px; + border: none; + cursor: default; - &:hover:not(.pagination-btn_active):not(:disabled) { + &:hover:not(.pagination-btn_active, :disabled) { cursor: pointer; } @@ -56,10 +56,10 @@ } .pagination-page-number { - padding: 2px 3px; box-sizing: content-box; - border-bottom: 2px solid transparent; + padding: 2px 3px; border-top: 2px solid transparent; + border-bottom: 2px solid transparent; } &.pagination-page-btn { @@ -71,8 +71,8 @@ } &.pagination-dots { - cursor: default; display: inline-flex; + cursor: default; } } diff --git a/src/common/ProjectDetailsHeader/ProjectDetailsHeader.jsx b/src/common/ProjectDetailsHeader/ProjectDetailsHeader.jsx index de7ee73f4d..72101a01fc 100644 --- a/src/common/ProjectDetailsHeader/ProjectDetailsHeader.jsx +++ b/src/common/ProjectDetailsHeader/ProjectDetailsHeader.jsx @@ -20,74 +20,39 @@ such restriction. import React from 'react' import PropTypes from 'prop-types' import { useSelector } from 'react-redux' -import { Link, useLocation } from 'react-router-dom' -import { getDateAndTimeByFormat } from '../../utils/' -import { PROJECT_MONITOR, PROJECT_QUICK_ACTIONS_PAGE } from '../../constants' +import PageHeader from '../../elements/PageHeader/PageHeader' + +import { getDateAndTimeByFormat } from 'igz-controls/utils/datetime.util' + +import { COUNTERS_GENERAL_MESSAGE } from '../../constants' import './ProjectDetailsHeader.scss' const ProjectDetailsHeader = ({ projectData, projectName }) => { - const location = useLocation() const frontendSpec = useSelector(store => store.appStore.frontendSpec) return ( -
-
-
-
- {projectName} -
- -

- {projectData && projectData.spec.description} -

+
+ + {projectData && ( +
+ + Created: + {getDateAndTimeByFormat(projectData.metadata.created + 'Z', ' MM/DD/YYYY, HH:mm:ss A')} + + {projectData.spec.owner && !frontendSpec.ce?.version && ( + Owner: {projectData.spec.owner} + )}
- {projectData && ( -
    -
  • - Created: - - {getDateAndTimeByFormat(projectData.metadata.created, 'MM/DD/YYYY, HH:mm:ss A')} - -
  • - {!frontendSpec.ce?.version && ( -
  • - Owner: - {projectData.spec.owner} -
  • - )} -
  • - Status: -
    - {projectData.status.state} - -
    -
  • -
  • - {location.pathname.includes(PROJECT_MONITOR) ? ( - - Project quick actions - - ) : ( - - Project monitoring - - )} -
  • -
- )} -
+ )}
) } ProjectDetailsHeader.propTypes = { projectData: PropTypes.object, - projectName: PropTypes.string.isRequired, + projectName: PropTypes.string.isRequired } export default ProjectDetailsHeader diff --git a/src/common/ProjectDetailsHeader/ProjectDetailsHeader.scss b/src/common/ProjectDetailsHeader/ProjectDetailsHeader.scss index aecdb2dbb3..f1a8ef5c66 100644 --- a/src/common/ProjectDetailsHeader/ProjectDetailsHeader.scss +++ b/src/common/ProjectDetailsHeader/ProjectDetailsHeader.scss @@ -36,21 +36,19 @@ &__details { display: flex; flex-flow: column nowrap; - list-style-type: none; margin: 1rem 0; padding: 0; line-height: 1.5; - - li { - display: flex; - align-items: center; - margin-bottom: 0.2rem; - } + list-style-type: none; &-label { - margin-right: 10px; - font-weight: 700; - min-width: 60px; + font-size: 14px; + + &:not(:last-child)::after { + margin: 8px; + border-right: borders.$dividerBorder; + content: ""; + } } i[class^='state-'] { diff --git a/src/common/RangeInput/RangeInput.jsx b/src/common/RangeInput/RangeInput.jsx index e18cd53688..34820011ee 100644 --- a/src/common/RangeInput/RangeInput.jsx +++ b/src/common/RangeInput/RangeInput.jsx @@ -25,7 +25,7 @@ import { isNil } from 'lodash' import Input from '../Input/Input' import { Tooltip, TextTooltipTemplate } from 'igz-controls/components' -import { DENSITY_OPTIONS } from '../../types' +import { DENSITY_OPTIONS } from 'igz-controls/types' import Arrow from 'igz-controls/images/range-arrow-small.svg?react' import ExclamationMarkIcon from 'igz-controls/images/exclamation-mark.svg?react' diff --git a/src/common/RangeInput/RangeInput.stories.js b/src/common/RangeInput/RangeInput.stories.jsx similarity index 100% rename from src/common/RangeInput/RangeInput.stories.js rename to src/common/RangeInput/RangeInput.stories.jsx diff --git a/src/common/ReactFlow/MlModelRunnerNode.jsx b/src/common/ReactFlow/MlModelRunnerNode.jsx new file mode 100644 index 0000000000..6f4452ab0c --- /dev/null +++ b/src/common/ReactFlow/MlModelRunnerNode.jsx @@ -0,0 +1,122 @@ +/* +Copyright 2019 Iguazio Systems Ltd. + +Licensed under the Apache License, Version 2.0 (the "License") with +an addition restriction as set forth herein. You may not use this +file except in compliance with the License. You may obtain a copy of +the License at http://www.apache.org/licenses/LICENSE-2.0. + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +In addition, you may not use the software for any purposes that are +illegal under applicable law, and the grant of the foregoing license +under the Apache 2.0 license is conditioned upon your compliance with +such restriction. +*/ +import React from 'react' +import PropTypes from 'prop-types' +import { Handle } from 'reactflow' +import { Form } from 'react-final-form' +import arrayMutators from 'final-form-arrays' + +import { Tooltip, TextTooltipTemplate, FormChipCell } from 'igz-controls/components' + +import { REACT_FLOW_NODE_DATA } from '../../types' +import { createForm } from 'final-form' +import { getChipOptions } from 'igz-controls/utils/chips.util' +import { setFieldState } from 'igz-controls/utils/form.util' + +import ConnectionIcon from 'igz-controls/images/connections-icon.svg?react' +import MonitoringIcon from 'igz-controls/images/monitoring-icon.svg?react' + +import './mlModelRunnerNode.scss' + +const MlModelRunnerNode = ({ data, isConnectable }) => { + const formRef = React.useRef( + createForm({ + initialValues: { + runningModels: Object.keys(data.customData.class_args.monitoring_data).map(runningModelName => { + return { + isKeyOnly: true, + key: runningModelName, + id: runningModelName + } + }) + }, + mutators: { ...arrayMutators, setFieldState }, + onSubmit: () => {} + }) + ) + + return ( +
{}}> + {formState => ( + <> + +
+
+ +
+
+
+ +
+
Model runner step
+
+ {data.customData.track_models && ( +
+ }> + + +
+ )} +
+
Running models
+
+ +
+ + + )} +
+ ) +} + +MlModelRunnerNode.propTypes = { + data: REACT_FLOW_NODE_DATA.isRequired, + isConnectable: PropTypes.bool.isRequired +} + +export default React.memo(MlModelRunnerNode) diff --git a/src/common/ReactFlow/MlReactFlow.jsx b/src/common/ReactFlow/MlReactFlow.jsx index f44552e253..37fe506443 100644 --- a/src/common/ReactFlow/MlReactFlow.jsx +++ b/src/common/ReactFlow/MlReactFlow.jsx @@ -22,9 +22,10 @@ import PropTypes from 'prop-types' import ReactFlow, { ReactFlowProvider, MiniMap, Controls } from 'reactflow' import MlReactFlowNode from './MlReactFlowNode' +import MlModelRunnerNode from './MlModelRunnerNode' import MlReactFlowEdge from './MlReactFlowEdge' -import { ML_EDGE, ML_NODE } from '../../constants' +import { ML_EDGE, ML_MODEL_RUNNER_NODE, ML_NODE } from '../../constants' import { getNodeClassName } from './mlReactFlow.util' import './mlReactFlow.scss' @@ -34,7 +35,8 @@ const edgeTypes = { } const nodeTypes = { - [ML_NODE]: MlReactFlowNode + [ML_NODE]: MlReactFlowNode, + [ML_MODEL_RUNNER_NODE]: MlModelRunnerNode } const MlReactFlow = ({ alignTriggerItem = '', edges, nodes, onNodeClick = () => {} }) => { @@ -62,7 +64,9 @@ const MlReactFlow = ({ alignTriggerItem = '', edges, nodes, onNodeClick = () => useEffect(() => { if (reactFlowInstance && !initialGraphViewGenerated && nodes.length > 0) { - setInitialGraphViewGenerated(true) + queueMicrotask(() => { + setInitialGraphViewGenerated(true) + }) } }, [nodes.length, initialGraphViewGenerated, reactFlowInstance]) diff --git a/src/common/ReactFlow/MlReactFlowEdge.jsx b/src/common/ReactFlow/MlReactFlowEdge.jsx index 9497695529..93771880eb 100644 --- a/src/common/ReactFlow/MlReactFlowEdge.jsx +++ b/src/common/ReactFlow/MlReactFlowEdge.jsx @@ -44,9 +44,11 @@ const MlReactFlowEdge = ({ targetY }) => { const nodes = useNodes() + const markerEndIdConverted = useMemo(() => markerEndId?.replace(' ', '_'), [markerEndId]) + const idConverted = useMemo(() => id?.replace(' ', '_'), [id]) const markerEnd = useMemo( - () => getMarkerEnd(arrowHeadType, markerEndId, id), - [arrowHeadType, id, markerEndId] + () => getMarkerEnd(arrowHeadType, markerEndIdConverted, idConverted), + [arrowHeadType, idConverted, markerEndIdConverted] ) const sourceNode = useMemo(() => nodes.find(n => n.id === source), [source, nodes]) const targetNode = useMemo(() => nodes.find(n => n.id === target), [target, nodes]) @@ -98,7 +100,7 @@ const MlReactFlowEdge = ({ - + ) } diff --git a/src/common/ReactFlow/MlReactFlowNode.jsx b/src/common/ReactFlow/MlReactFlowNode.jsx index cdec7ad8e2..877caf82c5 100644 --- a/src/common/ReactFlow/MlReactFlowNode.jsx +++ b/src/common/ReactFlow/MlReactFlowNode.jsx @@ -21,18 +21,9 @@ import React from 'react' import PropTypes from 'prop-types' import { Handle } from 'reactflow' -import { Tooltip, TextTooltipTemplate } from 'igz-controls/components' -import { Tip } from 'igz-controls/components' +import { Tooltip, TextTooltipTemplate, Tip } from 'igz-controls/components' -import { - GREY_NODE, - INPUT_NODE, - OUTPUT_NODE, - OVAL_NODE_SHAPE, - PRIMARY_NODE, - ROUNDED_RECTANGLE_NODE_SHAPE, - SECONDARY_NODE -} from '../../constants' +import { REACT_FLOW_NODE_DATA } from '../../types' const MlReactFlowNode = ({ data, isConnectable }) => { return ( @@ -50,7 +41,7 @@ const MlReactFlowNode = ({ data, isConnectable }) => {
{data.subLabel &&
{data.subLabel}
}
@@ -71,25 +62,7 @@ const MlReactFlowNode = ({ data, isConnectable }) => { } MlReactFlowNode.propTypes = { - data: PropTypes.shape({ - subType: PropTypes.oneOf([INPUT_NODE, OUTPUT_NODE, PRIMARY_NODE, SECONDARY_NODE, GREY_NODE]) - .isRequired, - label: PropTypes.string.isRequired, - tip: PropTypes.string, - subLabel: PropTypes.string, - isSelectable: PropTypes.bool, - withOpacity: PropTypes.bool, - shape: PropTypes.oneOf([OVAL_NODE_SHAPE, ROUNDED_RECTANGLE_NODE_SHAPE, null]), - sourceHandle: PropTypes.shape({ - tooltip: PropTypes.string, - className: PropTypes.string - }), - targetHandle: PropTypes.shape({ - tooltip: PropTypes.string, - className: PropTypes.string - }), - customData: PropTypes.object - }).isRequired, + data: REACT_FLOW_NODE_DATA.isRequired, isConnectable: PropTypes.bool.isRequired } diff --git a/src/common/ReactFlow/mlModelRunnerNode.scss b/src/common/ReactFlow/mlModelRunnerNode.scss new file mode 100644 index 0000000000..b9ae93c7d1 --- /dev/null +++ b/src/common/ReactFlow/mlModelRunnerNode.scss @@ -0,0 +1,49 @@ +@use 'igz-controls/scss/colors'; + +.react-flow__renderer { + .react-flow__node.react-flow__node-ml-model-runner-node { + flex-direction: column; + align-items: flex-start; + + .react-flow__node-header { + display: flex; + width: 100%; + margin-bottom: 10px; + stroke: initial; + + &-title { + overflow: hidden; + margin-left: 10px; + margin-right: auto; + } + + &-label { + font-size: 16px; + } + + &-sub-label { + color: colors.$topaz; + font-size: 14px; + } + + &-icon { + display: flex; + align-items: center; + } + + &-monitoring-icon { + margin-left: 10px; + } + } + + .react-flow__node-chips-title { + font-size: 14px; + font-weight: 500; + } + + .react-flow__node-chips { + margin-top: 5px; + width: 100%; + } + } +} diff --git a/src/common/ReactFlow/mlReactFlow.scss b/src/common/ReactFlow/mlReactFlow.scss index 3d344c919d..54b1195f2e 100644 --- a/src/common/ReactFlow/mlReactFlow.scss +++ b/src/common/ReactFlow/mlReactFlow.scss @@ -4,23 +4,23 @@ @mixin inputNode { color: colors.$white; background-color: colors.$hotPink; - fill: colors.$hotPink; border-color: colors.$hotPink; - stroke: colors.$hotPink; box-shadow: 0 3px 14px rgba(colors.$hotPink, 0.34); + fill: colors.$hotPink; + stroke: colors.$hotPink; } @mixin outputNode { color: colors.$white; background-color: colors.$malibu; - fill: colors.$malibu; border-color: colors.$malibu; - stroke: colors.$malibu; box-shadow: 0 3px 14px rgba(colors.$malibu, 0.5); + fill: colors.$malibu; + stroke: colors.$malibu; } @mixin primaryNode { - color: colors.$malibu; + color: colors.$primary; background-color: colors.$white; border-color: colors.$malibu; stroke: colors.$malibu; @@ -80,20 +80,20 @@ @mixin selectedNode { &.selected { border-color: colors.$brightTurquoise; - stroke: colors.$brightTurquoise; box-shadow: 0 4px 20px rgba(colors.$brightTurquoise, 0.5); + stroke: colors.$brightTurquoise; &.status-error, &.status-failed { border-color: colors.$burntSienna; - stroke: colors.$burntSienna; box-shadow: 0 4px 20px rgba(colors.$burntSienna, 0.5); + stroke: colors.$burntSienna; } &.status-running { border-color: colors.$pictonBlue; - stroke: colors.$pictonBlue; box-shadow: 0 4px 20px rgba(colors.$pictonBlue, 0.5); + stroke: colors.$pictonBlue; } } } @@ -123,9 +123,9 @@ .react-flow__node-label { position: relative; width: 100%; + overflow: hidden; font-size: 1.5rem; text-align: center; - overflow: hidden; } .react-flow__node-sub-label { diff --git a/src/common/ReactFlow/mlReactFlow.util.js b/src/common/ReactFlow/mlReactFlow.util.js index 2a67678951..77383c0967 100644 --- a/src/common/ReactFlow/mlReactFlow.util.js +++ b/src/common/ReactFlow/mlReactFlow.util.js @@ -18,15 +18,21 @@ under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ import classnames from 'classnames' -import dagre from 'dagre' +import dagre from '@dagrejs/dagre' import { Position } from 'reactflow' -import { ERROR_STATE, FAILED_STATE } from '../../constants' +import { ERROR_STATE, FAILED_STATE, ML_MODEL_RUNNER_NODE } from '../../constants' + +const nodeWidthByType = { + default: 300 +} +const nodeHeightByType = { + [ML_MODEL_RUNNER_NODE]: 120, + default: 80 +} +const dagreGraph = new dagre.graphlib.Graph() export const getLayoutedElements = (nodes, edges, direction = 'TB') => { - const elWidth = 300 - const elHeight = 80 - const dagreGraph = new dagre.graphlib.Graph() const isHorizontal = direction === 'LR' let layoutedNodes = [] let layoutedEdges = [] @@ -35,7 +41,9 @@ export const getLayoutedElements = (nodes, edges, direction = 'TB') => { dagreGraph.setGraph({ rankdir: direction }) nodes.forEach(node => { - dagreGraph.setNode(node.id, { width: elWidth, height: elHeight }) + const nodeHeight = nodeHeightByType[node.type] ?? nodeHeightByType.default + const nodeWidth = nodeWidthByType[node.type] ?? nodeWidthByType.default + dagreGraph.setNode(node.id, { width: nodeWidth, height: nodeHeight }) }) edges.forEach(edge => { @@ -47,6 +55,8 @@ export const getLayoutedElements = (nodes, edges, direction = 'TB') => { const selectedNode = nodes.find(node => node.className?.includes('selected')) layoutedNodes = nodes.map(node => { + const nodeHeight = nodeHeightByType[node.type] ?? nodeHeightByType.default + const nodeWidth = nodeWidthByType[node.type] ?? nodeWidthByType.default const nodeWithPosition = dagreGraph.node(node.id) node.targetPosition = isHorizontal ? 'left' : 'top' node.sourcePosition = isHorizontal ? 'right' : 'bottom' @@ -54,16 +64,16 @@ export const getLayoutedElements = (nodes, edges, direction = 'TB') => { node.className = getNodeClassName(node) node.style = { - width: elWidth, - height: elHeight, + width: nodeWidth, + height: nodeHeight, pointerEvents: 'all' } - // unfortunately we need this little hack to pass a slighltiy different position - // in order to notify react flow about the change + // We are shifting the dagre node position (anchor=center) to the top left + // so it matches the React Flow node anchor point (top left). node.position = { - x: nodeWithPosition.x + Math.random() / 1000, - y: nodeWithPosition.y + x: nodeWithPosition.x - nodeWidth / 2, + y: nodeWithPosition.y - nodeHeight / 2, } return node diff --git a/src/common/Search/Search.jsx b/src/common/Search/Search.jsx index 1d7469a226..4e4e386130 100644 --- a/src/common/Search/Search.jsx +++ b/src/common/Search/Search.jsx @@ -17,7 +17,7 @@ illegal under applicable law, and the grant of the foregoing license under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ -import React, { useState, useEffect, useCallback, useRef } from 'react' +import React, { useState, useEffect, useCallback, useRef, useLayoutEffect } from 'react' import PropTypes from 'prop-types' import classnames from 'classnames' @@ -25,7 +25,7 @@ import Input from '../Input/Input' import { SelectOption } from 'igz-controls/elements' import { PopUpDialog } from 'igz-controls/components' -import { deleteUnsafeHtml } from '../../utils' +import { deleteUnsafeHtml } from 'igz-controls/utils/string.util' import SearchIcon from 'igz-controls/images/search.svg?react' @@ -41,40 +41,34 @@ const Search = ({ placeholder = '', searchWhileTyping = false, value = '', + withoutBorder = false, wrapperClassName = '' }) => { const [searchValue, setSearchValue] = useState(value ?? '') - const [label, setLabel] = useState('') + // const [label, setLabel] = useState('') const [inputIsFocused, setInputFocused] = useState(false) + const [searchWidth, setSearchWidth] = useState(0) + const [hasMatch, setHasMatch] = useState(false) const searchRef = useRef() const popUpRef = useRef() - - const { width: searchWidth } = searchRef?.current?.getBoundingClientRect() || {} - const searchClassNames = classnames('search-container', className) - const handleSearchOnBlur = useCallback( - event => { - if ( - (event.type === 'click' && - searchRef.current && - !searchRef.current.contains(event.target)) || - (event.type === 'scroll' && popUpRef.current && !popUpRef?.current.contains(event.target)) - ) { - setInputFocused(false) - } - }, - [searchRef] - ) + // === Обчислення ширини інпута після монтування === + useLayoutEffect(() => { + if (searchRef.current) { + const { width } = searchRef.current.getBoundingClientRect() + setSearchWidth(width) + } + }, []) - useEffect(() => { - if (matches.length > 0 && searchValue.length > 0) { - setLabel( - matches.find(item => item.toLocaleLowerCase().includes(searchValue.toLocaleLowerCase())) ?? - '' - ) + const handleSearchOnBlur = useCallback(event => { + if ( + (event.type === 'click' && searchRef.current && !searchRef.current.contains(event.target)) || + (event.type === 'scroll' && popUpRef.current && !popUpRef.current.contains(event.target)) + ) { + setInputFocused(false) } - }, [matches, searchValue]) + }, []) useEffect(() => { window.addEventListener('click', handleSearchOnBlur) @@ -86,40 +80,53 @@ const Search = ({ } }, [handleSearchOnBlur]) - const searchOnChange = value => { - if (value.length === 0 && label.length > 0) { - setLabel('') - } - - onChange(value) + // === Основна логіка оновлення значення === + const handleSearchChange = value => { + const cleanValue = deleteUnsafeHtml(value) + setSearchValue(cleanValue) setInputFocused(true) - setSearchValue(deleteUnsafeHtml(value)) + onChange(cleanValue) + + const matchExists = matches.some(item => + item.toLocaleLowerCase().includes(cleanValue.toLocaleLowerCase()) + ) + setHasMatch(matchExists) } - const matchOnClick = item => { - setLabel('') + // === Клік на елемент зі списку === + const handleMatchClick = item => { setSearchValue(item) - onChange(item) + setHasMatch(false) setInputFocused(false) + onChange(item) } - const handleSearchIconClick = event => { + // === Клік по іконці пошуку === + const handleIconClick = event => { event.stopPropagation() - if (searchValue.length > 0) { + if (searchValue.trim().length > 0) { onChange(searchValue) setInputFocused(false) } } + useEffect(() => { + if (value !== searchValue) { + queueMicrotask(() => setSearchValue(value ?? '')) + } + }, [searchValue, value]) + + const filteredMatches = inputIsFocused + ? matches.filter(item => item.toLocaleLowerCase().includes(searchValue.toLocaleLowerCase())) + : [] + return (
{ - setInputFocused(true) - }} + onClick={() => setInputFocused(true)} > } iconClass="search-icon" - iconOnClick={handleSearchIconClick} - onChange={searchOnChange} + iconOnClick={handleIconClick} + onChange={handleSearchChange} onFocus={onFocus} focused={inputIsFocused} onKeyDown={event => { - if (event.key === 'Enter' && !searchWhileTyping && searchValue !== '') { + if (event.key === 'Enter' && !searchWhileTyping && searchValue.trim() !== '') { onChange(searchValue) setInputFocused(false) } }} value={searchValue} + withoutBorder={withoutBorder} /> - {matches.length > 0 && label.length > 0 && inputIsFocused && ( + + {filteredMatches.length > 0 && hasMatch && (
    - {matches.reduce((options, item, index) => { - if (item?.toLocaleLowerCase().includes(searchValue.toLocaleLowerCase())) { - options.push( - (match ? `${match}` : match) - ) - }} - name={item} - key={item + index} - onClick={() => matchOnClick(item)} - tabIndex={index} - /> - ) - } - - return options - }, [])} + {filteredMatches.map((item, index) => ( + (match ? `${match}` : match) + ) + }} + name={item} + onClick={() => handleMatchClick(item)} + tabIndex={index} + /> + ))}
)} @@ -196,6 +199,7 @@ Search.propTypes = { placeholder: PropTypes.string, searchWhileTyping: PropTypes.bool, value: PropTypes.string, + withoutBorder: PropTypes.bool, wrapperClassName: PropTypes.string } diff --git a/src/common/Search/search.scss b/src/common/Search/search.scss index 377b71fd9c..6d537e1384 100644 --- a/src/common/Search/search.scss +++ b/src/common/Search/search.scss @@ -19,6 +19,7 @@ &-input { z-index: 2; width: 100%; + // todo: delete `!important` after replacing `Input` with `FormInput` padding: 10px 20px 10px 35px !important; color: colors.$topaz; @@ -41,9 +42,9 @@ } &-matches { + max-height: 250px; margin: 0; padding: 0; - max-height: 250px; &__item { padding: 7px 15px; diff --git a/src/common/SearchNavigator/SearchNavigator.jsx b/src/common/SearchNavigator/SearchNavigator.jsx new file mode 100644 index 0000000000..b0107f0f68 --- /dev/null +++ b/src/common/SearchNavigator/SearchNavigator.jsx @@ -0,0 +1,159 @@ +/* +Copyright 2019 Iguazio Systems Ltd. + +Licensed under the Apache License, Version 2.0 (the "License") with +an addition restriction as set forth herein. You may not use this +file except in compliance with the License. You may obtain a copy of +the License at http://www.apache.org/licenses/LICENSE-2.0. + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +In addition, you may not use the software for any purposes that are +illegal under applicable law, and the grant of the foregoing license +under the Apache 2.0 license is conditioned upon your compliance with +such restriction. +*/ +import React, { useCallback, useEffect, useState } from 'react' +import PropTypes from 'prop-types' +import classnames from 'classnames' + +import Search from '../Search/Search' +import { RoundedIcon } from 'igz-controls/components' + +import { countMatchesInTemplate, highlightMatches } from './searchNavigator.util' + +import Arrow from 'igz-controls/images/arrow.svg?react' +import Close from 'igz-controls/images/close.svg?react' + +import './searchNavigator.scss' + +const SearchNavigator = ({ promptTemplate, setSearchResult, searchOnChange = null }) => { + const [matchCount, setMatchCount] = useState(0) + const [activeMatchIndex, setActiveMatchIndex] = useState(0) + const [matches, setMatches] = useState([]) + const [searchValue, setSearchValue] = useState('') + const navigatorCounterClassNames = classnames( + 'search-navigator__counter', + matchCount > 0 && 'search-navigator__counter_with-divider' + ) + + const clearResults = useCallback(() => { + setSearchResult(promptTemplate) + setMatches([]) + setActiveMatchIndex(0) + setSearchValue('') + setMatchCount(0) + searchOnChange?.('') + }, [promptTemplate, searchOnChange, setSearchResult]) + + const searchOnChangeHandler = useCallback( + value => { + if (value.length === 0) { + return clearResults() + } + + const regex = new RegExp(`(${value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')})`, 'gi') + const highlighted = highlightMatches(promptTemplate, regex, 0) + const jsxMatchCount = countMatchesInTemplate(highlighted, regex) + + setSearchResult(highlighted) + setMatchCount(jsxMatchCount) + setMatches(new Array(jsxMatchCount).fill(null)) + setActiveMatchIndex(0) + setSearchValue(value) + searchOnChange?.(value) + }, + [promptTemplate, setSearchResult, searchOnChange, clearResults] + ) + + const highlightMatch = useCallback( + index => { + if (!matches.length) return + + const regex = new RegExp(`(${searchValue})`, 'gi') + const highlighted = highlightMatches(promptTemplate, regex, index) + + setSearchResult(highlighted) + setActiveMatchIndex(index) + }, + [matches, promptTemplate, searchValue, setSearchResult] + ) + + const goToPrevMatch = () => { + if (!matches.length) return + + const prevIndex = (activeMatchIndex - 1 + matchCount) % matchCount + + highlightMatch(prevIndex) + } + + const goToNextMatch = () => { + if (!matches.length) return + + const nextIndex = (activeMatchIndex + 1) % matchCount + + highlightMatch(nextIndex) + } + + useEffect(() => { + const activeMark = document.querySelector(`mark[data-index="${activeMatchIndex}"]`) + + if (activeMark) { + activeMark.scrollIntoView({ + behavior: 'smooth', + block: 'center' + }) + } + }, [activeMatchIndex]) + + return ( +
+ +
+ {matchCount > 0 && `${activeMatchIndex + 1}/${matchCount}`} +
+ {searchValue.length > 0 && ( +
+ + + + + + + + + +
+ )} +
+ ) +} + +SearchNavigator.propTypes = { + promptTemplate: PropTypes.array.isRequired, + setSearchResult: PropTypes.func.isRequired, + searchOnChange: PropTypes.func +} + +export default SearchNavigator diff --git a/src/common/SearchNavigator/searchNavigator.scss b/src/common/SearchNavigator/searchNavigator.scss new file mode 100644 index 0000000000..b8a810408c --- /dev/null +++ b/src/common/SearchNavigator/searchNavigator.scss @@ -0,0 +1,58 @@ +@use 'igz-controls/scss/borders'; +@use 'igz-controls/scss/colors'; + +.search-navigator { + display: flex; + align-items: center; + min-width: 280px; + border: borders.$primaryBorder; + border-radius: 4px; + + &__counter { + display: flex; + color: colors.$topaz; + font-size: 13px; + + &::after { + display: none; + width: 5px; + height: 15px; + margin: 0 5px 0 8px; + border-right: borders.$primaryBorder; + content: ''; + } + + &_with-divider { + &::after { + display: block; + } + } + } + + &__buttons { + display: flex; + padding-right: 10px; + } + + &__button { + .round-icon-cp__circle { + width: 26px; + height: 26px; + } + + &_back { + rotate: -90deg; + } + + &_next { + rotate: 90deg; + } + + &_cancel { + .round-icon-cp__circle { + width: 24px; + height: 24px; + } + } + } +} \ No newline at end of file diff --git a/src/common/SearchNavigator/searchNavigator.util.jsx b/src/common/SearchNavigator/searchNavigator.util.jsx new file mode 100644 index 0000000000..9cd2912122 --- /dev/null +++ b/src/common/SearchNavigator/searchNavigator.util.jsx @@ -0,0 +1,98 @@ +/* +Copyright 2019 Iguazio Systems Ltd. + +Licensed under the Apache License, Version 2.0 (the "License") with +an addition restriction as set forth herein. You may not use this +file except in compliance with the License. You may obtain a copy of +the License at http://www.apache.org/licenses/LICENSE-2.0. + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +In addition, you may not use the software for any purposes that are +illegal under applicable law, and the grant of the foregoing license +under the Apache 2.0 license is conditioned upon your compliance with +such restriction. +*/ +import React from 'react' + +export function highlightMatches(template, regex, activeIndex = 0) { + let current = 0 + + const processText = (text, keyPrefix = '') => { + const parts = text.split(regex) + + return parts.map((part, index) => { + if (index % 2 === 1) { + const isActive = current === activeIndex + const highlighted = ( + + {part} + + ) + + current++ + + return highlighted + } + + return part + }) + } + + const processElement = (element, keyPrefix = '') => { + if (typeof element === 'string') { + return processText(element, keyPrefix) + } + + if (React.isValidElement(element)) { + const children = element.props.children + + let newChildren + + if (typeof children === 'string') { + newChildren = processText(children, `${keyPrefix}-str`) + } else if (Array.isArray(children)) { + newChildren = children.map((child, index) => processElement(child, `${keyPrefix}-${index}`)) + } else if (React.isValidElement(children)) { + newChildren = processElement(children, `${keyPrefix}-child`) + } else { + newChildren = children + } + + return React.cloneElement(element, { ...element.props, key: keyPrefix }, newChildren) + } + + return element + } + + return template.map((el, index) => processElement(el, `root-${index}`)) +} + +export function countMatchesInTemplate(template, regex) { + let count = 0 + + const traverse = node => { + if (typeof node === 'string') { + count += (node.match(regex) || []).length + } else if (Array.isArray(node)) { + node.forEach(child => traverse(child)) + } else if (React.isValidElement(node)) { + traverse(node.props.children) + } + } + + template.forEach(el => traverse(el)) + + return count +} diff --git a/src/common/Select/Select.jsx b/src/common/Select/Select.jsx index 0d783ff540..528ecbd92f 100644 --- a/src/common/Select/Select.jsx +++ b/src/common/Select/Select.jsx @@ -17,14 +17,15 @@ illegal under applicable law, and the grant of the foregoing license under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ -import React, { useState, useEffect, useCallback, useRef } from 'react' +import React, { useState, useEffect, useCallback, useRef, useLayoutEffect } from 'react' import PropTypes from 'prop-types' import classNames from 'classnames' import { ConfirmDialog, Tooltip, TextTooltipTemplate, PopUpDialog } from 'igz-controls/components' import { SelectOption } from 'igz-controls/elements' -import { DENSITY_OPTIONS, SELECT_OPTIONS } from '../../types' +import { SELECT_OPTIONS } from '../../types' +import { DENSITY_OPTIONS } from 'igz-controls/types' import { TERTIARY_BUTTON } from 'igz-controls/constants' import Caret from 'igz-controls/images/dropdown.svg?react' @@ -41,10 +42,13 @@ const Select = ({ labelAtTop = false, onClick = null, options, + popUpClassName = 'select__body', + position = 'bottom-right', search = false, selectType = '', selectedId = '', selectedItemAction = null, + width = '', withoutBorder = false, withSelectedIcon = false }) => { @@ -52,7 +56,7 @@ const Select = ({ const [isConfirmDialogOpen, setConfirmDialogOpen] = useState(false) const [isOpen, setOpen] = useState(false) const [searchValue, setSearchValue] = useState('') - const { width: dropdownWidth } = selectRef?.current?.getBoundingClientRect() || {} + const [dropdownWidth, setDropdownWidth] = useState(0) const selectClassName = classNames( 'select', className, @@ -73,6 +77,18 @@ const Select = ({ ) const selectedOption = options.find(option => option.id === selectedId) + const clickHandler = event => { + if (selectRef.current !== event.target.closest('.select')) { + setOpen(false) + } + } + + const handleScroll = event => { + if (!event.target.closest('.select__body')) { + setOpen(false) + } + } + useEffect(() => { if (isOpen) { window.addEventListener('scroll', handleScroll, true) @@ -86,18 +102,6 @@ const Select = ({ } }, [isOpen]) - const clickHandler = event => { - if (selectRef.current !== event.target.closest('.select')) { - setOpen(false) - } - } - - const handleScroll = event => { - if (!event.target.closest('.select__body')) { - setOpen(false) - } - } - const toggleOpen = () => { !disabled && setOpen(!isOpen) } @@ -111,6 +115,13 @@ const Select = ({ } }, []) + useLayoutEffect(() => { + if (selectRef.current) { + const { width } = selectRef.current.getBoundingClientRect() + setDropdownWidth(width) + } + }, [selectRef]) + const handleSelectOptionClick = (selectedOption, option) => { if (selectedOption !== selectedId) { option.handler && option.handler() @@ -198,11 +209,11 @@ const Select = ({ headerIsHidden customPosition={{ element: selectRef, - position: 'bottom-right' + position: position }} - style={{ width: `${dropdownWidth}px` }} + style={{ width: `${width || dropdownWidth}px` }} > -
+
{search && (
{ - const [selectedOption, setSelectedOption] = useState(null) + const selectedOption = options.find(option => option.id === selectedId) const arrowDirectionClassName = classNames( 'sort-icon', isDescendingOrder ? 'sort-icon_down' : 'sort-icon_up' ) - useEffect(() => { - setSelectedOption(options.find(option => option.id === selectedId)) - }, [options, selectedId]) - return (
* { - fill: currentColor; + fill: currentcolor; } } } diff --git a/src/common/StatsCard/StatsCard.jsx b/src/common/StatsCard/StatsCard.jsx index 55a7381b64..4eeaa4868b 100644 --- a/src/common/StatsCard/StatsCard.jsx +++ b/src/common/StatsCard/StatsCard.jsx @@ -18,16 +18,18 @@ under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ import React from 'react' -import PropTypes from 'prop-types' import classNames from 'classnames' +import PropTypes from 'prop-types' -import { Tip } from 'igz-controls/components' +import { TextTooltipTemplate, Tip, Tooltip } from 'igz-controls/components' import './statsCard.scss' -const StatsCard = ({ children, className = '', onClick = () => {} }) => { +const StatsCard = ({ children, className = '', onClick = () => { } }) => { + const cardClass = classNames('stats-card', className) + return ( -
+
{children}
) @@ -43,8 +45,10 @@ StatsCard.Header = ({ children = null, icon = null, iconClass = '', title = '',
{icon && {icon}} - {title && {title}} - {tip && } +
+ }>{title} + {tip && } +
{children}
@@ -62,6 +66,33 @@ StatsCard.Col = ({ children }) => { } StatsCard.Col.displayName = 'StatsCard.Col' +StatsCard.MainCounter = ({ children, className = '', id = '', onClick = () => { } }) => { + const mainCounterClass = classNames('stats__counter-main', className) + + return ( +
+
+ {children} +
+
+ ) +} +StatsCard.MainCounter.displayName = 'StatsCard.MainCounter' + +StatsCard.SecondaryCounter = ({ children, className }) => { + const secondaryCounterClass = classNames('stats__counter-secondary', className) + + return ( +
+
+ {children} +
+
+ ) +} +StatsCard.SecondaryCounter.displayName = 'StatsCard.SecondaryCounter' + + StatsCard.propTypes = { children: PropTypes.node.isRequired, className: PropTypes.string, @@ -84,4 +115,16 @@ StatsCard.Col.propTypes = { children: PropTypes.node } +StatsCard.MainCounter.propTypes = { + children: PropTypes.node.isRequired, + className: PropTypes.string, + id: PropTypes.string.isRequired, + onClick: PropTypes.func +} + +StatsCard.SecondaryCounter.propTypes = { + children: PropTypes.node.isRequired, + className: PropTypes.string +} + export default StatsCard diff --git a/src/common/StatsCard/statsCard.scss b/src/common/StatsCard/statsCard.scss index c951a442a1..2deaed945a 100644 --- a/src/common/StatsCard/statsCard.scss +++ b/src/common/StatsCard/statsCard.scss @@ -3,26 +3,27 @@ .stats { &-card { + position: relative; display: flex; flex-wrap: wrap; - position: relative; + padding: 15px; color: colors.$topaz; background-color: colors.$white; border-radius: 8px; box-shadow: shadows.$previewBoxShadowInit; - padding: 15px; transition: all 0.3s ease-in-out; @media screen and (min-width: 1500px) { - padding: 20px 25px 15px; + padding: 20px 20px 5px; } &__row { display: flex; - flex-flow: row nowrap; flex: 1 0 100%; - justify-content: space-between; + flex-flow: row nowrap; align-items: baseline; + justify-content: space-between; + font-size: 12px; &:not(:last-child) { margin-bottom: 1em; @@ -42,17 +43,15 @@ &__title { position: relative; display: flex; + gap: 6px; align-items: center; - color: colors.$primary; - font-weight: normal; - font-size: 1rem; margin: 0; + padding-bottom: 1em; + color: colors.$primary; + font-weight: 500; + font-size: 1.25em; transition: font-size 0.3s ease-in-out; - @media screen and (min-width: 1600px) { - font-size: 1.25rem; - } - &_with-icon { padding-left: 18px; @@ -63,20 +62,21 @@ &-icon { position: absolute; + top: 0; left: 0; - top: 1px; - height: 16px; width: 16px; + height: 16px; transition: all 0.3s ease-in-out; @media screen and (min-width: 1600px) { - height: 20px; + top: -2px; width: 20px; + height: 20px; } svg { - height: inherit; width: inherit; + height: inherit; path { fill: colors.$ceriseRed; @@ -88,5 +88,23 @@ &__title-tip { margin-left: 5px; } + + &__title-wrapper { + display: flex; + align-items: normal; + } + + .stats__counter { + color: colors.$primary; + font-weight: 500; + + &-main { + font-size: 26px; + } + + &-secondary { + font-size: 15px; + } + } } } diff --git a/src/common/TabsSlider/TabsSlider.jsx b/src/common/TabsSlider/TabsSlider.jsx deleted file mode 100644 index b8b22d5fc6..0000000000 --- a/src/common/TabsSlider/TabsSlider.jsx +++ /dev/null @@ -1,239 +0,0 @@ -/* -Copyright 2019 Iguazio Systems Ltd. - -Licensed under the Apache License, Version 2.0 (the "License") with -an addition restriction as set forth herein. You may not use this -file except in compliance with the License. You may obtain a copy of -the License at http://www.apache.org/licenses/LICENSE-2.0. - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -implied. See the License for the specific language governing -permissions and limitations under the License. - -In addition, you may not use the software for any purposes that are -illegal under applicable law, and the grant of the foregoing license -under the Apache 2.0 license is conditioned upon your compliance with -such restriction. -*/ -import React, { useCallback, useEffect, useState, useRef } from 'react' -import { Link, useLocation, useParams } from 'react-router-dom' -import PropTypes from 'prop-types' -import classnames from 'classnames' - -import { Tip } from 'igz-controls/components' - -import { SLIDER_TABS } from '../../types' -import { generateUrlFromRouterPath } from '../../utils/link-helper.util' - -import Arrow from 'igz-controls/images/arrow.svg?react' - -const TabsSlider = ({ - fontSize = 'sm', - initialTab = '', - isDetailsPopUp = false, - onClick = () => {}, - skipLink = false, - tabsList -}) => { - const [selectedTab, setSelectedTab] = useState(initialTab) - const [arrowsAreHidden, setArrowsAreHidden] = useState(true) - const [scrolledWidth, setScrolledWidth] = useState(0) - const [rightArrowDisabled, setRightArrowDisabled] = useState(false) - const tabsWrapperRef = useRef() - const tabsRef = useRef() - const location = useLocation() - const params = useParams() - const menuOffsetHalfWidth = 2 - const tabOffset = 1.5 - - const leftArrowClassNames = classnames( - 'tabs-slider__arrow', - 'tabs-slider__arrow_left', - arrowsAreHidden && 'tabs-slider__arrow_hidden', - scrolledWidth === 0 && 'tabs-slider__arrow_disabled' - ) - const rightArrowClassNames = classnames( - 'tabs-slider__arrow', - 'tabs-slider__arrow_right', - arrowsAreHidden && 'tabs-slider__arrow_hidden', - rightArrowDisabled && 'tabs-slider__arrow_disabled' - ) - - const scrollTabs = toRight => { - let scrollWidth - - if (toRight) { - if ( - tabsRef.current?.scrollWidth < - tabsWrapperRef.current?.offsetWidth * tabOffset + scrolledWidth - ) { - scrollWidth = tabsRef.current?.scrollWidth - tabsWrapperRef.current?.offsetWidth - - setRightArrowDisabled(true) - } else { - scrollWidth = scrolledWidth + tabsWrapperRef.current?.offsetWidth / menuOffsetHalfWidth - } - } else { - scrollWidth = Math.max( - 0, - scrolledWidth - tabsWrapperRef.current?.offsetWidth / menuOffsetHalfWidth - ) - - setRightArrowDisabled(false) - } - - setScrolledWidth(scrollWidth) - } - - const handleHideArrows = useCallback(() => { - const scrollIsHidden = tabsRef.current?.offsetWidth === tabsRef.current?.scrollWidth - - setArrowsAreHidden(scrollIsHidden) - - if (rightArrowDisabled) { - setScrolledWidth(tabsRef.current?.scrollWidth - tabsWrapperRef.current?.offsetWidth) - } - - if (scrollIsHidden) { - setScrolledWidth(0) - setRightArrowDisabled(false) - } - }, [rightArrowDisabled, tabsRef, tabsWrapperRef]) - - const moveToSelectedTab = useCallback(() => { - const selectedTabNode = document.querySelector(`[data-tab='${selectedTab}']`) - const centeredTabPosition = - selectedTabNode?.offsetLeft - - tabsWrapperRef.current?.offsetWidth / menuOffsetHalfWidth + - selectedTabNode?.offsetWidth / menuOffsetHalfWidth - - if (centeredTabPosition <= 0) { - setScrolledWidth(0) - setRightArrowDisabled(false) - } else if ( - tabsRef.current?.scrollWidth < - tabsWrapperRef.current?.offsetWidth / menuOffsetHalfWidth + - selectedTabNode?.offsetLeft + - selectedTabNode?.offsetWidth - ) { - setScrolledWidth(tabsRef.current?.scrollWidth - tabsWrapperRef.current?.offsetWidth) - setRightArrowDisabled(true) - } else { - setScrolledWidth(centeredTabPosition) - setRightArrowDisabled(false) - } - }, [selectedTab]) - - const onSelectTab = newTab => { - setSelectedTab(newTab) - onClick && onClick(newTab) - } - - useEffect(() => { - window.addEventListener('resize', handleHideArrows) - - return () => window.removeEventListener('resize', handleHideArrows) - }, [handleHideArrows]) - - useEffect(() => { - window.addEventListener('resize', moveToSelectedTab) - - return () => window.removeEventListener('resize', moveToSelectedTab) - }, [moveToSelectedTab]) - - useEffect(() => { - handleHideArrows() - }, [tabsList, handleHideArrows]) - - useEffect(() => { - moveToSelectedTab() - }, [moveToSelectedTab]) - - useEffect(() => { - if (params.tab && params.tab !== selectedTab && !isDetailsPopUp) { - setSelectedTab(tabsList.find(tab => tab.id === params.tab)?.id) - } - }, [isDetailsPopUp, params.tab, selectedTab, tabsList]) - - return ( -
-
{ - scrollTabs(false) - }} - > - -
-
-
- {tabsList.map(tab => { - const tabClassName = classnames( - 'content-menu__tab', - `content-menu__tab-${fontSize}`, - selectedTab === tab.id && 'content-menu__tab_active' - ) - - return ( - !tab.hidden && - (!skipLink ? ( - - onSelectTab(tab)} - > - {tab.icon &&
{tab.icon}
} - {tab.label} - {tab.tip && } -
- - ) : ( -
onSelectTab(tab.id)} - > - {tab.icon &&
{tab.icon}
} - {tab.label} - {tab.tip && } -
- )) - ) - })} -
-
-
scrollTabs(true)}> - -
-
- ) -} - -TabsSlider.propTypes = { - fontSize: PropTypes.oneOf(['sm', 'md', 'lg']), - initialTab: PropTypes.string, - isDetailsPopUp: PropTypes.bool, - onClick: PropTypes.func, - skipLink: PropTypes.bool, - tabsList: SLIDER_TABS.isRequired -} - -export default TabsSlider diff --git a/src/common/TargetPath/TargetPath.jsx b/src/common/TargetPath/TargetPath.jsx index 18c753d454..d2f1e383d7 100644 --- a/src/common/TargetPath/TargetPath.jsx +++ b/src/common/TargetPath/TargetPath.jsx @@ -36,6 +36,7 @@ import { handleStoreInputPathChange, isPathInputInvalid, pathPlaceholders, + prepareTargetPathInitialState, targetPathInitialState } from './targetPath.util' import { MLRUN_STORAGE_INPUT_PATH_SCHEME } from '../../constants' @@ -44,7 +45,9 @@ const TargetPath = ({ density = 'normal', formState, formStateFieldInfo, + formStateDataInputState = '', hiddenSelectOptionsIds = [], + inputDefaultState = null, inputDefaultValue = '', label = '', name, @@ -54,7 +57,9 @@ const TargetPath = ({ selectPlaceholder = '', setFieldState }) => { - const [dataInputState, setDataInputState] = useState(targetPathInitialState) + const [dataInputState, setDataInputState] = useState( + prepareTargetPathInitialState(inputDefaultState, inputDefaultValue, selectDefaultValue) + ) const dispatch = useDispatch() const handleOnChange = (selectValue, inputValue) => { @@ -75,21 +80,35 @@ const TargetPath = ({ } } + const handlePathChange = useCallback( + value => { + if (value.length !== 0) { + formState.form.change(`${formStateFieldInfo}.value`, value.replace(/[^:/]*:[/]{2,3}/, '')) + formState.form.change(`${formStateFieldInfo}.pathType`, value.match(/^\w*:[/]{2,3}/)[0]) + + if (formStateDataInputState) { + formState.form.change(`${formStateDataInputState}`, dataInputState) + } + } + }, + [dataInputState, formState.form, formStateDataInputState, formStateFieldInfo] + ) + const handleGetProjectsNames = useCallback(() => { getProjectsNames(dispatch, setDataInputState, params.projectName) - }, [dispatch, params.projectName]) + }, [dispatch, setDataInputState, params.projectName]) const handleGetArtifacts = useCallback(() => { getArtifacts(dispatch, dataInputState.project, dataInputState.storePathType, setDataInputState) - }, [dataInputState.project, dataInputState.storePathType, dispatch]) + }, [dataInputState.project, dataInputState.storePathType, dispatch, setDataInputState]) const handleGetFeatureVectors = useCallback(() => { getFeatureVectors(dispatch, dataInputState.project, setDataInputState) - }, [dataInputState.project, dispatch]) + }, [dataInputState.project, dispatch, setDataInputState]) const handleGetArtifact = useCallback(() => { getArtifact(dispatch, dataInputState.project, dataInputState.projectItem, setDataInputState) - }, [dataInputState.project, dataInputState.projectItem, dispatch]) + }, [dataInputState.project, dataInputState.projectItem, dispatch, setDataInputState]) const handleGetFeatureVector = useCallback(() => { getFeatureVector( @@ -98,7 +117,7 @@ const TargetPath = ({ dataInputState.projectItem, setDataInputState ) - }, [dataInputState.project, dataInputState.projectItem, dispatch]) + }, [dataInputState.project, dataInputState.projectItem, dispatch, setDataInputState]) useEffect(() => { if (dataInputState.inputStorePathTypeEntered && dataInputState.projects.length === 0) { @@ -115,24 +134,27 @@ const TargetPath = ({ if ( get(formState.values, `${formStateFieldInfo}.pathType`) === MLRUN_STORAGE_INPUT_PATH_SCHEME ) { - setDataInputState(prev => ({ - ...prev, - comboboxMatches: generateComboboxMatchesList( - dataInputState.artifacts, - dataInputState.artifactsReferences, - dataInputState.featureVectors, - dataInputState.featureVectorsReferences, - dataInputState.inputProjectItemPathEntered, - dataInputState.inputProjectItemReferencePathEntered, - dataInputState.inputProjectPathEntered, - dataInputState.inputStorePathTypeEntered, - dataInputState.project, - dataInputState.projectItem, - dataInputState.projectItemReference, - dataInputState.projects, - dataInputState.storePathType - ) - })) + //TODO + setTimeout(() => { + setDataInputState(prev => ({ + ...prev, + comboboxMatches: generateComboboxMatchesList( + dataInputState.artifacts, + dataInputState.artifactsReferences, + dataInputState.featureVectors, + dataInputState.featureVectorsReferences, + dataInputState.inputProjectItemPathEntered, + dataInputState.inputProjectItemReferencePathEntered, + dataInputState.inputProjectPathEntered, + dataInputState.inputStorePathTypeEntered, + dataInputState.project, + dataInputState.projectItem, + dataInputState.projectItemReference, + dataInputState.projects, + dataInputState.storePathType + ) + })) + }, 0) } }, [ dataInputState.artifacts, @@ -210,16 +232,6 @@ const TargetPath = ({ handleGetFeatureVector ]) - const handlePathChange = useCallback( - value => { - if (value.length !== 0) { - formState.form.change(`${formStateFieldInfo}.value`, value.replace(/[^:/]*:[/]{2,3}/, '')) - formState.form.change(`${formStateFieldInfo}.pathType`, value.match(/^\w*:[/]{2,3}/)[0]) - } - }, - [formState.form, formStateFieldInfo] - ) - return ( <> { return uniqBy(generatedArtifacts, 'id') } -export const getProjectsNames = (dispatch, setDataInputState, projectName) => { +export const getProjectsNames = debounce((dispatch, setDataInputState, projectName) => { dispatch(fetchProjectsNames()) .unwrap() .then(result => { @@ -342,9 +343,9 @@ export const getProjectsNames = (dispatch, setDataInputState, projectName) => { })) }) .catch(() => {}) -} +}, 300) -export const getArtifacts = (dispatch, project, storePathType, setDataInputState) => { +export const getArtifacts = debounce((dispatch, project, storePathType, setDataInputState) => { dispatch( fetchArtifacts({ project, @@ -373,9 +374,9 @@ export const getArtifacts = (dispatch, project, storePathType, setDataInputState .catch(error => { showErrorNotification(dispatch, error, '', 'Failed to fetch artifacts') }) -} +}, 300) -export const getFeatureVectors = (dispatch, project, setDataInputState) => { +export const getFeatureVectors = debounce((dispatch, project, setDataInputState) => { dispatch(fetchFeatureVectors({ project, filters: {}, config: {} })) .unwrap() .then(featureVectors => { @@ -393,9 +394,9 @@ export const getFeatureVectors = (dispatch, project, setDataInputState) => { featureVectors: featureVectorsList })) }) -} +}, 300) -export const getArtifact = (dispatch, project, projectItem, setDataInputState) => { +export const getArtifact = debounce((dispatch, project, projectItem, setDataInputState) => { dispatch(fetchArtifact({ project, artifact: projectItem })) .unwrap() .then(artifacts => { @@ -409,9 +410,9 @@ export const getArtifact = (dispatch, project, projectItem, setDataInputState) = .catch(error => { showErrorNotification(dispatch, error, '', 'Failed to fetch artifact data') }) -} +}, 300) -export const getFeatureVector = (dispatch, project, projectItem, setDataInputState) => { +export const getFeatureVector = debounce((dispatch, project, projectItem, setDataInputState) => { dispatch(fetchFeatureVector({ project, featureVector: projectItem })) .unwrap() .then(featureVectors => { @@ -436,4 +437,35 @@ export const getFeatureVector = (dispatch, project, projectItem, setDataInputSta .catch(error => { showErrorNotification(dispatch, error, '', 'Failed to fetch feature vector data') }) +}, 300) + +export const prepareTargetPathInitialState = ( + inputDefaultState, + inputDefaultValue = '', + selectDefaultValue = '' +) => { + if (inputDefaultState) { + return inputDefaultState + } + + if (inputDefaultValue && selectDefaultValue.startsWith('store')) { + const state = { ...targetPathInitialState } + const { key, project, kind } = parseUri(selectDefaultValue + inputDefaultValue) + const projectItemReference = inputDefaultValue.split(`${kind}/${project}/${key}`)?.[1] || '' + state.storePathType = kind + state.project = project + state.projectItem = key + state.inputProjectItemPathEntered = true + state.inputProjectPathEntered = true + state.inputStorePathTypeEntered = true + + if (projectItemReference) { + state.projectItemReference = projectItemReference + state.inputProjectItemReferencePathEntered = true + } + + return state + } + + return targetPathInitialState } diff --git a/src/common/TimePicker/TimePicker.jsx b/src/common/TimePicker/TimePicker.jsx index 0c12f926e0..6e573223e1 100644 --- a/src/common/TimePicker/TimePicker.jsx +++ b/src/common/TimePicker/TimePicker.jsx @@ -22,7 +22,7 @@ import PropTypes from 'prop-types' import MaskedInput from 'react-text-mask' import classNames from 'classnames' -import { DENSITY_OPTIONS } from '../../types' +import { DENSITY_OPTIONS } from 'igz-controls/types' import './timePicker.scss' diff --git a/src/components/ActionBar/ActionBar.jsx b/src/components/ActionBar/ActionBar.jsx index 735812a889..36f3626fa4 100644 --- a/src/components/ActionBar/ActionBar.jsx +++ b/src/components/ActionBar/ActionBar.jsx @@ -21,8 +21,7 @@ import React, { useCallback, useEffect, useLayoutEffect, useMemo, useState } fro import PropTypes from 'prop-types' import arrayMutators from 'final-form-arrays' import classnames from 'classnames' -import { Field } from 'react-final-form' -import { Form } from 'react-final-form' +import { Field, Form } from 'react-final-form' import { createForm } from 'final-form' import { isEmpty, isEqual, isNil, mapValues, pickBy } from 'lodash' import { useDispatch, useSelector } from 'react-redux' @@ -31,7 +30,7 @@ import { useNavigate, useParams } from 'react-router-dom' import DatePicker from '../../common/DatePicker/DatePicker' import FilterMenuModal from '../FilterMenuModal/FilterMenuModal' import NameFilter from '../../common/NameFilter/NameFilter' -import { RoundedIcon, Button, FormCheckBox, FormOnChange } from 'igz-controls/components' +import { Button, FormCheckBox, FormOnChange, RoundedIcon } from 'igz-controls/components' import { AUTO_REFRESH, @@ -75,6 +74,7 @@ const ActionBar = ({ hidden = false, internalAutoRefreshIsEnabled = false, removeSelectedItem = null, + selectedItemName = '', setSearchParams, setSelectedRowData = null, tab = '', @@ -88,7 +88,7 @@ const ActionBar = ({ internalAutoRefreshIsEnabled ) const filtersStore = useSelector(store => store.filtersStore) - const changes = useSelector(store => store.detailsStore.changes) + const changes = useSelector(store => store.commonDetailsStore.changes) const dispatch = useDispatch() const navigate = useNavigate() const params = useParams() @@ -126,22 +126,20 @@ const ActionBar = ({ }, [filtersConfig]) const formInitialValues = useMemo(() => { - const initialValues = { + return { [AUTO_REFRESH_ID]: autoRefreshIsEnabled, [INTERNAL_AUTO_REFRESH_ID]: internalAutoRefreshIsEnabled, ...formFiltersInitialValues } - - return initialValues }, [autoRefreshIsEnabled, formFiltersInitialValues, internalAutoRefreshIsEnabled]) - const formRef = React.useRef( - createForm({ + const [form] = useState(() => { + return createForm({ initialValues: formInitialValues, mutators: { ...arrayMutators, setFieldState }, onSubmit: () => {} }) - ) + }) const filterMenuModalInitialState = useMemo(() => { return mapValues( @@ -185,13 +183,14 @@ const ActionBar = ({ ) const applyFilters = useCallback( - async (formValues, filters) => { - const actionCanBePerformed = await performDetailsActionHelper(changes, dispatch, true) + async (formValues, filters, actionCanBePerformedChecked) => { + const actionCanBePerformed = + actionCanBePerformedChecked || (await performDetailsActionHelper(changes, dispatch, true)) const newFilters = { ...filters, ...formValues } if (actionCanBePerformed) { if (closeParamName) { - navigate(getCloseDetailsLink(closeParamName, true), { replace: true }) + navigate(getCloseDetailsLink(closeParamName, true, selectedItemName), { replace: true }) } if ( @@ -224,7 +223,8 @@ const ActionBar = ({ setSelectedRowData, toggleAllRows, handleRefresh, - navigate + navigate, + selectedItemName ] ) @@ -275,14 +275,14 @@ const ActionBar = ({ } useEffect(() => { - if (!isEqual(formRef.current?.getState().values, filterMenu)) { - formRef.current?.batch(() => { + if (!isEqual(form.getState().values, filterMenu)) { + form.batch(() => { for (const filterName in filterMenu) { - formRef.current?.change(filterName, filterMenu[filterName]) + form.change(filterName, filterMenu[filterName]) } }) } - }, [filterMenu, filtersConfig]) + }, [filterMenu, filtersConfig, form]) useEffect(() => { if ( @@ -292,7 +292,7 @@ const ActionBar = ({ ) { const intervalId = setInterval(() => { if (!autoRefreshIsStopped) { - refresh(formRef.current.getState()) + refresh(form.getState()) } }, 30000) @@ -304,19 +304,24 @@ const ActionBar = ({ refresh, withInternalAutoRefresh, filtersStore.internalAutoRefresh, - filtersStore.autoRefresh + filtersStore.autoRefresh, + form ]) useEffect(() => { if (autoRefreshStopTrigger && filtersStore.internalAutoRefresh) { - formRef.current?.change(INTERNAL_AUTO_REFRESH_ID, false) - setInternalAutoRefreshPrevValue(true) + form.change(INTERNAL_AUTO_REFRESH_ID, false) + queueMicrotask(() => { + setInternalAutoRefreshPrevValue(true) + }) dispatch(toggleInternalAutoRefresh(false)) handleAutoRefreshPrevValueChange && handleAutoRefreshPrevValueChange(true) } else if (!autoRefreshStopTrigger && internalAutoRefreshPrevValue) { - setInternalAutoRefreshPrevValue(false) + queueMicrotask(() => { + setInternalAutoRefreshPrevValue(false) + }) dispatch(toggleInternalAutoRefresh(true)) - formRef.current?.change(INTERNAL_AUTO_REFRESH_ID, true) + form.change(INTERNAL_AUTO_REFRESH_ID, true) handleAutoRefreshPrevValueChange && handleAutoRefreshPrevValueChange(false) } }, [ @@ -324,7 +329,8 @@ const ActionBar = ({ autoRefreshStopTrigger, handleAutoRefreshPrevValueChange, dispatch, - filtersStore.internalAutoRefresh + filtersStore.internalAutoRefresh, + form ]) useEffect(() => { @@ -334,21 +340,21 @@ const ActionBar = ({ }, []) useLayoutEffect(() => { - const prevValues = formRef.current.getState().values + const prevValues = form.getState().values const valuesToReset = { [INTERNAL_AUTO_REFRESH_ID]: prevValues[INTERNAL_AUTO_REFRESH_ID], [AUTO_REFRESH_ID]: prevValues[AUTO_REFRESH_ID], ...formFiltersInitialValues } - formRef.current.reset(valuesToReset) - }, [formFiltersInitialValues]) + form.reset(valuesToReset) + }, [formFiltersInitialValues, form]) useLayoutEffect(() => { - formRef.current?.batch(() => { - formRef.current?.change(AUTO_REFRESH_ID, autoRefreshIsEnabled) - formRef.current?.change(INTERNAL_AUTO_REFRESH_ID, internalAutoRefreshIsEnabled) + form.batch(() => { + form.change(AUTO_REFRESH_ID, autoRefreshIsEnabled) + form.change(INTERNAL_AUTO_REFRESH_ID, internalAutoRefreshIsEnabled) }) - }, [autoRefreshIsEnabled, internalAutoRefreshIsEnabled]) + }, [autoRefreshIsEnabled, form, internalAutoRefreshIsEnabled]) useEffect(() => { dispatch(toggleAutoRefresh(false)) @@ -356,7 +362,7 @@ const ActionBar = ({ }, [dispatch, params.projectName]) return ( -
{}}> + {}}> {formState => (
@@ -402,9 +408,12 @@ const ActionBar = ({
{!isEmpty(filterMenuModalInitialState) && ( applyFilters(formState.values, filterMenuModal)} + applyChanges={(filterMenuModal, actionCanBePerformedChecked) => + applyFilters(formState.values, filterMenuModal, actionCanBePerformedChecked) + } initialValues={filterMenuModalInitialState} values={filterMenuModal} + detailsChanges={changes} > {children} @@ -512,6 +521,7 @@ ActionBar.propTypes = { hidden: PropTypes.bool, internalAutoRefreshIsEnabled: PropTypes.bool, removeSelectedItem: PropTypes.func, + selectedItemName: PropTypes.string, setSearchParams: PropTypes.func.isRequired, setSelectedRowData: PropTypes.func, tab: PropTypes.string, diff --git a/src/components/AddToFeatureVectorPage/AddToFeatureVectorPage.jsx b/src/components/AddToFeatureVectorPage/AddToFeatureVectorPage.jsx index c51b67b90d..87a33c71cc 100644 --- a/src/components/AddToFeatureVectorPage/AddToFeatureVectorPage.jsx +++ b/src/components/AddToFeatureVectorPage/AddToFeatureVectorPage.jsx @@ -52,9 +52,9 @@ import { getFiltersConfig } from './addToFeatureVectorPage.util' import { getScssVariableValue } from 'igz-controls/utils/common.util' import { handleFeaturesResponse } from '../FeatureStore/Features/features.util' import { isEveryObjectValueEmpty } from '../../utils/isEveryObjectValueEmpty' -import { setNotification } from '../../reducers/notificationReducer' +import { setNotification } from 'igz-controls/reducers/notificationReducer' import { setTablePanelOpen } from '../../reducers/tableReducer' -import { showErrorNotification } from '../../utils/notifications.util' +import { showErrorNotification } from 'igz-controls/utils/notification.util' import { toggleYaml } from '../../reducers/appReducer' import { useFiltersFromSearchParams } from '../../hooks/useFiltersFromSearchParams.hook' import { useGroupContent } from '../../hooks/groupContent.hook' diff --git a/src/components/AddToFeatureVectorPage/AddToFeatureVectorView.jsx b/src/components/AddToFeatureVectorPage/AddToFeatureVectorView.jsx index a50e142d67..d9f0b89ecf 100644 --- a/src/components/AddToFeatureVectorPage/AddToFeatureVectorView.jsx +++ b/src/components/AddToFeatureVectorPage/AddToFeatureVectorView.jsx @@ -22,13 +22,13 @@ import { useParams } from 'react-router-dom' import PropTypes from 'prop-types' import AddToFeatureVectorPageHeader from '../../elements/AddToFeatureVectorPageHeader/AddToFeatureVectorPageHeader' -import Loader from '../../common/Loader/Loader' import NoData from '../../common/NoData/NoData' import Table from '../Table/Table' import FeatureStoreTableRow from '../../elements/FeatureStoreTableRow/FeatureStoreTableRow' +import { Loader } from 'igz-controls/components' import { ADD_TO_FEATURE_VECTOR_TAB, FEATURE_STORE_PAGE } from '../../constants' -import { VIRTUALIZATION_CONFIG } from '../../types' +import { VIRTUALIZATION_CONFIG } from 'igz-controls/types' import { getNoDataMessage } from '../../utils/getNoDataMessage' import { isRowRendered } from '../../hooks/useVirtualization.hook' import ActionBar from '../ActionBar/ActionBar' @@ -62,9 +62,9 @@ const AddToFeatureVectorView = React.forwardRef( const params = useParams() return (
-
- +
+
-
- {(featureStore.loading || featureStore.features.loading) && } -
+ {(featureStore.loading || featureStore.features.loading) && }
{featureStore.loading || featureStore.features.loading ? null : content.length === 0 ? ( { const [selectedAlert, setSelectedAlert] = useState({}) @@ -70,6 +71,12 @@ const Alerts = () => { setSearchParams } = useAlertsPageData(alertsFilters, true) + useTableScroll({ + content: paginatedAlerts, + selectedItem: selectedAlert, + isAllVersions: true + }) + const tableContent = useMemo(() => { return paginatedAlerts.map(alert => createAlertRowData(alert, isCrossProjects)) }, [isCrossProjects, paginatedAlerts]) @@ -149,7 +156,7 @@ const Alerts = () => { withRefreshButton withoutExpandButton > - +
{alertsStore.loading && } diff --git a/src/components/Alerts/AlertsFilters.jsx b/src/components/Alerts/AlertsFilters.jsx index 6849b05603..de6ce8e86c 100644 --- a/src/components/Alerts/AlertsFilters.jsx +++ b/src/components/Alerts/AlertsFilters.jsx @@ -24,7 +24,7 @@ import PropTypes from 'prop-types' import { useForm, useFormState } from 'react-final-form' import { upperFirst } from 'lodash' -import StatusFilter from '../../common/StatusFilter/StatusFilter' +import MultiSelectFilter from '../../common/MultiSelectFilter/MultiSelectFilter' import { FormSelect, FormInput, FormOnChange } from 'igz-controls/components' import { generateProjectsList } from '../../utils/projects' @@ -127,16 +127,16 @@ const AlertsFilters = ({ isAlertsPage, isCrossProjects }) => { {(entityType === FILTER_ALL_ITEMS || entityType === MODEL_MONITORING_APPLICATION || entityType === MODEL_ENDPOINT_RESULT) && ( -
- - handleInputChange(value, ENTITY_ID)} name={ENTITY_ID} /> -
- )} +
+ + handleInputChange(value, ENTITY_ID)} name={ENTITY_ID} /> +
+ )} {entityType === JOB && (
{ )}
- +
{ return { - [NAME_FILTER]: { label: 'Alert Name:', initialValue: '', hidden: isAlertsPage }, + [NAME_FILTER]: { label: 'Alert name:', initialValue: '', hidden: isAlertsPage }, [DATES_FILTER]: { initialValue: getDatePickerFilterValue( datePickerPastOptions, isAlertsPage ? PAST_MONTH_DATE_OPTION : PAST_24_HOUR_DATE_OPTION ), - hidden: isAlertsPage, label: 'Start time:', timeFrameLimit: timeFrameLimit ? TIME_FRAME_LIMITS.MONTH : Infinity }, @@ -75,13 +75,13 @@ export const getAlertsFiltersConfig = (timeFrameLimit = false, isAlertsPage = fa initialValue: PROJECTS_FILTER_ALL_ITEMS, isModal: true }, - [ENTITY_TYPE]: { label: 'Entity Type:', initialValue: FILTER_ALL_ITEMS, isModal: true }, + [ENTITY_TYPE]: { label: 'Entity type:', initialValue: FILTER_ALL_ITEMS, isModal: true }, [ENTITY_ID]: { label: 'Entity ID:', initialValue: '', isModal: true }, [JOB_NAME]: { label: 'Job Name:', initialValue: '', isModal: true }, - [ENDPOINT_APPLICATION]: { label: 'Application Name:', initialValue: '', isModal: true }, + [ENDPOINT_APPLICATION]: { label: 'Application name:', initialValue: '', isModal: true }, [ENDPOINT_RESULT]: { label: 'Result:', initialValue: '', isModal: true }, [SEVERITY]: { label: 'Severity:', initialValue: [FILTER_ALL_ITEMS], isModal: true }, - [EVENT_TYPE]: { label: 'Event Type:', initialValue: FILTER_ALL_ITEMS, isModal: true } + [EVENT_TYPE]: { label: 'Event type:', initialValue: FILTER_ALL_ITEMS, isModal: true } } } @@ -142,7 +142,7 @@ export const filterAlertsSeverityOptions = [ const alertsEventTypeOptions = [ { label: upperFirst(FILTER_ALL_ITEMS), id: FILTER_ALL_ITEMS }, - { label: 'Job failed', id: 'failed', ENTITY_TYPE: JOB_KIND_JOB }, + { label: 'Job failed', id: FAILED_STATE, ENTITY_TYPE: JOB_KIND_JOB }, { label: 'Data drift detected', id: 'data-drift-detected', ENTITY_TYPE: MODEL_ENDPOINT_RESULT }, { label: 'Data drift suspected', id: 'data-drift-suspected', ENTITY_TYPE: MODEL_ENDPOINT_RESULT }, { @@ -201,25 +201,25 @@ export const alertsHeaders = (type, isCrossProjects) => { if (type) { const entityType = { [JOB]: [ - { label: 'Project Name', id: 'projectName', hidden: !isCrossProjects }, - { label: 'Job Name', id: 'jobName' }, + { label: 'Project name', id: 'projectName', hidden: !isCrossProjects }, + { label: 'Job name', id: 'jobName' }, { label: 'Type', id: 'type' }, { label: 'Timestamp', id: 'timestamp' }, { label: 'Severity', id: SEVERITY }, { label: 'Job', id: 'job' } ], [MODEL_ENDPOINT_RESULT]: [ - { label: 'Project Name', id: 'projectName', hidden: !isCrossProjects }, + { label: 'Project name', id: 'projectName', hidden: !isCrossProjects }, { label: 'Endpoint ID', id: 'uid' }, - { label: 'Application Name', id: 'applicationName' }, - { label: 'Result Name', id: 'resultName' }, + { label: 'Application name', id: 'applicationName' }, + { label: 'Result name', id: 'resultName' }, { label: 'Type', id: 'type' }, { label: 'Timestamp', id: 'timestamp' }, { label: 'Severity', id: SEVERITY } ], [MODEL_MONITORING_APPLICATION]: [ - { label: 'Project Name', id: 'projectName', hidden: !isCrossProjects }, - { label: 'Application Name', id: 'applicationName' }, + { label: 'Project name', id: 'projectName', hidden: !isCrossProjects }, + { label: 'Application name', id: 'applicationName' }, { label: 'Type', id: 'type' }, { label: 'Timestamp', id: 'timestamp' }, { label: 'Severity', id: SEVERITY } diff --git a/src/components/ApplicationMetrics/ApplicationMetrics.jsx b/src/components/ApplicationMetrics/ApplicationMetrics.jsx new file mode 100644 index 0000000000..58472dd585 --- /dev/null +++ b/src/components/ApplicationMetrics/ApplicationMetrics.jsx @@ -0,0 +1,364 @@ +/* +Copyright 2019 Iguazio Systems Ltd. + +Licensed under the Apache License, Version 2.0 (the "License") with +an addition restriction as set forth herein. You may not use this +file except in compliance with the License. You may obtain a copy of +the License at http://www.apache.org/licenses/LICENSE-2.0. + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +In addition, you may not use the software for any purposes that are +illegal under applicable law, and the grant of the foregoing license +under the Apache 2.0 license is conditioned upon your compliance with +such restriction. +*/ +import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react' +import { Link, useNavigate, useParams } from 'react-router-dom' +import { useDispatch, useSelector } from 'react-redux' +import { debounce, isEmpty } from 'lodash' +import { createForm } from 'final-form' +import { Form } from 'react-final-form' +import classNames from 'classnames' + +import HistoryBackLink from '../../common/HistoryBackLink/historyBackLink' +import Breadcrumbs from '../../common/Breadcrumbs/Breadcrumbs' +import DetailsMetrics from '../DetailsMetrics/DetailsMetrics' +import NoData from '../../common/NoData/NoData' +import { + Button, + FormInput, + FormOnChange, + RoundedIcon, + TextTooltipTemplate, + Tooltip, + Loader +} from 'igz-controls/components' + +import { fetchModelEndpoints } from '../../reducers/artifactsReducer' +import { + DATES_FILTER, + DETAILS_OVERVIEW_TAB, + MODEL_ENDPOINTS_TAB, + MODELS_PAGE, + MONITORING_APP_PAGE, + REQUEST_CANCELED +} from '../../constants' +import { getScssVariableValue } from 'igz-controls/utils/common.util' +import { isRowRendered, useVirtualization } from '../../hooks/useVirtualization.hook' +import { fetchMonitoringApplication } from '../../reducers/monitoringApplicationsReducer' +import { PRIMARY_BUTTON } from 'igz-controls/constants' + +import RefreshIcon from 'igz-controls/images/refresh.svg?react' +import SearchIcon from 'igz-controls/images/search.svg?react' +import PresentMetricsIcon from 'igz-controls/images/present-metrics-icon.svg?react' +import { + datePickerPastOptions, + getDatePickerFilterValue, + PAST_24_HOUR_DATE_OPTION +} from '../../utils/datePicker.util' +import { clearMetricsOptions } from '../../reducers/detailsReducer' + +import './ApplicationMetrics.scss' + +export const LIST_ID = 'LIST_ID' +export const LIST_ITEMS_ID = 'LIST_ITEMS_ID' + +const ApplicationMetrics = () => { + const [requestErrorMessage, setRequestErrorMessage] = useState('') + const [selectedModelEndpoint, setSelectedModelEndpoint] = useState({}) + const [modelEndpoints, setModelEndpoints] = useState([]) + const [searchName, setSearchName] = useState('') + const detailsStore = useSelector(store => store.detailsStore) + const artifactsStore = useSelector(store => store.artifactsStore) + const applicationsStore = useSelector(store => store.monitoringApplicationsStore) + const dispatch = useDispatch() + const navigate = useNavigate() + const params = useParams() + const abortControllerRef = useRef() + + const filteredEndpoints = useMemo(() => { + return modelEndpoints.filter(modelEndpoint => { + return !searchName || modelEndpoint.name?.toLowerCase()?.includes(searchName.toLowerCase()) + }) + }, [modelEndpoints, searchName]) + + const listItemHeight = useMemo(() => getScssVariableValue('--listItemHeight'), []) + const searchHeight = useMemo(() => getScssVariableValue('--searchHeight'), []) + + const rowsSizes = useMemo( + () => new Array(filteredEndpoints.length).fill(parseInt(listItemHeight)), + [listItemHeight, filteredEndpoints.length] + ) + const heightData = useMemo( + () => ({ + headerRowHeight: searchHeight, + rowHeight: listItemHeight, + rowHeightExtended: listItemHeight + }), + [listItemHeight, searchHeight] + ) + + const virtualizationConfig = useVirtualization({ + renderTriggerItem: modelEndpoints, + heightData, + rowsSizes, + tableBodyId: LIST_ID, + tableId: LIST_ITEMS_ID + }) + + const formRef = React.useRef( + createForm({ + initialValues: { + MEPSearchName: '' + }, + onSubmit: () => {} + }) + ) + + const fetchModelEndpointsData = useCallback(() => { + abortControllerRef.current = new AbortController() + + dispatch( + fetchModelEndpoints({ + project: params.projectName, + filters: {}, + config: { + ui: { + controller: abortControllerRef.current, + setRequestErrorMessage + } + }, + params: { + latest_only: 'True' + } + }) + ) + .unwrap() + .then(modelEndpoints => { + if (modelEndpoints) { + setModelEndpoints(modelEndpoints) + } + }) + }, [dispatch, params.projectName]) + + const setSearchNameDebounced = useMemo( + () => + debounce(name => { + setSearchName(name) + }, 500), + [setSearchName] + ) + + useEffect(() => { + if ( + applicationsStore.monitoringApplications.applications?.find( + app => app.name.toLowerCase() === params.appName.toLowerCase() + ) + ) { + fetchModelEndpointsData() + } else { + dispatch( + fetchMonitoringApplication({ + project: params.projectName, + functionName: params.appName, + filters: { + [DATES_FILTER]: getDatePickerFilterValue( + datePickerPastOptions, + PAST_24_HOUR_DATE_OPTION, + false + ) + } + }) + ) + .unwrap() + .then(app => { + if (!isEmpty(app)) { + fetchModelEndpointsData() + } else { + navigate( + `/projects/${params.projectName}/${MONITORING_APP_PAGE}${window.location.search}`, + { replace: true } + ) + } + }) + .catch(() => { + navigate( + `/projects/${params.projectName}/${MONITORING_APP_PAGE}${window.location.search}`, + { replace: true } + ) + }) + } + + return () => { + abortControllerRef.current?.abort?.(REQUEST_CANCELED) + } + + // navigate triggers this use effect when we select first item in the list if id is not in the URL + // if adding new deps, please double check it by removing next comment + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [ + applicationsStore.monitoringApplications.applications, + dispatch, + fetchModelEndpointsData, + params.appName, + params.projectName + ]) + + useEffect(() => { + if (params.id && modelEndpoints.length > 0) { + const searchItem = modelEndpoints.find(item => item.metadata?.uid === params.id) + + if (!searchItem) { + navigate( + `/projects/${params.projectName}/${MONITORING_APP_PAGE}/${params.appName}/${MODEL_ENDPOINTS_TAB}/${modelEndpoints[0].metadata.uid}${window.location.search}`, + { replace: true } + ) + } else { + setSelectedModelEndpoint(searchItem) + } + } else if (modelEndpoints.length > 0) { + navigate( + `/projects/${params.projectName}/${MONITORING_APP_PAGE}/${params.appName}/${MODEL_ENDPOINTS_TAB}/${modelEndpoints[0].metadata.uid}${window.location.search}`, + { replace: true } + ) + } else { + setSelectedModelEndpoint({}) + } + }, [dispatch, modelEndpoints, navigate, params.id, params.appName, params.projectName]) + + useEffect(()=> { + return () => { + dispatch(clearMetricsOptions()) + } + }, [dispatch]) + + return ( +
+
+ +
+
+
+
+ } + /> +
+
+
+
+ {(artifactsStore.modelEndpoints.loading || + applicationsStore.loading || + detailsStore.loadingCounter > 0) && } + {artifactsStore.modelEndpoints.loading || + applicationsStore.loading ? null : modelEndpoints.length === 0 ? ( + + ) : ( + <> +
+ {}}> + {() => ( +
+
+ } + name="MEPSearchName" + placeholder="Search endpoint..." + /> + +
+
{`${filteredEndpoints.length} endpoint${filteredEndpoints.length !== 1 ? 's' : ''} found`}
+
+ )} + +
+
+
    + {filteredEndpoints.map((modelEndpoint, modelEndpointIndex) => { + return ( + isRowRendered(virtualizationConfig, modelEndpointIndex) && ( +
  • + + } + > + {modelEndpoint.name} + + +
  • + ) + ) + })} +
+
+
+
+
+
+
+ {!isEmpty(selectedModelEndpoint) && ( + ( + + } + > + {selectedModelEndpoint.name} + + + )} + /> + )} +
+
+
+ + )} +
+
+
+
+ ) +} + +export default ApplicationMetrics diff --git a/src/components/ApplicationMetrics/ApplicationMetrics.scss b/src/components/ApplicationMetrics/ApplicationMetrics.scss new file mode 100644 index 0000000000..9d2340155b --- /dev/null +++ b/src/components/ApplicationMetrics/ApplicationMetrics.scss @@ -0,0 +1,124 @@ +@use 'igz-controls/scss/shadows'; +@use 'igz-controls/scss/colors'; +@use 'igz-controls/scss/borders'; + +$listItemHeight: 52px; +$searchHeight: 75px; + +:root { + --listItemHeight: #{$listItemHeight}; + --searchHeight: #{$searchHeight}; +} + +.application-metrics-container { + height: 100%; + + .content__action-bar-wrapper { + margin-bottom: 10px; + + .action-bar { + gap: 15px; + align-items: center; + } + } + + .list-view { + display: flex; + gap: 20px; + height: calc(100% - 60px); + + .list-view__section { + width: 100%; + height: 100%; + padding: 16px; + background-color: colors.$white; + border: borders.$primaryBorder; + border-radius: 8px; + box-shadow: shadows.$previewBoxShadowInit; + } + + .list-view__section-list { + position: relative; + display: flex; + flex-direction: column; + align-items: center; + justify-content: flex-start; + width: 270px; + min-width: 270px; + max-width: 270px; + + .list-view__section-list__search { + height: $searchHeight; + + .list-view__section-list__search_endpoints-counter { + color: colors.$topaz; + font-weight: 500; + font-size: 13px; + line-height: 35px; + } + } + + .list-view__section-list__items-wrapper { + position: relative; + width: 100%; + height: 100%; + + .list-view__section-list__items { + position: absolute; + width: 100%; + height: 100%; + overflow-y: auto; + + ul { + margin: 0; + padding: 0; + list-style: none; + + li { + padding: 0 8px; + cursor: pointer; + user-select: none; + + div { + height: $listItemHeight; + line-height: $listItemHeight; + border-bottom: borders.$tableRowBorder; + } + + &:hover, + &.active { + background-color: colors.$ghostWhite; + } + } + + li:last-child { + div { + border-bottom: none; + } + } + } + } + } + } + + .list-view__section-details { + position: relative; + min-width: 700px; + + .list-view__section__metrics-content-wrapper { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + padding: 20px; + + .list-view__section__metrics-content { + height: 100%; + padding-right: 20px; + overflow-y: auto; + } + } + } + } +} diff --git a/src/components/ArtifactInfoSources/ArtifactInfoSources.jsx b/src/components/ArtifactInfoSources/ArtifactInfoSources.jsx index fc2a230a84..9b5ce8da37 100644 --- a/src/components/ArtifactInfoSources/ArtifactInfoSources.jsx +++ b/src/components/ArtifactInfoSources/ArtifactInfoSources.jsx @@ -22,13 +22,12 @@ import PropTypes from 'prop-types' import FeatureVectorPopUp from '../../elements/DetailsPopUp/FeatureVectorPopUp/FeatureVectorPopUp' import ArtifactPopUp from '../../elements/DetailsPopUp/ArtifactPopUp/ArtifactPopUp' -import { Tooltip, TextTooltipTemplate } from 'igz-controls/components' +import { Tooltip, TextTooltipTemplate, CopyToClipboard } from 'igz-controls/components' import { openPopUp } from 'igz-controls/utils/common.util' import { FEATURE_VECTORS_TAB } from '../../constants' import './artifactInfoSources.scss' -import CopyToClipboard from '../../common/CopyToClipboard/CopyToClipboard' const ArtifactInfoSources = ({ isDetailsPopUp = false, sources = {} }) => { const handleOpenSourceDetails = sourceData => { diff --git a/src/components/ArtifactInfoSources/artifactInfoSources.scss b/src/components/ArtifactInfoSources/artifactInfoSources.scss index 60e988a157..9ccc5bf3cd 100644 --- a/src/components/ArtifactInfoSources/artifactInfoSources.scss +++ b/src/components/ArtifactInfoSources/artifactInfoSources.scss @@ -39,8 +39,8 @@ display: inline-block; flex: 1 1; min-width: 110px; - word-break: break-word; color: colors.$topaz; + word-break: break-word; &__copy-to-clipboard { display: flex; diff --git a/src/components/Artifacts/Artifacts.jsx b/src/components/Artifacts/Artifacts.jsx index aa398a1e40..4bf940a671 100644 --- a/src/components/Artifacts/Artifacts.jsx +++ b/src/components/Artifacts/Artifacts.jsx @@ -21,17 +21,13 @@ such restriction. import { useCallback, useEffect, useMemo, useRef, useState } from 'react' import { useDispatch, useSelector } from 'react-redux' import { useLocation, useNavigate, useParams } from 'react-router-dom' +import { chain, isEmpty, isNil } from 'lodash' import PropTypes from 'prop-types' +import AddArtifactTagPopUp from '../../elements/AddArtifactTagPopUp/AddArtifactTagPopUp' import ArtifactsView from './ArtifactsView' +import DeployModelPopUp from '../../elements/DeployModelPopUp/DeployModelPopUp' -import { getViewMode } from '../../utils/helper' -import { getSavedSearchParams, transformSearchParams } from '../../utils/filter.util' -import { getFiltersConfig } from './artifacts.util' -import { useFiltersFromSearchParams } from '../../hooks/useFiltersFromSearchParams.hook' -import { useRefreshAfterDelete } from '../../hooks/useRefreshAfterDelete.hook' -import { getCloseDetailsLink, isDetailsTabExists } from '../../utils/link-helper.util' -import { openPopUp } from 'igz-controls/utils/common.util' import { ALL_VERSIONS_PATH, BE_PAGE, @@ -44,18 +40,22 @@ import { TAG_FILTER, TAG_FILTER_ALL_ITEMS } from '../../constants' -import { toggleYaml } from '../../reducers/appReducer' -import { chain, isEmpty, isNil } from 'lodash' +import { checkForSelectedArtifact } from '../../utils/artifacts.util' import { fetchArtifactsFunctions, fetchArtifactTags } from '../../reducers/artifactsReducer' -import { getFilterTagOptions, setFilters } from '../../reducers/filtersReducer' -import AddArtifactTagPopUp from '../../elements/AddArtifactTagPopUp/AddArtifactTagPopUp' -import DeployModelPopUp from '../../elements/DeployModelPopUp/DeployModelPopUp' -import { setNotification } from '../../reducers/notificationReducer' -import { usePagination } from '../../hooks/usePagination.hook' -import { checkForSelectedArtifact, setFullSelectedArtifact } from '../../utils/artifacts.util' -import { getFeatureVectorData } from '../ModelsPage/Models/models.util' import { fetchModelFeatureVector } from '../../reducers/detailsReducer' +import { getCloseDetailsLink, isDetailsTabExists } from '../../utils/link-helper.util' +import { getFeatureVectorData } from '../ModelsPage/Models/models.util' +import { getFilterTagOptions, setFilters } from '../../reducers/filtersReducer' +import { getFiltersConfig } from './artifacts.util' +import { getSavedSearchParams, transformSearchParams } from 'igz-controls/utils/filter.util' +import { openPopUp, getViewMode } from 'igz-controls/utils/common.util' +import { setNotification } from 'igz-controls/reducers/notificationReducer' +import { toggleYaml } from '../../reducers/appReducer' +import { useFiltersFromSearchParams } from '../../hooks/useFiltersFromSearchParams.hook' import { useMode } from '../../hooks/mode.hook' +import { usePagination } from '../../hooks/usePagination.hook' +import { useRefreshAfterDelete } from '../../hooks/useRefreshAfterDelete.hook' +import { useTableScroll } from 'igz-controls/hooks/useTable.hook' const Artifacts = ({ actionButtons = [], @@ -65,6 +65,7 @@ const Artifacts = ({ generateActionsMenu, generateDetailsFormInitialValues, generatePageData, + getArtifactFiltersConfig = null, handleApplyDetailsChanges, handleDeployArtifactFailure = null, isAllVersions = false, @@ -101,17 +102,25 @@ const Artifacts = ({ `/projects/${params.projectName}/${page}${tab ? `/${tab}` : ''}${getSavedSearchParams(location.search)}`, [location.search, page, params.projectName, tab] ) - const filtersConfig = useMemo(() => getFiltersConfig(isAllVersions), [isAllVersions]) + const filtersConfig = useMemo( + () => (getArtifactFiltersConfig || getFiltersConfig)(isAllVersions), + [getArtifactFiltersConfig, isAllVersions] + ) const artifactsFilters = useFiltersFromSearchParams(filtersConfig) const [refreshAfterDeleteCallback, refreshAfterDeleteTrigger] = useRefreshAfterDelete( paginationConfigArtifactVersionsRef, historyBackLink, 'artifacts', - params.id && getCloseDetailsLink(isAllVersions ? ALL_VERSIONS_PATH : tab || page, true), + params.id && + getCloseDetailsLink( + isAllVersions ? ALL_VERSIONS_PATH : tab || page, + true, + params.artifactName + ), isAllVersions ) const pageData = useMemo( - () => generatePageData(viewMode, selectedArtifact, params, false, isDemoMode), + () => generatePageData(viewMode, false, selectedArtifact, params, isDemoMode), [generatePageData, isDemoMode, params, selectedArtifact, viewMode] ) const detailsFormInitialValues = useMemo(() => { @@ -383,6 +392,12 @@ const Artifacts = ({ resetPaginationTrigger: `${params.projectName}_${isAllVersions}` }) + useTableScroll({ + content: isAllVersions ? paginatedArtifactVersions : paginatedArtifacts, + selectedItem: selectedArtifact, + isAllVersions + }) + const tableContent = useMemo(() => { return (isAllVersions ? paginatedArtifactVersions : paginatedArtifacts).map(contentItem => createArtifactsRowData(contentItem, params.projectName, isAllVersions) @@ -397,29 +412,6 @@ const Artifacts = ({ const tableHeaders = useMemo(() => tableContent[0]?.content ?? [], [tableContent]) - const getAndSetSelectedArtifact = useCallback(() => { - setFullSelectedArtifact( - page, - tab, - dispatch, - navigate, - params.artifactName, - setSelectedArtifact, - params.projectName, - params.id, - isAllVersions - ) - }, [ - page, - tab, - dispatch, - navigate, - params.artifactName, - params.projectName, - params.id, - isAllVersions - ]) - useEffect(() => { if (params.id && pageData.details.menu.length > 0) { isDetailsTabExists(params.tab, pageData.details.menu, navigate, location) @@ -432,11 +424,12 @@ const Artifacts = ({ } }, [selectedArtifact]) - useEffect(() => { + const getAndSetSelectedArtifact = useCallback((ignoreLastCheckedArtifact = false) => { checkForSelectedArtifact({ artifactName: params.artifactName, artifacts: isAllVersions ? artifactVersions : artifacts, dispatch, + ignoreLastCheckedArtifact, isAllVersions, navigate, paginatedArtifacts: isAllVersions ? paginatedArtifactVersions : paginatedArtifacts, @@ -472,6 +465,8 @@ const Artifacts = ({ tab ]) + useEffect(() => getAndSetSelectedArtifact(true), [getAndSetSelectedArtifact]) + useEffect(() => { const tagAbortControllerCurrent = tagAbortControllerRef.current @@ -562,6 +557,7 @@ Artifacts.propTypes = { generateActionsMenu: PropTypes.func.isRequired, generateDetailsFormInitialValues: PropTypes.func.isRequired, generatePageData: PropTypes.func.isRequired, + getArtifactFiltersConfig: PropTypes.func, handleApplyDetailsChanges: PropTypes.func.isRequired, handleDeployArtifactFailure: PropTypes.func, isAllVersions: PropTypes.bool, diff --git a/src/components/Artifacts/ArtifactsTable.jsx b/src/components/Artifacts/ArtifactsTable.jsx index 451df06d23..d536e922bc 100644 --- a/src/components/Artifacts/ArtifactsTable.jsx +++ b/src/components/Artifacts/ArtifactsTable.jsx @@ -22,7 +22,6 @@ import PropTypes from 'prop-types' import { isEmpty } from 'lodash' import NoData from '../../common/NoData/NoData' -import Loader from '../../common/Loader/Loader' import Table from '../Table/Table' import ArtifactsFilters from '../ArtifactsActionBar/ArtifactsFilters' import ActionBar from '../ActionBar/ActionBar' @@ -30,11 +29,13 @@ import HistoryBackLink from '../../common/HistoryBackLink/historyBackLink' import Details from '../Details/Details' import ArtifactsTableRow from '../../elements/ArtifactsTableRow/ArtifactsTableRow' import Pagination from '../../common/Pagination/Pagination' +import { Loader } from 'igz-controls/components' -import { getNoDataMessage } from '../../utils/getNoDataMessage' -import { ALL_VERSIONS_PATH, FULL_VIEW_MODE } from '../../constants' +import { ALL_VERSIONS_PATH } from '../../constants' +import { FULL_VIEW_MODE } from 'igz-controls/constants' import { getCloseDetailsLink } from '../../utils/link-helper.util' import { getDefaultFirstHeader } from '../../utils/createArtifactsContent' +import { getNoDataMessage } from '../../utils/getNoDataMessage' let ArtifactsTable = ({ actionButtons, @@ -67,10 +68,22 @@ let ArtifactsTable = ({ tableHeaders, viewMode }) => { + const renderHistoryBackLink = () => { + if (!isAllVersions) return null + + return isOnlyTabScreen ? ( +
+ +
+ ) : ( + + ) + } + return (
- {renderPageTabs && renderPageTabs()} + {renderPageTabs ? renderPageTabs() : renderHistoryBackLink()} - +
- {isAllVersions && - (isOnlyTabScreen ? ( -
- -
- ) : ( - - ))} + {renderPageTabs && renderHistoryBackLink()} {artifactsStore.loading ? null : tableContent.length === 0 && isEmpty(selectedArtifact) ? ( - getCloseDetailsLink(isAllVersions ? ALL_VERSIONS_PATH : tab || page) + getCloseDetailsLink( + isAllVersions ? ALL_VERSIONS_PATH : tab || page, + false, + artifactName + ) } handleCancel={() => setSelectedArtifact({})} pageData={pageData} @@ -138,6 +153,7 @@ let ArtifactsTable = ({ )} diff --git a/src/components/Artifacts/ArtifactsView.jsx b/src/components/Artifacts/ArtifactsView.jsx index 283a9ffb10..2168b061f7 100644 --- a/src/components/Artifacts/ArtifactsView.jsx +++ b/src/components/Artifacts/ArtifactsView.jsx @@ -22,8 +22,8 @@ import PropTypes from 'prop-types' import ArtifactsTable from './ArtifactsTable' import Breadcrumbs from '../../common/Breadcrumbs/Breadcrumbs' -import Loader from '../../common/Loader/Loader' import PreviewModal from '../../elements/PreviewModal/PreviewModal' +import { Loader } from 'igz-controls/components' import './artifacts.scss' diff --git a/src/components/Artifacts/artifacts.scss b/src/components/Artifacts/artifacts.scss index 9a5c65d1db..b26b375d43 100644 --- a/src/components/Artifacts/artifacts.scss +++ b/src/components/Artifacts/artifacts.scss @@ -1,5 +1,5 @@ @use 'igz-controls/scss/variables'; -@use '/src/scss/mixins'; +@use '@/scss/mixins'; $artifactsRowHeight: variables.$rowHeight; $artifactsHeaderRowHeight: variables.$headerRowHeight; diff --git a/src/components/Artifacts/artifacts.util.js b/src/components/Artifacts/artifacts.util.js index d147343d62..79e58a65a3 100644 --- a/src/components/Artifacts/artifacts.util.js +++ b/src/components/Artifacts/artifacts.util.js @@ -36,7 +36,7 @@ export const getFiltersConfig = isAllVersions => ({ }, [LABELS_FILTER]: { label: 'Labels:', initialValue: '', isModal: true }, [ITERATIONS_FILTER]: { - label: 'Show best iteration only:', + label: 'Show best iteration only', initialValue: isAllVersions ? '' : SHOW_ITERATIONS, isModal: true } diff --git a/src/components/ArtifactsActionBar/ArtifactsFilters.jsx b/src/components/ArtifactsActionBar/ArtifactsFilters.jsx index e9599c2fd4..95f567e577 100644 --- a/src/components/ArtifactsActionBar/ArtifactsFilters.jsx +++ b/src/components/ArtifactsActionBar/ArtifactsFilters.jsx @@ -17,51 +17,100 @@ illegal under applicable law, and the grant of the foregoing license under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ -import React from 'react' +import React, { useState } from 'react' import { useForm } from 'react-final-form' import PropTypes from 'prop-types' import { FormInput, FormCheckBox, FormOnChange } from 'igz-controls/components' import FormTagFilter from '../../common/FormTagFilter/FormTagFilter' -import { ITERATIONS_FILTER, LABELS_FILTER, SHOW_ITERATIONS, TAG_FILTER } from '../../constants' +import { + ITERATIONS_FILTER, + LABELS_FILTER, + MODEL_NAME_FILTER, + MODEL_TAG_FILTER, + SHOW_ITERATIONS, + TAG_FILTER +} from '../../constants' + +import SearchIcon from 'igz-controls/images/search.svg?react' import './artifactsFilters.scss' -const ArtifactsFilters = ({ artifacts, isAllVersions }) => { +const ArtifactsFilters = ({ artifacts, filtersConfig, isAllVersions }) => { const form = useForm() + const [modelName, setModelName] = useState(form.getState().values[MODEL_NAME_FILTER] || '') const handleIter = value => { form.change(ITERATIONS_FILTER, value ? SHOW_ITERATIONS : '') } - const handleLabelsChange = value => { - form.change(LABELS_FILTER, value || '') + const handleInputChange = (value, filterName) => { + form.change(filterName, value || '') + } + + const handleModelNameChange = value => { + form.change(MODEL_NAME_FILTER, value || '') + setModelName(value) + + if (value.length === 0) { + form.change(MODEL_TAG_FILTER, '') + } } return (
- + handleInputChange(value, LABELS_FILTER)} + />
+ {filtersConfig[MODEL_NAME_FILTER] && ( + <> +
+ } + name={MODEL_NAME_FILTER} + placeholder="Search model name.." + /> + +
+
+ 0 ? : null} + name={MODEL_TAG_FILTER} + placeholder="All tags" + disabled={modelName.length === 0} + tip={modelName.length === 0 ? 'Enter a model name to enable field.' : null} + /> + handleInputChange(value, MODEL_TAG_FILTER)} + /> +
+ + )}
@@ -72,6 +121,7 @@ const ArtifactsFilters = ({ artifacts, isAllVersions }) => { ArtifactsFilters.propTypes = { artifacts: PropTypes.arrayOf(PropTypes.object).isRequired, + filtersConfig: PropTypes.object.isRequired, isAllVersions: PropTypes.bool.isRequired } diff --git a/src/components/ArtifactsPreview/ArtifactsPreview.jsx b/src/components/ArtifactsPreview/ArtifactsPreview.jsx index 2ad5abc0f4..28c9f1bf9a 100644 --- a/src/components/ArtifactsPreview/ArtifactsPreview.jsx +++ b/src/components/ArtifactsPreview/ArtifactsPreview.jsx @@ -22,8 +22,8 @@ import PropTypes from 'prop-types' import classnames from 'classnames' import ArtifactsPreviewView from './ArtifactsPreviewView' -import Loader from '../../common/Loader/Loader' import NoData from '../../common/NoData/NoData' +import { Loader } from 'igz-controls/components' const ArtifactsPreview = ({ className = '', noData, preview }) => { const [showErrorBody, setShowErrorBody] = useState(false) diff --git a/src/components/ArtifactsPreview/ArtifactsPreviewView.jsx b/src/components/ArtifactsPreview/ArtifactsPreviewView.jsx index 3b9b2fcb4a..85a61ba9ec 100644 --- a/src/components/ArtifactsPreview/ArtifactsPreviewView.jsx +++ b/src/components/ArtifactsPreview/ArtifactsPreviewView.jsx @@ -26,7 +26,7 @@ import PreviewError from './PreviewError/PreviewError' import { Tooltip, TextTooltipTemplate } from 'igz-controls/components' import WarningMessage from '../../common/WarningMessage/WarningMessage' -import { ARTIFACT_PREVIEW_TABLE_ROW_LIMIT, ERROR_STATE } from '../../constants' +import { ARTIFACT_PREVIEW_TABLE_ROW_LIMIT, ERROR_STATE, UNKNOWN_STATE } from '../../constants' import './artifactsPreview.scss' @@ -145,7 +145,7 @@ const ArtifactsPreviewView = ({ className, preview, setShowErrorBody, showErrorB alt="preview" /> )} - {preview?.type === 'unknown' && ( + {preview?.type === UNKNOWN_STATE && (

{preview?.data?.content ? preview?.data.content : 'No preview'}

diff --git a/src/components/ArtifactsPreview/artifactsPreview.scss b/src/components/ArtifactsPreview/artifactsPreview.scss index 9c8feb71c2..bbcc290cba 100644 --- a/src/components/ArtifactsPreview/artifactsPreview.scss +++ b/src/components/ArtifactsPreview/artifactsPreview.scss @@ -20,7 +20,7 @@ &-title { display: flex; align-items: center; - margin: 0 0 15px 0; + margin: 0 0 15px; color: colors.$topaz; font-weight: 500; font-size: 20px; diff --git a/src/components/ArtifactsPreview/artifactsPreviewController.scss b/src/components/ArtifactsPreview/artifactsPreviewController.scss index 9a9f12a7f3..94573d135a 100644 --- a/src/components/ArtifactsPreview/artifactsPreviewController.scss +++ b/src/components/ArtifactsPreview/artifactsPreviewController.scss @@ -10,11 +10,11 @@ } .icon-popout { - text-align: end; - cursor: pointer; - min-height: 40px; width: 100%; height: auto; - padding: 0; + min-height: 40px; margin-bottom: 10px; + padding: 0; + text-align: end; + cursor: pointer; } diff --git a/src/components/ConsumerGroup/ConsumerGroup.jsx b/src/components/ConsumerGroup/ConsumerGroup.jsx index 43156676f8..be29d755ba 100644 --- a/src/components/ConsumerGroup/ConsumerGroup.jsx +++ b/src/components/ConsumerGroup/ConsumerGroup.jsx @@ -22,13 +22,12 @@ import { useDispatch, useSelector } from 'react-redux' import { isEmpty } from 'lodash' import { useParams } from 'react-router-dom' -import Loader from '../../common/Loader/Loader' +import ConsumerGroupShardLagTableRow from '../../elements/ConsumerGroupShardLagTableRow/ConsumerGroupShardLagTableRow' import NoData from '../../common/NoData/NoData' import PageHeader from '../../elements/PageHeader/PageHeader' -import Table from '../Table/Table' -import { RoundedIcon } from 'igz-controls/components' -import ConsumerGroupShardLagTableRow from '../../elements/ConsumerGroupShardLagTableRow/ConsumerGroupShardLagTableRow' import Search from '../../common/Search/Search' +import Table from '../Table/Table' +import { RoundedIcon, Loader } from 'igz-controls/components' import { CONSUMER_GROUP_PAGE, @@ -38,7 +37,7 @@ import createConsumerGroupContent from '../../utils/createConsumerGroupContent' import { fetchNuclioV3ioStreamShardLags, resetV3ioStreamShardLagsError } from '../../reducers/nuclioReducer.js' import { generatePageData } from './consumerGroup.util.js' import { getNoDataMessage } from '../../utils/getNoDataMessage' -import { showErrorNotification } from '../../utils/notifications.util' +import { showErrorNotification } from 'igz-controls/utils/notification.util' import RefreshIcon from 'igz-controls/images/refresh.svg?react' diff --git a/src/components/ConsumerGroups/ConsumerGroups.jsx b/src/components/ConsumerGroups/ConsumerGroups.jsx index 5f86492ffd..099c79b4a9 100644 --- a/src/components/ConsumerGroups/ConsumerGroups.jsx +++ b/src/components/ConsumerGroups/ConsumerGroups.jsx @@ -21,12 +21,12 @@ import React, { useEffect, useMemo, useState } from 'react' import { useDispatch, useSelector } from 'react-redux' import { useParams, useOutletContext } from 'react-router-dom' -import Loader from '../../common/Loader/Loader' import NoData from '../../common/NoData/NoData' import PageHeader from '../../elements/PageHeader/PageHeader' import Search from '../../common/Search/Search' import Table from '../Table/Table' import ConsumerGroupTableRow from '../../elements/ConsumerGroupTableRow/ConsumerGroupTableRow' +import { Loader } from 'igz-controls/components' import createConsumerGroupsContent from '../../utils/createConsumerGroupsContent' import { CONSUMER_GROUPS_PAGE, GROUP_BY_NONE, NAME_FILTER } from '../../constants' diff --git a/src/components/ConsumerGroupsWrapper/ConsumerGroupsWrapper.jsx b/src/components/ConsumerGroupsWrapper/ConsumerGroupsWrapper.jsx index e43c882ced..42957a1e37 100644 --- a/src/components/ConsumerGroupsWrapper/ConsumerGroupsWrapper.jsx +++ b/src/components/ConsumerGroupsWrapper/ConsumerGroupsWrapper.jsx @@ -22,14 +22,14 @@ import { useNavigate, useParams, Outlet } from 'react-router-dom' import { useDispatch, useSelector } from 'react-redux' import { isEmpty } from 'lodash' +import { Loader } from 'igz-controls/components' import Breadcrumbs from '../../common/Breadcrumbs/Breadcrumbs' -import Loader from '../../common/Loader/Loader' import { GROUP_BY_NONE } from '../../constants' import { areNuclioStreamsEnabled } from '../../utils/helper' import { fetchNuclioV3ioStreams, resetV3ioStreamsError } from '../../reducers/nuclioReducer' import { setFilters } from '../../reducers/filtersReducer' -import { showErrorNotification } from '../../utils/notifications.util' +import { showErrorNotification } from 'igz-controls/utils/notification.util' const ConsumerGroupsWrapper = () => { const [requestErrorMessage, setRequestErrorMessage] = useState('') diff --git a/src/components/Datasets/datasets.util.jsx b/src/components/Datasets/datasets.util.jsx index 7ce396d648..cc2319809b 100644 --- a/src/components/Datasets/datasets.util.jsx +++ b/src/components/Datasets/datasets.util.jsx @@ -22,21 +22,23 @@ import React from 'react' import JobWizard from '../JobWizard/JobWizard' import DeleteArtifactPopUp from '../../elements/DeleteArtifactPopUp/DeleteArtifactPopUp' +import { ARTIFACT_MAX_DOWNLOAD_SIZE, DATASET_TYPE, DATASETS_PAGE } from '../../constants' +import { PRIMARY_BUTTON, FULL_VIEW_MODE } from 'igz-controls/constants' import { - ARTIFACT_MAX_DOWNLOAD_SIZE, - DATASET_TYPE, - DATASETS_PAGE, - FULL_VIEW_MODE -} from '../../constants' -import { PRIMARY_BUTTON } from 'igz-controls/constants' -import { applyTagChanges, chooseOrFetchArtifact } from '../../utils/artifacts.util' -import { copyToClipboard } from '../../utils/copyToClipboard' + applyTagChanges, + chooseOrFetchArtifact, + processActionAfterTagUniquesValidation +} from '../../utils/artifacts.util' import { getIsTargetPathValid } from '../../utils/createArtifactsContent' import { showArtifactsPreview } from '../../reducers/artifactsReducer' import { generateUri } from '../../utils/resources' import { handleDeleteArtifact } from '../../utils/handleDeleteArtifact' -import { openPopUp, openDeleteConfirmPopUp } from 'igz-controls/utils/common.util' +import { openPopUp, openDeleteConfirmPopUp, copyToClipboard } from 'igz-controls/utils/common.util' import { setDownloadItem, setShowDownloadsList } from '../../reducers/downloadReducer' +import { + decreaseDetailsLoadingCounter, + increaseDetailsLoadingCounter +} from '../../reducers/detailsReducer' import TagIcon from 'igz-controls/images/tag-icon.svg?react' import YamlIcon from 'igz-controls/images/yaml.svg?react' @@ -65,7 +67,7 @@ export const infoHeaders = [ export const registerDatasetTitle = 'Register dataset' -export const generateDataSetsDetailsMenu = (selectedItem, isDemoMode) => [ +export const generateDataSetsDetailsMenu = selectedItem => [ { label: 'overview', id: 'overview' @@ -82,21 +84,15 @@ export const generateDataSetsDetailsMenu = (selectedItem, isDemoMode) => [ { label: 'analysis', id: 'analysis', - hidden: !isDemoMode || !selectedItem?.extra_data + hidden: !selectedItem?.extra_data } ] -export const generatePageData = ( - viewMode, - selectedItem, - params, - isDetailsPopUp = false, - isDemoMode -) => { +export const generatePageData = (viewMode, isDetailsPopUp = false, selectedItem, params) => { return { page: DATASETS_PAGE, details: { - menu: generateDataSetsDetailsMenu(selectedItem, isDemoMode), + menu: generateDataSetsDetailsMenu(selectedItem), infoHeaders, type: DATASETS_PAGE, hideBackBtn: viewMode === FULL_VIEW_MODE && !isDetailsPopUp, @@ -129,7 +125,17 @@ export const handleApplyDetailsChanges = ( setNotification, dispatch ) => { - return applyTagChanges(changes, selectedItem, projectName, dispatch, setNotification) + return processActionAfterTagUniquesValidation({ + tag: changes?.data?.tag?.currentFieldValue, + artifact: selectedItem, + projectName, + dispatch, + actionCallback: () => + applyTagChanges(changes, selectedItem, projectName, dispatch, setNotification), + throwError: true, + showLoader: () => dispatch(increaseDetailsLoadingCounter()), + hideLoader: () => dispatch(decreaseDetailsLoadingCounter()) + }) } export const generateActionsMenu = ( diff --git a/src/components/Details/Details.jsx b/src/components/Details/Details.jsx index b99e4bfb04..10617d5f5e 100644 --- a/src/components/Details/Details.jsx +++ b/src/components/Details/Details.jsx @@ -17,23 +17,12 @@ illegal under applicable law, and the grant of the foregoing license under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ -import React, { useEffect, useCallback, useRef, useMemo, useState } from 'react' +import React, { useEffect, useCallback } from 'react' import PropTypes from 'prop-types' -import { useLocation, useParams } from 'react-router-dom' import { useDispatch, useSelector } from 'react-redux' -import { createForm } from 'final-form' -import arrayMutators from 'final-form-arrays' -import { Form } from 'react-final-form' -import { cloneDeep, isEqual, pickBy } from 'lodash' -import classnames from 'classnames' -import { ConfirmDialog } from 'igz-controls/components' -import ErrorMessage from '../../common/ErrorMessage/ErrorMessage' -import DetailsTabsContent from './DetailsTabsContent/DetailsTabsContent' import DetailsHeader from './DetailsHeader/DetailsHeader' -import Loader from '../../common/Loader/Loader' -import TabsSlider from '../../common/TabsSlider/TabsSlider' -import BlockerSpy from '../../common/BlockerSpy/BlockerSpy' +import DetailsTabsContent from './DetailsTabsContent/DetailsTabsContent' import { ALERTS_PAGE, @@ -47,8 +36,7 @@ import { JOBS_PAGE, LLM_PROMPTS_PAGE, MODEL_ENDPOINTS_TAB, - MODELS_TAB, - VIEW_SEARCH_PARAMETER + MODELS_TAB } from '../../constants' import { generateAlertsContent, @@ -57,24 +45,13 @@ import { generateFunctionsContent, generateJobsContent } from './details.util' -import { - removeDetailsPopUpInfoContent, - removeInfoContent, - removeModelFeatureVector, - resetChanges, - setDetailsPopUpInfoContent, - setEditMode, - setFiltersWasHandled, - setInfoContent, - showWarning -} from '../../reducers/detailsReducer' -import { ACTIONS_MENU } from '../../types' -import { TERTIARY_BUTTON, PRIMARY_BUTTON } from 'igz-controls/constants' +import { DETAILS_MENU, ACTIONS_MENU } from 'igz-controls/types' import { isEveryObjectValueEmpty } from '../../utils/isEveryObjectValueEmpty' -import { setFieldState } from 'igz-controls/utils/form.util' +import { removeModelFeatureVector } from '../../reducers/detailsReducer' import { showArtifactsPreview } from '../../reducers/artifactsReducer' +import { useDetails } from 'igz-controls/hooks/useDetails.hook' -import './details.scss' +import 'igz-controls/scss/details.scss' const Details = ({ actionsMenu, @@ -94,37 +71,36 @@ const Details = ({ tab = '', withActionMenu = true }) => { - const [blocker, setBlocker] = useState({}) - const applyChangesRef = useRef() - const dispatch = useDispatch() - const detailsRef = useRef() - const params = useParams() + const { + DetailsContainer, + applyChanges, + applyChangesRef, + blocker, + cancelChanges, + detailsPanelClassNames, + detailsRef, + commonDetailsStore, + doNotLeavePage, + form, + handleShowWarning, + leavePage, + location, + params, + removeDetailsInfo, + setBlocker, + setDetailsInfo, + shouldDetailsBlock + } = useDetails({ + applyDetailsChanges, + applyDetailsChangesCallback, + formInitialValues, + isDetailsPopUp, + isDetailsScreen, + selectedItem + }) const detailsStore = useSelector(store => store.detailsStore) const frontendSpec = useSelector(store => store.appStore.frontendSpec) - const location = useLocation() - const [setDetailsInfo, removeDetailsInfo] = useMemo(() => { - return isDetailsPopUp - ? [setDetailsPopUpInfoContent, removeDetailsPopUpInfoContent] - : [setInfoContent, removeInfoContent] - }, [isDetailsPopUp]) - const previousPathnameRef = useRef( - location.pathname.substring(0, location.pathname.lastIndexOf(params.tab)) - ) - - const detailsPanelClassNames = classnames( - 'table__item', - detailsStore.showWarning && 'pop-up-dialog-opened', - isDetailsScreen && 'table__item_big', - isDetailsPopUp && 'table__item-popup' - ) - - const formRef = useRef( - createForm({ - initialValues: formInitialValues, - mutators: { ...arrayMutators, setFieldState }, - onSubmit: () => {} - }) - ) + const dispatch = useDispatch() const handlePreview = useCallback(() => { dispatch( @@ -135,14 +111,6 @@ const Details = ({ ) }, [dispatch, selectedItem]) - useEffect(() => { - return () => { - if (!isDetailsPopUp) { - dispatch(resetChanges()) - } - } - }, [dispatch, isDetailsPopUp]) - useEffect(() => { if (!isEveryObjectValueEmpty(selectedItem)) { if (pageData.details.type === JOBS_PAGE) { @@ -200,189 +168,54 @@ const Details = ({ } }, [dispatch, pageData.details.type, removeDetailsInfo, selectedItem]) - const handleShowWarning = useCallback( - show => { - dispatch(showWarning(show)) - }, - [dispatch] - ) - - const handleRefreshClick = useCallback( - event => { - if ( - detailsStore.changes.counter > 0 && - document.getElementById('refresh')?.contains(event.target) - ) { - handleShowWarning(true) - dispatch(setFiltersWasHandled(true)) - } - }, - [detailsStore.changes.counter, dispatch, handleShowWarning] - ) - - useEffect(() => { - window.addEventListener('click', handleRefreshClick) - - return () => { - window.removeEventListener('click', handleRefreshClick) - } - }, [handleRefreshClick]) - - const shouldDetailsBlock = useCallback( - ({ currentLocation, nextLocation }) => { - const currentDetailsView = currentLocation.search.split(`${VIEW_SEARCH_PARAMETER}=`)?.[1] - const nextDetailsView = nextLocation.search.split(`${VIEW_SEARCH_PARAMETER}=`)?.[1] - const currentLocationPathname = currentLocation.pathname.split('/') - const nextLocationPathname = nextLocation.pathname.split('/') - currentLocationPathname.pop() - nextLocationPathname.pop() - - return ( - detailsStore.changes.counter > 0 && - (currentLocationPathname.join('/') !== nextLocationPathname.join('/') || - currentDetailsView !== nextDetailsView) - ) - }, - [detailsStore.changes.counter] - ) - - useEffect(() => { - if ( - formRef.current && - detailsStore.changes.counter === 0 && - !isEqual(pickBy(formInitialValues), pickBy(formRef.current.getState()?.values)) && - !formRef.current.getState()?.active - ) { - formRef.current.restart(formInitialValues) - } - }, [formInitialValues, detailsStore.changes.counter]) - - useEffect(() => { - const currentPathname = location.pathname.substring( - 0, - location.pathname.lastIndexOf(params.tab) - ) - - if (previousPathnameRef.current !== currentPathname && !isDetailsPopUp) { - formRef.current.restart(formInitialValues) - dispatch(setEditMode(false)) - previousPathnameRef.current = currentPathname - } - }, [dispatch, formInitialValues, isDetailsPopUp, location.pathname, params.tab]) - - const applyChanges = useCallback(() => { - applyDetailsChanges(detailsStore.changes).then(() => { - dispatch(resetChanges()) - - const changes = cloneDeep(detailsStore.changes) - - // todo [redux-toolkit] rework it after redux-toolkit will be added to the details store. Need to remove setTimeout and use a Promise that resolves after the state is updated. - setTimeout(() => { - applyDetailsChangesCallback(changes, selectedItem) - }) - }) - }, [ - applyDetailsChanges, - applyDetailsChangesCallback, - detailsStore.changes, - dispatch, - selectedItem - ]) - - const cancelChanges = useCallback(() => { - if (detailsStore.changes.counter > 0) { - dispatch(resetChanges()) - formRef.current.reset(formInitialValues) - } - }, [detailsStore.changes.counter, dispatch, formInitialValues]) - - const leavePage = useCallback(() => { - cancelChanges() - handleShowWarning(false) - - if (detailsStore.filtersWasHandled) { - dispatch(setFiltersWasHandled(false)) - } else { - blocker.proceed?.() - } - - window.dispatchEvent(new CustomEvent('discardChanges')) - }, [blocker, cancelChanges, detailsStore.filtersWasHandled, dispatch, handleShowWarning]) - - const doNotLeavePage = useCallback(() => { - blocker.reset?.() - dispatch(showWarning(false)) - window.dispatchEvent(new CustomEvent('cancelLeave')) - }, [blocker, dispatch]) - return ( -
{}}> - {formState => ( -
- {detailsStore.loadingCounter > 0 && } - {detailsStore.error && } -
- - {withActionMenu && ( - setDetailsPopUpSelectedTab && setDetailsPopUpSelectedTab(newTab)} - skipLink={isDetailsPopUp} - tabsList={detailsMenu} - /> - )} -
-
- -
- {(blocker.state === 'blocked' || detailsStore.showWarning) && ( - - )} - {!isDetailsPopUp && ( - - )} -
+ ( + + )} + renderTabsContent={formState => ( + )} - + setBlocker={setBlocker} + shouldDetailsBlock={shouldDetailsBlock} + withActionMenu={withActionMenu} + /> ) } @@ -390,13 +223,7 @@ Details.propTypes = { actionsMenu: ACTIONS_MENU.isRequired, applyDetailsChanges: PropTypes.func, applyDetailsChangesCallback: PropTypes.func, - detailsMenu: PropTypes.arrayOf( - PropTypes.shape({ - id: PropTypes.string.isRequired, - label: PropTypes.string.isRequired, - hidden: PropTypes.bool - }) - ).isRequired, + detailsMenu: DETAILS_MENU.isRequired, detailsPopUpSelectedTab: PropTypes.string, formInitialValues: PropTypes.object, getCloseDetailsLink: PropTypes.func, diff --git a/src/components/Details/DetailsGenerationConfiguration/DetailsGenerationConfiguration.jsx b/src/components/Details/DetailsGenerationConfiguration/DetailsGenerationConfiguration.jsx new file mode 100644 index 0000000000..a95293080a --- /dev/null +++ b/src/components/Details/DetailsGenerationConfiguration/DetailsGenerationConfiguration.jsx @@ -0,0 +1,58 @@ +/* +Copyright 2019 Iguazio Systems Ltd. + +Licensed under the Apache License, Version 2.0 (the "License") with +an addition restriction as set forth herein. You may not use this +file except in compliance with the License. You may obtain a copy of +the License at http://www.apache.org/licenses/LICENSE-2.0. + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +In addition, you may not use the software for any purposes that are +illegal under applicable law, and the grant of the foregoing license +under the Apache 2.0 license is conditioned upon your compliance with +such restriction. +*/ +import React from 'react' +import PropTypes from 'prop-types' +import { isEmpty } from 'lodash' + +import './detailsGenerationConfiguration.scss' + +const DetailsGenerationConfiguration = ({ selectedItem }) => { + return ( +
+ {!isEmpty(selectedItem.invocation_config) && ( + <> +
+ {Object.entries(selectedItem.invocation_config || {}).length} modifications made to + the default configuration: +
+
+
Key
+
Value
+
+ {Object.entries(selectedItem.invocation_config || {}).map(([key, value]) => { + return ( +
+
{key}
+
{value}
+
+ ) + })} + + )} + {isEmpty(selectedItem.invocation_config) && Default configuration is used.} +
+ ) +} + +DetailsGenerationConfiguration.propTypes = { + selectedItem: PropTypes.object.isRequired +} + +export default DetailsGenerationConfiguration diff --git a/src/components/Details/DetailsGenerationConfiguration/detailsGenerationConfiguration.scss b/src/components/Details/DetailsGenerationConfiguration/detailsGenerationConfiguration.scss new file mode 100644 index 0000000000..7794ba4e90 --- /dev/null +++ b/src/components/Details/DetailsGenerationConfiguration/detailsGenerationConfiguration.scss @@ -0,0 +1,27 @@ +@use 'igz-controls/scss/borders'; +@use 'igz-controls/scss/colors'; + +.generation-configuration-tab { + margin-top: 15px; + + &__counter { + margin-bottom: 20px; + } + + &__table-header { + font-weight: 500; + } + + &__row { + display: flex; + padding: 10px 0; + font-size: 15px; + line-height: 20px; + border-bottom: borders.$secondaryBorder; + + &-key, + &-value { + width: 50%; + } + } +} \ No newline at end of file diff --git a/src/components/Details/DetailsHeader/DetailsHeader.jsx b/src/components/Details/DetailsHeader/DetailsHeader.jsx index 1b49000623..e65244c818 100644 --- a/src/components/Details/DetailsHeader/DetailsHeader.jsx +++ b/src/components/Details/DetailsHeader/DetailsHeader.jsx @@ -17,40 +17,29 @@ illegal under applicable law, and the grant of the foregoing license under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ -import React, { useCallback, useRef, useMemo } from 'react' +import React, { useMemo, useCallback } from 'react' import PropTypes from 'prop-types' -import { Link, useLocation, useNavigate, useParams } from 'react-router-dom' -import { isEmpty } from 'lodash' import { useDispatch, useSelector } from 'react-redux' +import { Link } from 'react-router-dom' +import { isEmpty } from 'lodash' -import { Button, Tooltip, TextTooltipTemplate, RoundedIcon } from 'igz-controls/components' -import LoadButton from '../../../common/LoadButton/LoadButton' import Select from '../../../common/Select/Select' -import ActionsMenu from '../../../common/ActionsMenu/ActionsMenu' +import { Tooltip, TextTooltipTemplate, RoundedIcon } from 'igz-controls/components' +import { ACTIONS_MENU } from 'igz-controls/types' import { + ABORTED_STATE, DETAILS_ARTIFACTS_TAB, - FULL_VIEW_MODE, - JOBS_PAGE, - VIEW_SEARCH_PARAMETER + DETAILS_LOGS_TAB, + JOBS_PAGE } from '../../../constants' -import { formatDatetime } from '../../../utils' -import { TERTIARY_BUTTON } from 'igz-controls/constants' -import { ACTIONS_MENU } from '../../../types' -import { getViewMode } from '../../../utils/helper' -import { - generateUrlFromRouterPath, - getDefaultCloseDetailsLink -} from '../../../utils/link-helper.util' -import { getFilteredSearchParams } from '../../../utils/filter.util' -import { setIteration } from '../../../reducers/detailsReducer' +import { formatDatetime } from 'igz-controls/utils/datetime.util' +import { generateUrlFromRouterPath } from 'igz-controls/utils/common.util' +import { getDefaultCloseDetailsLink } from '../../../utils/link-helper.util' +import { setIteration, setRunAttempt } from '../../../reducers/detailsReducer' +import { useDetailsHeader } from 'igz-controls/hooks/useDetailsHeader.hook' -import Close from 'igz-controls/images/close.svg?react' import Back from 'igz-controls/images/back-arrow.svg?react' -import Refresh from 'igz-controls/images/refresh.svg?react' -import EnlargeIcon from 'igz-controls/images/ml-enlarge.svg?react' -import MinimizeIcon from 'igz-controls/images/ml-minimize.svg?react' -import HistoryIcon from 'igz-controls/images/history.svg?react' import InfoIcon from 'igz-controls/images/info-fill.svg?react' const DetailsHeader = ({ @@ -60,22 +49,37 @@ const DetailsHeader = ({ cancelChanges, getCloseDetailsLink = null, handleCancel = null, - handleRefresh, + handleRefresh = null, handleShowWarning, - isDetailsScreen, isDetailsPopUp = false, + isDetailsScreen, pageData, selectedItem, - tab, + tab = '', withActionMenu = true }) => { + const { + DetailsHeaderContainer, + actionButton, + commonDetailsStore, + handleActionClick, + handleBackClick, + handleCancelClick, + headerRef, + location, + navigate, + params, + showAllVersions, + viewMode, + withToggleViewBtn + } = useDetailsHeader({ + handleCancel, + handleShowWarning, + isDetailsPopUp, + pageData + }) + const detailsStore = useSelector(store => store.detailsStore) - const params = useParams() - const navigate = useNavigate() - const viewMode = getViewMode(window.location.search) - const { actionButton, withToggleViewBtn, showAllVersions } = pageData.details - const headerRef = useRef() - const location = useLocation() const dispatch = useDispatch() const errorMessage = useMemo( @@ -92,253 +96,215 @@ const DetailsHeader = ({ return isDetailsPopUp ? detailsStore.detailsJobPods : detailsStore.pods }, [detailsStore.detailsJobPods, detailsStore.pods, isDetailsPopUp]) - const { - value: stateValue, - label: stateLabel, - className: stateClassName - } = selectedItem.state || {} + const state = useMemo(() => { + const selectedItemState = selectedItem.state || {} - const handleBackClick = useCallback(() => { - if (detailsStore.changes.counter > 0) { - handleShowWarning(true) - } else { - handleCancel() + return { + value: selectedItemState.value, + label: selectedItemState.label, + className: selectedItemState.className } - }, [detailsStore.changes.counter, handleCancel, handleShowWarning]) + }, [selectedItem.state]) - const handleCancelClick = useCallback(() => { - if (detailsStore.changes.counter === 0 || isDetailsPopUp) { - handleCancel() - } - }, [detailsStore.changes.counter, handleCancel, isDetailsPopUp]) - - return ( -
-
-

- {isDetailsScreen && !pageData.details.hideBackBtn && !isDetailsPopUp && ( - - - - - - )} - } + const renderTitle = useCallback(() => { + return ( + <> + {isDetailsScreen && !pageData.details.hideBackBtn && !isDetailsPopUp && ( + - {selectedItem.name || selectedItem.db_key} - -

-
- {/*In the Workflow page we display both Jobs and Functions items. The function contains `updated` property. + + + + + )} + }> + {selectedItem.name || selectedItem.db_key} + + + ) + }, [ + isDetailsScreen, + pageData.details.hideBackBtn, + isDetailsPopUp, + getCloseDetailsLink, + selectedItem.name, + handleBackClick, + selectedItem.db_key + ]) + + const renderStatus = useCallback(() => { + return ( + <> + {/*In the Workflow page we display both Jobs and Functions items. The function contains `updated` property. The job contains startTime property.*/} -
- - {Object.keys(selectedItem).length > 0 && - pageData.page === JOBS_PAGE && - !selectedItem?.updated - ? formatDatetime( - selectedItem?.startTime, - stateValue === 'aborted' ? 'N/A' : 'Not yet started' - ) - : selectedItem?.updated - ? formatDatetime(selectedItem?.updated, 'N/A') - : pageData.details.additionalHeaderInfo || ''} - - {stateValue && stateLabel && ( - }> - - - )} -
-
- {selectedItem.ui?.customError?.title && selectedItem.ui?.customError?.message && ( - - } - > - {selectedItem.ui.customError.title} {selectedItem.ui.customError.message} - - )} - {errorMessage && ( - } - > - {errorMessage} - - )} - {!isEmpty(podsData?.podsPending) && ( - - {`${podsData.podsPending.length} of ${podsData.podsList.length} pods are pending`} - - )} - {detailsStore.pods.error && ( - Failed to load pods - )} -
- {selectedItem.ui?.infoMessage && ( -
-
- - } - > - {selectedItem.ui.infoMessage} - -
-
+
+ + {Object.keys(selectedItem).length > 0 && + pageData.page === JOBS_PAGE && + !selectedItem?.updated + ? formatDatetime( + selectedItem?.startTime, + state.value === ABORTED_STATE ? 'N/A' : 'Not yet started' + ) + : selectedItem?.updated + ? formatDatetime(selectedItem?.updated, 'N/A') + : pageData.details.additionalHeaderInfo || ''} + + {state.value && state.label && ( + }> + + )}
-
-
- {params.tab === DETAILS_ARTIFACTS_TAB && detailsStore.iteration && !isDetailsPopUp && ( - { + dispatch(setIteration(option)) + }} + options={detailsStore.iterationOptions} + selectedId={detailsStore.iteration} + /> + ) + ) + } + case DETAILS_LOGS_TAB: { + return ( + detailsStore.runAttempt && + !isEmpty(detailsStore.runAttemptOptions) && + !isDetailsPopUp && ( + { if (featureStore.newFeatureSet.spec.source.parse_dates !== event.target.value) { dispatch(setNewFeatureSetDataSourceParseDates(event.target.value)) diff --git a/src/components/FeatureSetsPanel/FeatureSetsPanelTableRow/FeatureSetsPanelTableRow.jsx b/src/components/FeatureSetsPanel/FeatureSetsPanelTableRow/FeatureSetsPanelTableRow.jsx index 29b1ecf17b..98f184f9ff 100644 --- a/src/components/FeatureSetsPanel/FeatureSetsPanelTableRow/FeatureSetsPanelTableRow.jsx +++ b/src/components/FeatureSetsPanel/FeatureSetsPanelTableRow/FeatureSetsPanelTableRow.jsx @@ -22,10 +22,9 @@ import PropTypes from 'prop-types' import { map } from 'lodash' import classnames from 'classnames' -import ActionsMenu from '../../../common/ActionsMenu/ActionsMenu' -import { Tooltip, TextTooltipTemplate } from 'igz-controls/components' +import { Tooltip, TextTooltipTemplate, ActionsMenu } from 'igz-controls/components' -import { ACTIONS_MENU } from '../../../types' +import { ACTIONS_MENU } from 'igz-controls/types' const FeatureSetsPanelTableRow = ({ actionButton = null, diff --git a/src/components/FeatureSetsPanel/FeatureSetsPanelTargetStore/FeatureSetsPanelTargetStore.jsx b/src/components/FeatureSetsPanel/FeatureSetsPanelTargetStore/FeatureSetsPanelTargetStore.jsx index a8ed0bec34..8afe73cdc0 100644 --- a/src/components/FeatureSetsPanel/FeatureSetsPanelTargetStore/FeatureSetsPanelTargetStore.jsx +++ b/src/components/FeatureSetsPanel/FeatureSetsPanelTargetStore/FeatureSetsPanelTargetStore.jsx @@ -92,37 +92,39 @@ const FeatureSetsPanelTargetStore = ({ ) useEffect(() => { - if (!targetsPathEditData.online.isModified && !targetsPathEditData.online.isEditMode) { - setData(state => ({ - ...state, - online: { - ...state.online, - path: generatePath( - frontendSpec.feature_store_data_prefixes, - project, - state.online.kind, - featureStore.newFeatureSet.metadata.name, - '' - ) - } - })) - } + queueMicrotask(() => { + if (!targetsPathEditData.online.isModified && !targetsPathEditData.online.isEditMode) { + setData(state => ({ + ...state, + online: { + ...state.online, + path: generatePath( + frontendSpec.feature_store_data_prefixes, + project, + state.online.kind, + featureStore.newFeatureSet.metadata.name, + '' + ) + } + })) + } - if (!targetsPathEditData.parquet.isModified && !targetsPathEditData.parquet.isEditMode) { - setData(state => ({ - ...state, - parquet: { - ...state.parquet, - path: generatePath( - frontendSpec.feature_store_data_prefixes, - project, - PARQUET, - featureStore.newFeatureSet.metadata.name, - state.parquet?.partitioned ? '' : PARQUET - ) - } - })) - } + if (!targetsPathEditData.parquet.isModified && !targetsPathEditData.parquet.isEditMode) { + setData(state => ({ + ...state, + parquet: { + ...state.parquet, + path: generatePath( + frontendSpec.feature_store_data_prefixes, + project, + PARQUET, + featureStore.newFeatureSet.metadata.name, + state.parquet?.partitioned ? '' : PARQUET + ) + } + })) + } + }) }, [ featureStore.newFeatureSet.metadata.name, featureStore.newFeatureSet.spec.source.kind, @@ -207,29 +209,31 @@ const FeatureSetsPanelTargetStore = ({ ]) useEffect(() => { - if (isEmpty(frontendSpec.feature_store_data_prefixes)) { - setTargetsPathEditData(state => ({ - ...state, - [PARQUET]: { - ...state[PARQUET], - isEditMode: true - }, - [ONLINE]: { - ...state[ONLINE], - isEditMode: true - } - })) - setDisableButtons(state => ({ - ...state, - isOfflineTargetPathEditModeClosed: false, - isOnlineTargetPathEditModeClosed: false - })) - setValidation(state => ({ - ...state, - isOfflineTargetPathValid: false, - isOnlineTargetPathValid: false - })) - } + queueMicrotask(() => { + if (isEmpty(frontendSpec.feature_store_data_prefixes)) { + setTargetsPathEditData(state => ({ + ...state, + [PARQUET]: { + ...state[PARQUET], + isEditMode: true + }, + [ONLINE]: { + ...state[ONLINE], + isEditMode: true + } + })) + setDisableButtons(state => ({ + ...state, + isOfflineTargetPathEditModeClosed: false, + isOnlineTargetPathEditModeClosed: false + })) + setValidation(state => ({ + ...state, + isOfflineTargetPathValid: false, + isOnlineTargetPathValid: false + })) + } + }) }, [frontendSpec.feature_store_data_prefixes, setDisableButtons, setValidation]) useEffect(() => { @@ -674,56 +678,58 @@ const FeatureSetsPanelTargetStore = ({ ]) useEffect(() => { - if (featureStore.newFeatureSet.spec.passthrough && !passthroughtEnabled) { - setPreviousTargets({ - data: { - ...data, - [PARQUET]: { - ...data[PARQUET], - path: data[PARQUET].path ?? offlineTarget.path - }, - [ONLINE]: { - ...data[ONLINE], - path: data[ONLINE].path ?? onlineTarget.path - } - }, - featureSetTargets: featureStore.newFeatureSet.spec.targets, - selectedPartitionKind, - selectedTargetKind, - partitionRadioButtonsState - }) - - setPassThrouthEnabled(true) - - if (selectedTargetKind.includes(ONLINE)) { - openPopUp(ConfirmDialog, { - confirmButton: { - label: 'Unset online-target', - variant: PRIMARY_BUTTON, - handler: () => { - clearTargets(false) - } - }, - cancelButton: { - label: 'Keep online-target set', - variant: TERTIARY_BUTTON, - handler: () => { - clearTargets(true) + queueMicrotask(() => { + if (featureStore.newFeatureSet.spec.passthrough && !passthroughtEnabled) { + setPreviousTargets({ + data: { + ...data, + [PARQUET]: { + ...data[PARQUET], + path: data[PARQUET].path ?? offlineTarget.path + }, + [ONLINE]: { + ...data[ONLINE], + path: data[ONLINE].path ?? onlineTarget.path } }, - closePopUp: () => { - dispatch(setNewFeatureSetPassthrough(false)) - }, - message: - 'Passthrough set to "enabled" while online-target is set. Do you want to unset online-target?' + featureSetTargets: featureStore.newFeatureSet.spec.targets, + selectedPartitionKind, + selectedTargetKind, + partitionRadioButtonsState }) - } else { - clearTargets(false) + + setPassThrouthEnabled(true) + + if (selectedTargetKind.includes(ONLINE)) { + openPopUp(ConfirmDialog, { + confirmButton: { + label: 'Unset online-target', + variant: PRIMARY_BUTTON, + handler: () => { + clearTargets(false) + } + }, + cancelButton: { + label: 'Keep online-target set', + variant: TERTIARY_BUTTON, + handler: () => { + clearTargets(true) + } + }, + closePopUp: () => { + dispatch(setNewFeatureSetPassthrough(false)) + }, + message: + 'Passthrough set to "enabled" while online-target is set. Do you want to unset online-target?' + }) + } else { + clearTargets(false) + } + } else if (!featureStore.newFeatureSet.spec.passthrough && passthroughtEnabled) { + restoreTargets() + setPassThrouthEnabled(false) } - } else if (!featureStore.newFeatureSet.spec.passthrough && passthroughtEnabled) { - restoreTargets() - setPassThrouthEnabled(false) - } + }) }, [ clearTargets, data, diff --git a/src/components/FeatureSetsPanel/FeatureSetsPanelTargetStore/FeatureSetsPanelTargetStoreView.jsx b/src/components/FeatureSetsPanel/FeatureSetsPanelTargetStore/FeatureSetsPanelTargetStoreView.jsx index ee0bd4454d..b54d59366b 100644 --- a/src/components/FeatureSetsPanel/FeatureSetsPanelTargetStore/FeatureSetsPanelTargetStoreView.jsx +++ b/src/components/FeatureSetsPanel/FeatureSetsPanelTargetStore/FeatureSetsPanelTargetStoreView.jsx @@ -23,13 +23,18 @@ import { CSSTransition } from 'react-transition-group' import classNames from 'classnames' import CheckBox from '../../../common/CheckBox/CheckBox' -import ErrorMessage from '../../../common/ErrorMessage/ErrorMessage' import FeatureSetsPanelSection from '../FeatureSetsPanelSection/FeatureSetsPanelSection' import Input from '../../../common/Input/Input' import PartitionFields from '../../../elements/PartitionFields/PartitionFields' import Select from '../../../common/Select/Select' import UrlPath from '../UrlPath' -import { Tip, Tooltip, TextTooltipTemplate, RoundedIcon } from 'igz-controls/components' +import { + Tip, + Tooltip, + TextTooltipTemplate, + RoundedIcon, + ErrorMessage +} from 'igz-controls/components' import { MLRUN_STORAGE_INPUT_PATH_SCHEME, diff --git a/src/components/FeatureSetsPanel/FeatureSetsPanelTitle/FeatureSetsPanelTitle.jsx b/src/components/FeatureSetsPanel/FeatureSetsPanelTitle/FeatureSetsPanelTitle.jsx index 63ce585c5d..f19114c299 100644 --- a/src/components/FeatureSetsPanel/FeatureSetsPanelTitle/FeatureSetsPanelTitle.jsx +++ b/src/components/FeatureSetsPanel/FeatureSetsPanelTitle/FeatureSetsPanelTitle.jsx @@ -62,10 +62,12 @@ const FeatureSetsPanelTitle = ({ useEffect(() => { if (featureStore.newFeatureSet.spec.passthrough !== Boolean(data.passthrough)) { - setData(state => ({ - ...state, - passthrough: featureStore.newFeatureSet.spec.passthrough ? 'passthrough' : '' - })) + queueMicrotask(() => { + setData(state => ({ + ...state, + passthrough: featureStore.newFeatureSet.spec.passthrough ? 'passthrough' : '' + })) + }) } }, [data.passthrough, featureStore.newFeatureSet.spec.passthrough]) diff --git a/src/components/FeatureSetsPanel/FeatureSetsPanelTitle/FeatureSetsPanelTitleView.jsx b/src/components/FeatureSetsPanel/FeatureSetsPanelTitle/FeatureSetsPanelTitleView.jsx index 660612adf4..2deecbabf7 100644 --- a/src/components/FeatureSetsPanel/FeatureSetsPanelTitle/FeatureSetsPanelTitleView.jsx +++ b/src/components/FeatureSetsPanel/FeatureSetsPanelTitle/FeatureSetsPanelTitleView.jsx @@ -30,7 +30,7 @@ import { getValidationRules, getInternalLabelsValidationRule } from 'igz-controls/utils/validation.util' -import { getChipOptions } from '../../../utils/getChipOptions' +import { getChipOptions } from 'igz-controls/utils/chips.util' import CloseIcon from 'igz-controls/images/close.svg?react' @@ -64,7 +64,7 @@ const FeatureSetsPanelTitleView = ({ floatingLabel invalid={!validation.isNameValid} invalidText="This field is invalid" - label="Feature Set Name" + label="Feature set name" onChange={name => setData(state => ({ ...state, name }))} onBlur={handleNameOnBlur} required @@ -145,7 +145,7 @@ const FeatureSetsPanelTitleView = ({ Passthrough
diff --git a/src/components/FeatureSetsPanel/FeatureSetsPanelView.jsx b/src/components/FeatureSetsPanel/FeatureSetsPanelView.jsx index 959c3949f9..2f41404f3b 100644 --- a/src/components/FeatureSetsPanel/FeatureSetsPanelView.jsx +++ b/src/components/FeatureSetsPanel/FeatureSetsPanelView.jsx @@ -26,9 +26,8 @@ import FeatureSetsPanelDataSource from './FeatureSetsPanelDataSource/FeatureSets import FeatureSetsPanelSchema from './FeatureSetsPanelSchema/FeatureSetsPanelSchema' import FeatureSetsPanelTargetStore from './FeatureSetsPanelTargetStore/FeatureSetsPanelTargetStore' import FeatureSetsPanelTitle from './FeatureSetsPanelTitle/FeatureSetsPanelTitle' -import Loader from '../../common/Loader/Loader' import PanelCredentialsAccessKey from '../../elements/PanelCredentialsAccessKey/PanelCredentialsAccessKey' -import { Button, ConfirmDialog } from 'igz-controls/components' +import { Button, ConfirmDialog, Loader } from 'igz-controls/components' import { PRIMARY_BUTTON, TERTIARY_BUTTON, LABEL_BUTTON } from 'igz-controls/constants' import { setNewFeatureSetCredentialsAccessKey } from '../../reducers/featureStoreReducer' diff --git a/src/components/FeatureSetsPanel/ScheduleFeatureSet/ScheduleFeatureSet.jsx b/src/components/FeatureSetsPanel/ScheduleFeatureSet/ScheduleFeatureSet.jsx index c9f4b5f50c..95f0743943 100644 --- a/src/components/FeatureSetsPanel/ScheduleFeatureSet/ScheduleFeatureSet.jsx +++ b/src/components/FeatureSetsPanel/ScheduleFeatureSet/ScheduleFeatureSet.jsx @@ -22,12 +22,12 @@ import PropTypes from 'prop-types' import ScheduleFeatureSetView from './ScheduleFeatureSetView' -import { tabs } from './scheduleFeatureSet.util' -import { initialState, recurringReducer, scheduleActionType } from './recurringReducer' import { decodeLocale, getWeekDays, getWeekStart } from '../../../utils/datePicker.util' -import { getFormatTime } from '../../../utils' import { generateCronInitialValue } from '../../../utils/generateCronInitialValue' import { getDefaultSchedule } from '../../../utils/getDefaultSchedule' +import { getFormatTime } from 'igz-controls/utils/datetime.util' +import { initialState, recurringReducer, scheduleActionType } from './recurringReducer' +import { tabs } from './scheduleFeatureSet.util' const ScheduleFeatureSet = ({ defaultCron = '', setNewFeatureSetSchedule, setShowSchedule }) => { const [activeTab, setActiveTab] = useState(tabs[0].id) diff --git a/src/components/FeatureSetsPanel/ScheduleFeatureSet/ScheduleFeatureSetView.jsx b/src/components/FeatureSetsPanel/ScheduleFeatureSet/ScheduleFeatureSetView.jsx index 10231586da..4008979181 100644 --- a/src/components/FeatureSetsPanel/ScheduleFeatureSet/ScheduleFeatureSetView.jsx +++ b/src/components/FeatureSetsPanel/ScheduleFeatureSet/ScheduleFeatureSetView.jsx @@ -21,10 +21,9 @@ import React from 'react' import PropTypes from 'prop-types' import classnames from 'classnames' -import ErrorMessage from '../../../common/ErrorMessage/ErrorMessage' import ScheduleFeatureSetSimple from '../ScheduleFeatureSetSimple/ScheduleFeatureSetSimple' import ScheduleCron from '../../ScheduleCron/ScheduleCron' -import { Button, RoundedIcon } from 'igz-controls/components' +import { Button, RoundedIcon, ErrorMessage } from 'igz-controls/components' import { tabs } from './scheduleFeatureSet.util' import { PRIMARY_BUTTON } from 'igz-controls/constants' diff --git a/src/components/FeatureSetsPanel/UrlPath.utils.js b/src/components/FeatureSetsPanel/UrlPath.utils.js index f560e6c2fa..74de9cfb0c 100644 --- a/src/components/FeatureSetsPanel/UrlPath.utils.js +++ b/src/components/FeatureSetsPanel/UrlPath.utils.js @@ -35,7 +35,7 @@ import { generateArtifactsReferencesList, generateProjectsList } from '../../utils/panelPathScheme' -import { showErrorNotification } from '../../utils/notifications.util' +import { showErrorNotification } from 'igz-controls/utils/notification.util' import { fetchArtifact, fetchArtifacts } from '../../reducers/artifactsReducer' import { fetchProjectsNames } from '../../reducers/projectReducer' import { isCommunityEdition } from '../../utils/helper' diff --git a/src/components/FeatureSetsPanel/featureSetsPanel.scss b/src/components/FeatureSetsPanel/featureSetsPanel.scss index 1be3c5c236..580e8202bb 100644 --- a/src/components/FeatureSetsPanel/featureSetsPanel.scss +++ b/src/components/FeatureSetsPanel/featureSetsPanel.scss @@ -1,7 +1,6 @@ @use 'igz-controls/scss/colors'; @use 'igz-controls/scss/borders'; @use 'igz-controls/scss/mixins'; - @include mixins.newItemSidePanel; .feature-set-panel { diff --git a/src/components/FeatureStore/FeatureSets/FeatureSets.jsx b/src/components/FeatureStore/FeatureSets/FeatureSets.jsx index cb97ad0a03..90d5f652ec 100644 --- a/src/components/FeatureStore/FeatureSets/FeatureSets.jsx +++ b/src/components/FeatureStore/FeatureSets/FeatureSets.jsx @@ -60,12 +60,11 @@ import { getScssVariableValue } from 'igz-controls/utils/common.util' import { isDetailsTabExists } from '../../../utils/link-helper.util' import { parseChipsData } from '../../../utils/convertChipsData' import { parseFeatureSets } from '../../../utils/parseFeatureSets' -import { setNotification } from '../../../reducers/notificationReducer' -import { sortListByDate } from '../../../utils' +import { setNotification } from 'igz-controls/reducers/notificationReducer' +import { sortListByDate } from 'igz-controls/utils/datetime.util' import { useFiltersFromSearchParams } from '../../../hooks/useFiltersFromSearchParams.hook' import { useGroupContent } from '../../../hooks/groupContent.hook' import { useInitialTableFetch } from '../../../hooks/useInitialTableFetch.hook' -import { useMode } from '../../../hooks/mode.hook' import { useOpenPanel } from '../../../hooks/openPanel.hook' import { useVirtualization } from '../../../hooks/useVirtualization.hook' @@ -88,7 +87,6 @@ const FeatureSets = () => { const navigate = useNavigate() const location = useLocation() const dispatch = useDispatch() - const { isDemoMode } = useMode() const frontendSpec = useSelector(store => store.appStore.frontendSpec) const detailsFormInitialValues = useMemo( () => ({ @@ -112,8 +110,8 @@ const FeatureSets = () => { [] ) const pageData = useMemo( - () => generatePageData(selectedFeatureSet, isDemoMode), - [isDemoMode, selectedFeatureSet] + () => generatePageData(selectedFeatureSet), + [selectedFeatureSet] ) const actionsMenu = useMemo( () => generateActionsMenu(dispatch, selectedFeatureSet, toggleConvertedYaml), diff --git a/src/components/FeatureStore/FeatureSets/FeatureSetsView.jsx b/src/components/FeatureStore/FeatureSets/FeatureSetsView.jsx index 5ca68e8eb3..8609613980 100644 --- a/src/components/FeatureStore/FeatureSets/FeatureSetsView.jsx +++ b/src/components/FeatureStore/FeatureSets/FeatureSetsView.jsx @@ -21,18 +21,18 @@ import React from 'react' import { useParams } from 'react-router-dom' import PropTypes from 'prop-types' +import { Loader } from 'igz-controls/components' import FeatureSetsPanel from '../../FeatureSetsPanel/FeatureSetsPanel' import FeatureStoreTableRow from '../../../elements/FeatureStoreTableRow/FeatureStoreTableRow' import NoData from '../../../common/NoData/NoData' import Table from '../../Table/Table' import ActionBar from '../../ActionBar/ActionBar' import FeatureStoreFilters from '../FeatureStoreFilters' -import Loader from '../../../common/Loader/Loader' import FeatureStorePageTabs from '../FeatureStorePageTabs/FeatureStorePageTabs' import { FEATURE_SETS_TAB, FEATURE_STORE_PAGE } from '../../../constants' import { PRIMARY_BUTTON } from 'igz-controls/constants' -import { VIRTUALIZATION_CONFIG } from '../../../types' +import { VIRTUALIZATION_CONFIG } from 'igz-controls/types' import { filtersConfig } from './featureSets.util' import { getNoDataMessage } from '../../../utils/getNoDataMessage' import { isRowRendered } from '../../../hooks/useVirtualization.hook' @@ -132,6 +132,7 @@ const FeatureSetsView = React.forwardRef( selectedItem={selectedFeatureSet} selectedRowData={selectedRowData} toggleRow={toggleRow} + withQuickActions={true} /> ) )} diff --git a/src/components/FeatureStore/FeatureSets/featureSets.scss b/src/components/FeatureStore/FeatureSets/featureSets.scss index d09344b5ee..c381eceea0 100644 --- a/src/components/FeatureStore/FeatureSets/featureSets.scss +++ b/src/components/FeatureStore/FeatureSets/featureSets.scss @@ -1,5 +1,5 @@ @use 'igz-controls/scss/variables'; -@use '/src/scss/mixins'; +@use '@/scss/mixins'; $featureSetsRowHeight: variables.$rowHeight; $featureSetsHeaderRowHeight: variables.$headerRowHeight; diff --git a/src/components/FeatureStore/FeatureSets/featureSets.util.jsx b/src/components/FeatureStore/FeatureSets/featureSets.util.jsx index 8492f1a4fe..891661a938 100644 --- a/src/components/FeatureStore/FeatureSets/featureSets.util.jsx +++ b/src/components/FeatureStore/FeatureSets/featureSets.util.jsx @@ -28,12 +28,15 @@ import { TAG_FILTER, TAG_FILTER_LATEST } from '../../../constants' -import { showErrorNotification } from '../../../utils/notifications.util' +import { showErrorNotification } from 'igz-controls/utils/notification.util' +import { copyToClipboard } from '../../../utils/copyToClipboard' +import { generateUri } from '../../../utils/resources' import { fetchFeatureSet } from '../../../reducers/featureStoreReducer' +import Copy from 'igz-controls/images/copy-to-clipboard-icon.svg?react' import Yaml from 'igz-controls/images/yaml.svg?react' -export const generateFeatureSetsDetailsMenu = (selectedItem, isDemoMode) => [ +export const generateFeatureSetsDetailsMenu = (selectedItem) => [ { label: 'overview', id: 'overview' @@ -59,8 +62,7 @@ export const generateFeatureSetsDetailsMenu = (selectedItem, isDemoMode) => [ }, { label: 'analysis', - id: 'analysis', - hidden: !isDemoMode + id: 'analysis' } ] @@ -84,12 +86,12 @@ export const filtersConfig = { [LABELS_FILTER]: { label: 'Labels:', initialValue: '', isModal: true } } -export const generatePageData = (selectedFeatureSet, isDemoMode) => { +export const generatePageData = (selectedFeatureSet) => { return { page: FEATURE_STORE_PAGE, details: { type: FEATURE_SETS_TAB, - menu: generateFeatureSetsDetailsMenu(selectedFeatureSet, isDemoMode), + menu: generateFeatureSetsDetailsMenu(selectedFeatureSet), infoHeaders: featureSetsInfoHeaders } } @@ -105,6 +107,14 @@ export const generateActionsMenu = (dispatch, selectedFeatureSet, toggleConverte toggleConvertedYaml ) } + ], + [ + { + label: 'Copy URI', + icon: , + onClick: featureSet => + copyToClipboard(generateUri(featureSet, null, FEATURE_SETS_TAB), dispatch) + } ] ] diff --git a/src/components/FeatureStore/FeatureStore.jsx b/src/components/FeatureStore/FeatureStore.jsx index c399bb4ce5..753179f93a 100644 --- a/src/components/FeatureStore/FeatureStore.jsx +++ b/src/components/FeatureStore/FeatureStore.jsx @@ -21,9 +21,8 @@ import React, { useCallback, useState } from 'react' import { Outlet } from 'react-router-dom' import { useDispatch, useSelector } from 'react-redux' -import Loader from '../../common/Loader/Loader' import Breadcrumbs from '../../common/Breadcrumbs/Breadcrumbs' -import { ConfirmDialog } from 'igz-controls/components' +import { ConfirmDialog, Loader } from 'igz-controls/components' import { TABLE_CONTAINER } from '../../constants' import { toggleYaml } from '../../reducers/appReducer' diff --git a/src/components/FeatureStore/FeatureVectors/FeatureVectors.jsx b/src/components/FeatureStore/FeatureVectors/FeatureVectors.jsx index a2a249049c..495feb9dae 100644 --- a/src/components/FeatureStore/FeatureVectors/FeatureVectors.jsx +++ b/src/components/FeatureStore/FeatureVectors/FeatureVectors.jsx @@ -59,13 +59,12 @@ import { getScssVariableValue } from 'igz-controls/utils/common.util' import { isDetailsTabExists } from '../../../utils/link-helper.util' import { parseFeatureVectors } from '../../../utils/parseFeatureVectors' import { setFeaturesPanelData } from '../../../reducers/tableReducer' -import { setNotification } from '../../../reducers/notificationReducer' -import { showErrorNotification } from '../../../utils/notifications.util' -import { sortListByDate } from '../../../utils' +import { setNotification } from 'igz-controls/reducers/notificationReducer' +import { showErrorNotification } from 'igz-controls/utils/notification.util' +import { sortListByDate } from 'igz-controls/utils/datetime.util' import { useFiltersFromSearchParams } from '../../../hooks/useFiltersFromSearchParams.hook' import { useGroupContent } from '../../../hooks/groupContent.hook' import { useInitialTableFetch } from '../../../hooks/useInitialTableFetch.hook' -import { useMode } from '../../../hooks/mode.hook' import { useOpenPanel } from '../../../hooks/openPanel.hook' import { useVirtualization } from '../../../hooks/useVirtualization.hook' @@ -89,7 +88,6 @@ const FeatureVectors = () => { const navigate = useNavigate() const location = useLocation() const dispatch = useDispatch() - const { isDemoMode } = useMode() const { createVectorPopUpIsOpen, @@ -112,8 +110,8 @@ const FeatureVectors = () => { [] ) const pageData = useMemo( - () => generatePageData(selectedFeatureVector, isDemoMode), - [isDemoMode, selectedFeatureVector] + () => generatePageData(selectedFeatureVector), + [selectedFeatureVector] ) const detailsFormInitialValues = useMemo( @@ -249,8 +247,8 @@ const FeatureVectors = () => { ) const actionsMenu = useMemo( - () => generateActionsMenu(onDeleteFeatureVector, toggleConvertedYaml), - [onDeleteFeatureVector, toggleConvertedYaml] + () => generateActionsMenu(dispatch, onDeleteFeatureVector, toggleConvertedYaml), + [onDeleteFeatureVector, toggleConvertedYaml, dispatch] ) const handleRefresh = useCallback( diff --git a/src/components/FeatureStore/FeatureVectors/FeatureVectorsView.jsx b/src/components/FeatureStore/FeatureVectors/FeatureVectorsView.jsx index d7a87bf793..127a5cbf8e 100644 --- a/src/components/FeatureStore/FeatureVectors/FeatureVectorsView.jsx +++ b/src/components/FeatureStore/FeatureVectors/FeatureVectorsView.jsx @@ -30,7 +30,7 @@ import Table from '../../Table/Table' import { FEATURE_STORE_PAGE, FEATURE_VECTORS_TAB } from '../../../constants' import { PRIMARY_BUTTON } from 'igz-controls/constants' -import { VIRTUALIZATION_CONFIG } from '../../../types' +import { VIRTUALIZATION_CONFIG } from 'igz-controls/types' import { createFeatureVectorTitle } from '../featureStore.util' import { filtersConfig } from './featureVectors.util' import { getNoDataMessage } from '../../../utils/getNoDataMessage' @@ -124,6 +124,7 @@ const FeatureVectorsView = React.forwardRef( selectedItem={selectedFeatureVector} selectedRowData={selectedRowData} toggleRow={toggleRow} + withQuickActions={true} /> ) )} diff --git a/src/components/FeatureStore/FeatureVectors/featureVectors.scss b/src/components/FeatureStore/FeatureVectors/featureVectors.scss index 3a160dabb8..eb5c63e963 100644 --- a/src/components/FeatureStore/FeatureVectors/featureVectors.scss +++ b/src/components/FeatureStore/FeatureVectors/featureVectors.scss @@ -1,5 +1,5 @@ @use 'igz-controls/scss/variables'; -@use '/src/scss/mixins'; +@use '@/scss/mixins'; $featureVectorsRowHeight: variables.$rowHeight; $featureVectorsHeaderRowHeight: variables.$headerRowHeight; diff --git a/src/components/FeatureStore/FeatureVectors/featureVectors.util.jsx b/src/components/FeatureStore/FeatureVectors/featureVectors.util.jsx index 0453d2b350..a5470d48ce 100644 --- a/src/components/FeatureStore/FeatureVectors/featureVectors.util.jsx +++ b/src/components/FeatureStore/FeatureVectors/featureVectors.util.jsx @@ -29,11 +29,14 @@ import { } from '../../../constants' import { parseFeatureTemplate } from '../../../utils/parseFeatureTemplate' import { parseChipsData } from '../../../utils/convertChipsData' +import { copyToClipboard } from '../../../utils/copyToClipboard' +import { generateUri } from '../../../utils/resources' import Delete from 'igz-controls/images/delete.svg?react' import Yaml from 'igz-controls/images/yaml.svg?react' +import Copy from 'igz-controls/images/copy-to-clipboard-icon.svg?react' -export const generateFeatureVectorsDetailsMenu = (selectedItem, isDemoMode) => [ +export const generateFeatureVectorsDetailsMenu = (selectedItem) => [ { label: 'overview', id: 'overview' @@ -55,12 +58,12 @@ export const generateFeatureVectorsDetailsMenu = (selectedItem, isDemoMode) => [ { label: 'statistics', id: 'statistics', - hidden: !selectedItem.stats && !selectedItem.features + hidden: !selectedItem.stats && !selectedItem.features, + tip: 'Note that some values may be empty due to the use of different engines for calculating statistics' }, { label: 'analysis', - id: 'analysis', - hidden: !isDemoMode + id: 'analysis' } ] @@ -83,18 +86,19 @@ export const filtersConfig = { [LABELS_FILTER]: { label: 'Labels:', initialValue: '', isModal: true } } -export const generatePageData = (selectedFeatureSet, isDemoMode) => { +export const generatePageData = (selectedFeatureSet) => { return { page: FEATURE_STORE_PAGE, details: { type: FEATURE_VECTORS_TAB, - menu: generateFeatureVectorsDetailsMenu(selectedFeatureSet, isDemoMode), + menu: generateFeatureVectorsDetailsMenu(selectedFeatureSet), infoHeaders: featureSetsInfoHeaders } } } export const generateActionsMenu = ( + dispatch, onDeleteFeatureVector, toggleConvertedYaml, isDetailsPopUp = false @@ -113,6 +117,14 @@ export const generateActionsMenu = ( onClick: onDeleteFeatureVector, allowLeaveWarning: true } + ], + [ + { + label: 'Copy URI', + icon: , + onClick: featureSet => + copyToClipboard(generateUri(featureSet, null, FEATURE_VECTORS_TAB), dispatch) + } ] ] diff --git a/src/components/FeatureStore/Features/FeaturesView.jsx b/src/components/FeatureStore/Features/FeaturesView.jsx index bb7a51a18e..f1df3f8c2e 100644 --- a/src/components/FeatureStore/Features/FeaturesView.jsx +++ b/src/components/FeatureStore/Features/FeaturesView.jsx @@ -20,20 +20,20 @@ such restriction. import React from 'react' import PropTypes from 'prop-types' +import ActionBar from '../../ActionBar/ActionBar' +import FeatureStoreFilters from '../FeatureStoreFilters' +import FeatureStorePageTabs from '../FeatureStorePageTabs/FeatureStorePageTabs' import FeatureStoreTableRow from '../../../elements/FeatureStoreTableRow/FeatureStoreTableRow' import NoData from '../../../common/NoData/NoData' import Table from '../../Table/Table' -import FeatureStorePageTabs from '../FeatureStorePageTabs/FeatureStorePageTabs' import { FEATURE_STORE_PAGE, FEATURES_TAB } from '../../../constants' import { PRIMARY_BUTTON } from 'igz-controls/constants' -import { VIRTUALIZATION_CONFIG } from '../../../types' +import { VIRTUALIZATION_CONFIG } from 'igz-controls/types' +import { addToFeatureVectorTitle } from '../featureStore.util' import { filtersConfig } from './features.util' import { getNoDataMessage } from '../../../utils/getNoDataMessage' import { isRowRendered } from '../../../hooks/useVirtualization.hook' -import ActionBar from '../../ActionBar/ActionBar' -import FeatureStoreFilters from '../FeatureStoreFilters' -import { addToFeatureVectorTitle } from '../featureStore.util' const FeaturesView = React.forwardRef( ( diff --git a/src/components/FeatureStore/Features/features.scss b/src/components/FeatureStore/Features/features.scss index 17bef53e51..b0ce7abcdb 100644 --- a/src/components/FeatureStore/Features/features.scss +++ b/src/components/FeatureStore/Features/features.scss @@ -1,5 +1,5 @@ @use 'igz-controls/scss/variables'; -@use '/src/scss/mixins'; +@use '@/scss/mixins'; $featuresRowHeight: variables.$rowHeightSmall; $featuresHeaderRowHeight: variables.$headerRowHeight; diff --git a/src/components/FeatureStore/featureStore.util.js b/src/components/FeatureStore/featureStore.util.js index 8486e88eff..f78e296f30 100644 --- a/src/components/FeatureStore/featureStore.util.js +++ b/src/components/FeatureStore/featureStore.util.js @@ -31,8 +31,8 @@ import { } from '../../constants' import { FORBIDDEN_ERROR_STATUS_CODE } from 'igz-controls/constants' import { convertChipsData } from '../../utils/convertChipsData' -import { showErrorNotification } from '../../utils/notifications.util' -import { truncateUid } from '../../utils' +import { showErrorNotification } from 'igz-controls/utils/notification.util' +import { truncateUid } from 'igz-controls/utils/string.util' import { updateFeatureStoreData } from '../../reducers/featureStoreReducer' export const createFeatureSetTitle = 'Create set' diff --git a/src/components/Files/files.util.jsx b/src/components/Files/files.util.jsx index b151dfcc2c..af82a55d77 100644 --- a/src/components/Files/files.util.jsx +++ b/src/components/Files/files.util.jsx @@ -25,17 +25,24 @@ import { ARTIFACT_MAX_DOWNLOAD_SIZE, ARTIFACT_OTHER_TYPE, ARTIFACT_TYPE, - FILES_PAGE, - FULL_VIEW_MODE + FILES_PAGE } from '../../constants' -import { applyTagChanges, chooseOrFetchArtifact } from '../../utils/artifacts.util' -import { copyToClipboard } from '../../utils/copyToClipboard' -import { getIsTargetPathValid } from '../../utils/createArtifactsContent' -import { showArtifactsPreview } from '../../reducers/artifactsReducer' +import { FULL_VIEW_MODE } from 'igz-controls/constants' +import { + processActionAfterTagUniquesValidation, + applyTagChanges, + chooseOrFetchArtifact +} from '../../utils/artifacts.util' import { generateUri } from '../../utils/resources' +import { getIsTargetPathValid } from '../../utils/createArtifactsContent' import { handleDeleteArtifact } from '../../utils/handleDeleteArtifact' -import { openDeleteConfirmPopUp, openPopUp } from 'igz-controls/utils/common.util' +import { openDeleteConfirmPopUp, openPopUp, copyToClipboard } from 'igz-controls/utils/common.util' import { setDownloadItem, setShowDownloadsList } from '../../reducers/downloadReducer' +import { showArtifactsPreview } from '../../reducers/artifactsReducer' +import { + decreaseDetailsLoadingCounter, + increaseDetailsLoadingCounter +} from '../../reducers/detailsReducer' import TagIcon from 'igz-controls/images/tag-icon.svg?react' import YamlIcon from 'igz-controls/images/yaml.svg?react' @@ -72,14 +79,14 @@ export const infoHeaders = [ { label: 'Labels', id: 'labels' } ] -export const generatePageData = viewMode => { +export const generatePageData = (viewMode, isDetailsPopUp = false) => { return { page: FILES_PAGE, details: { type: FILES_PAGE, menu: detailsMenu, infoHeaders, - hideBackBtn: viewMode === FULL_VIEW_MODE, + hideBackBtn: viewMode === FULL_VIEW_MODE && !isDetailsPopUp, withToggleViewBtn: true } } @@ -94,7 +101,17 @@ export const handleApplyDetailsChanges = ( setNotification, dispatch ) => { - return applyTagChanges(changes, selectedItem, projectName, dispatch, setNotification) + return processActionAfterTagUniquesValidation({ + tag: changes?.data?.tag?.currentFieldValue, + artifact: selectedItem, + projectName, + dispatch, + actionCallback: () => + applyTagChanges(changes, selectedItem, projectName, dispatch, setNotification), + throwError: true, + showLoader: () => dispatch(increaseDetailsLoadingCounter()), + hideLoader: () => dispatch(decreaseDetailsLoadingCounter()) + }) } export const generateActionsMenu = ( diff --git a/src/components/FilterMenu/FilterMenu.jsx b/src/components/FilterMenu/FilterMenu.jsx index ea60c6804c..f190c7520d 100644 --- a/src/components/FilterMenu/FilterMenu.jsx +++ b/src/components/FilterMenu/FilterMenu.jsx @@ -56,7 +56,7 @@ import { filterSelectOptions, tagFilterOptions } from './filterMenu.settings' import { generateProjectsList } from '../../utils/projects' import { getDefaultCloseDetailsLink } from '../../utils/link-helper.util' import { removeFilters, setFilterProjectOptions, setFilters } from '../../reducers/filtersReducer' -import { setFiltersWasHandled, showWarning } from '../../reducers/detailsReducer' +import { setFiltersWasHandled, showWarning } from 'igz-controls/reducers/commonDetailsReducer' import './filterMenu.scss' @@ -84,7 +84,7 @@ const FilterMenu = ({ const dispatch = useDispatch() const filtersStore = useSelector(store => store.filtersStore) const projectStore = useSelector(store => store.projectStore) - const changes = useSelector(store => store.detailsStore.changes) + const changes = useSelector(store => store.commonDetailsStore.changes) useEffect(() => { setLabels(filtersStore.labels) diff --git a/src/components/FilterMenu/filterMenu.settings.js b/src/components/FilterMenu/filterMenu.settings.js index 2d067686e8..ac05705cee 100644 --- a/src/components/FilterMenu/filterMenu.settings.js +++ b/src/components/FilterMenu/filterMenu.settings.js @@ -42,25 +42,36 @@ import { SORT_BY, STATUS_FILTER, TAG_FILTER_ALL_ITEMS, - TAG_FILTER_LATEST + TAG_FILTER_LATEST, + REAL_TIME_FILTER, + BATCH_FILTER, + PENDING_STATE, + RUNNING_STATE, + COMPLETED_STATE, + ABORTED_STATE, + ABORTING_STATE, + PENDING_RETRY_STATE, + TERMINATING_STATE } from '../../constants' export const jobsStatuses = [ { label: 'All', id: FILTER_ALL_ITEMS, status: FILTER_ALL_ITEMS }, - { label: 'Aborted', id: 'aborted', status: 'aborted' }, - { label: 'Aborting', id: 'aborting', status: 'aborting' }, - { label: 'Completed', id: 'completed', status: 'completed' }, + { label: 'Aborted', id: ABORTED_STATE, status: ABORTED_STATE }, + { label: 'Aborting', id: ABORTING_STATE, status: ABORTING_STATE }, + { label: 'Completed', id: COMPLETED_STATE, status: COMPLETED_STATE }, { label: 'Error', id: ERROR_STATE, status: ERROR_STATE }, - { label: 'Running', id: 'running', status: 'running' }, - { label: 'Pending', id: 'pending', status: 'pending' } + { label: 'Running', id: RUNNING_STATE, status: RUNNING_STATE }, + { label: 'Pending', id: PENDING_STATE, status: PENDING_STATE }, + { label: 'Pending retry', id: PENDING_RETRY_STATE, status: PENDING_RETRY_STATE } ] export const workflowsStatuses = [ { label: 'All', id: FILTER_ALL_ITEMS, status: FILTER_ALL_ITEMS }, { label: 'Error', id: ERROR_STATE, status: ERROR_STATE }, { label: 'Failed', id: FAILED_STATE, status: FAILED_STATE }, - { label: 'Running', id: 'running', status: 'running' }, - { label: 'Completed', id: 'completed', status: 'completed' } + { label: 'Running', id: RUNNING_STATE, status: RUNNING_STATE }, + { label: 'Completed', id: COMPLETED_STATE, status: COMPLETED_STATE }, + { label: 'Terminating', id: TERMINATING_STATE, status: TERMINATING_STATE } ] export const generateStatusFilter = useFailedStatus => { @@ -68,11 +79,11 @@ export const generateStatusFilter = useFailedStatus => { return [ { label: 'All', id: FILTER_ALL_ITEMS, status: FILTER_ALL_ITEMS }, - { label: 'Completed', id: 'completed', status: 'completed' }, - { label: 'Running', id: 'running', status: 'running' }, - { label: 'Pending', id: 'pending', status: 'pending' }, + { label: 'Completed', id: COMPLETED_STATE, status: COMPLETED_STATE }, + { label: 'Running', id: RUNNING_STATE, status: RUNNING_STATE }, + { label: 'Pending', id: PENDING_STATE, status: PENDING_STATE }, { label: 'Error', id: status, status: status }, - { label: 'Aborted', id: 'aborted', status: 'aborted' } + { label: 'Aborted', id: ABORTED_STATE, status: ABORTED_STATE } ] } @@ -105,6 +116,21 @@ export const generateTypeFilter = tab => { ] } +export const modelEndpointsModesList = [ + { + id: FILTER_ALL_ITEMS, + label: 'All' + }, + { + id: REAL_TIME_FILTER, + label: 'Real-time' + }, + { + id: BATCH_FILTER, + label: 'Batch' + } +] + export const filterSelectOptions = { [STATUS_FILTER]: generateStatusFilter(false), [GROUP_BY_FILTER]: [ @@ -124,6 +150,6 @@ export const tagFilterOptions = [ export const getTagFilterOptions = (isLatestOnly = false) => { return [ { label: 'latest', id: TAG_FILTER_LATEST }, - ...(isLatestOnly ? [] : [{ label: 'All tags', id: TAG_FILTER_ALL_ITEMS }]) + ...(isLatestOnly ? [] : [{ label: 'All tags', id: TAG_FILTER_ALL_ITEMS }]) ] -} \ No newline at end of file +} diff --git a/src/components/FilterMenuModal/FilterMenuModal.jsx b/src/components/FilterMenuModal/FilterMenuModal.jsx index 4a5c4f4cf7..9c8325cc3b 100644 --- a/src/components/FilterMenuModal/FilterMenuModal.jsx +++ b/src/components/FilterMenuModal/FilterMenuModal.jsx @@ -30,6 +30,7 @@ import { PopUpDialog, RoundedIcon, Button } from 'igz-controls/components' import { PRIMARY_BUTTON, TERTIARY_BUTTON } from 'igz-controls/constants' import { isTargetElementInContainerElement } from '../../utils/checkElementsPosition.utils' import { setModalFiltersValues } from '../../reducers/filtersReducer' +import { performDetailsActionHelper } from '../Details/details.util' import FilterIcon from 'igz-controls/images/filter.svg?react' @@ -42,6 +43,7 @@ const FilterMenuModal = ({ applyButton = { label: 'Apply', variant: PRIMARY_BUTTON }, cancelButton = { label: 'Clear', variant: TERTIARY_BUTTON }, children, + detailsChanges = null, filterMenuName = '', header = 'Filter by', initialValues, @@ -50,14 +52,14 @@ const FilterMenuModal = ({ wizardClassName = '' }) => { const [filtersWizardIsShown, setFiltersWizardIsShown] = useState(false) - const filtersIconButtonRef = useRef() - const dispatch = useDispatch() - const formRef = React.useRef( - createForm({ + const [form] = useState(() => { + return createForm({ onSubmit: () => {}, initialValues }) - ) + }) + const filtersIconButtonRef = useRef() + const dispatch = useDispatch() const filtersIconClassnames = classnames( 'filters-button', !isEqual(values, initialValues) && 'filters-button_applied' @@ -66,14 +68,14 @@ const FilterMenuModal = ({ const filtersWizardClassnames = classnames('filters-wizard', wizardClassName) useEffect(() => { - if (!isEqual(formRef.current?.getState().values, values)) { - formRef.current?.batch(() => { + if (!isEqual(form.getState().values, values)) { + form.batch(() => { for (const filterName in values) { - formRef.current?.change(filterName, values[filterName]) + form.change(filterName, values[filterName]) } }) } - }, [values]) + }, [form, values]) const hideFiltersWizard = useCallback(event => { if ( @@ -100,8 +102,8 @@ const FilterMenuModal = ({ }, [hideFiltersWizard]) useLayoutEffect(() => { - formRef.current.reset(initialValues) - }, [initialValues]) + form.reset(initialValues) + }, [form, initialValues]) const getFilterCounter = formState => { const initialValuesLocal = applyChanges ? initialValues : formState.initialValues @@ -133,28 +135,36 @@ const FilterMenuModal = ({ setFiltersWizardIsShown(false) } - const handleClearFilters = (formState, counter) => { + const handleClearFilters = async (formState, counter) => { if (!isEqual(initialValues, formState.values)) { - formRef.current.restart(initialValues) - setFiltersWizardIsShown(false) + let actionCanBePerformed = true - if (counter > 0) { - if (filterMenuName) { - dispatch( - setModalFiltersValues({ - name: filterMenuName, - value: initialValues - }) - ) - } + if (detailsChanges) { + actionCanBePerformed = await performDetailsActionHelper(detailsChanges, dispatch, true) + } - applyChanges && applyChanges(initialValues) + if (actionCanBePerformed) { + form.restart(initialValues) + setFiltersWizardIsShown(false) + + if (counter > 0) { + if (filterMenuName) { + dispatch( + setModalFiltersValues({ + name: filterMenuName, + value: initialValues + }) + ) + } + + applyChanges && applyChanges(initialValues, true) + } } } } return ( -
{}}> + {}}> {formState => { const counter = getFilterCounter(formState) return ( @@ -226,6 +236,7 @@ FilterMenuModal.propTypes = { variant: PropTypes.string.isRequired }), children: PropTypes.node.isRequired, + detailsChanges: PropTypes.object, filterMenuName: PropTypes.string, header: PropTypes.string, initialValues: PropTypes.object.isRequired, diff --git a/src/components/FilterMenuModal/filterMenuModal.scss b/src/components/FilterMenuModal/filterMenuModal.scss index 54ce1aab92..a0f5e0dfd8 100644 --- a/src/components/FilterMenuModal/filterMenuModal.scss +++ b/src/components/FilterMenuModal/filterMenuModal.scss @@ -13,16 +13,16 @@ top: 0; margin: 0; padding: 0 0 16px; - background: colors.$white; + color: colors.$mulledWine; font-weight: 500; font-size: 20px; line-height: 23.44px; - color: colors.$mulledWine; + background: colors.$white; } &__list { - padding-right: 15px; margin: 0 -15px 0 0; + padding-right: 15px; overflow-y: auto; } @@ -44,16 +44,16 @@ position: relative; &::after { - content: ''; position: absolute; top: 4px; right: 4px; - height: 10px; + z-index: 2; width: 10px; + height: 10px; + background: colors.$brightTurquoise; border: 2px solid colors.$white; border-radius: 50%; - background: colors.$brightTurquoise; - z-index: 2; + content: ''; } } } diff --git a/src/components/FunctionsPage/Functions.jsx b/src/components/FunctionsPage/Functions.jsx index 25b4a242a9..7afb6a6742 100644 --- a/src/components/FunctionsPage/Functions.jsx +++ b/src/components/FunctionsPage/Functions.jsx @@ -62,19 +62,20 @@ import { } from '../../reducers/functionReducer' import createFunctionsRowData from '../../utils/createFunctionsRowData' import { DANGER_BUTTON, TERTIARY_BUTTON } from 'igz-controls/constants' -import { transformSearchParams } from '../../utils/filter.util' +import { transformSearchParams } from 'igz-controls/utils/filter.util' import { isBackgroundTaskRunning } from '../../utils/poll.util' import { isDetailsTabExists } from '../../utils/link-helper.util' import { openPopUp } from 'igz-controls/utils/common.util' import { parseFunctions } from '../../utils/parseFunctions' import { runNewJob } from '../../reducers/jobReducer' import { setFilters } from '../../reducers/filtersReducer' -import { setNotification } from '../../reducers/notificationReducer' -import { showErrorNotification } from '../../utils/notifications.util' +import { setNotification } from 'igz-controls/reducers/notificationReducer' +import { showErrorNotification } from 'igz-controls/utils/notification.util' import { toggleYaml } from '../../reducers/appReducer' import { useFiltersFromSearchParams } from '../../hooks/useFiltersFromSearchParams.hook' import { useMode } from '../../hooks/mode.hook' import { usePagination } from '../../hooks/usePagination.hook' +import { useTableScroll } from 'igz-controls/hooks/useTable.hook' const Functions = ({ isAllVersions = false }) => { const [confirmData, setConfirmData] = useState(null) @@ -649,6 +650,12 @@ const Functions = ({ isAllVersions = false }) => { resetPaginationTrigger: `${params.projectName}_${isAllVersions}` }) + useTableScroll({ + content: isAllVersions ? paginatedFunctionVersions : paginatedFunctions, + selectedItem: selectedFunction, + isAllVersions + }) + const tableContent = useMemo( () => (isAllVersions ? paginatedFunctionVersions : paginatedFunctions).map(contentItem => diff --git a/src/components/FunctionsPage/FunctionsView.jsx b/src/components/FunctionsPage/FunctionsView.jsx index 89c2dfaaf8..0d86b6d5d8 100644 --- a/src/components/FunctionsPage/FunctionsView.jsx +++ b/src/components/FunctionsPage/FunctionsView.jsx @@ -27,11 +27,10 @@ import FunctionsFilters from './FunctionsFilters' import FunctionsPanel from '../FunctionsPanel/FunctionsPanel' import FunctionsTableRow from '../../elements/FunctionsTableRow/FunctionsTableRow' import HistoryBackLink from '../../common/HistoryBackLink/historyBackLink' -import Loader from '../../common/Loader/Loader' import NoData from '../../common/NoData/NoData' import Pagination from '../../common/Pagination/Pagination' import Table from '../Table/Table' -import { ConfirmDialog } from 'igz-controls/components' +import { ConfirmDialog, Loader } from 'igz-controls/components' import { FUNCTIONS_PAGE, @@ -44,7 +43,7 @@ import { FILTERS_CONFIG } from '../../types' import { PRIMARY_BUTTON } from 'igz-controls/constants' import { getCloseDetailsLink } from '../../utils/link-helper.util' import { getNoDataMessage } from '../../utils/getNoDataMessage' -import { getSavedSearchParams } from '../../utils/filter.util' +import { getSavedSearchParams } from 'igz-controls/utils/filter.util' import { isEmpty } from 'lodash' const FunctionsView = ({ @@ -106,6 +105,7 @@ const FunctionsView = ({ filtersConfig={functionsFiltersConfig} handleRefresh={handleRefreshFunctions} setSearchParams={setSearchFunctionsParams} + selectedItemName={params.funcName} withoutExpandButton > @@ -130,7 +130,7 @@ const FunctionsView = ({ - getCloseDetailsLink(isAllVersions ? ALL_VERSIONS_PATH : FUNCTIONS_PAGE_PATH) + getCloseDetailsLink(isAllVersions ? ALL_VERSIONS_PATH : FUNCTIONS_PAGE_PATH, false, params.funcName) } handleCancel={handleCancel} pageData={pageData} @@ -160,6 +160,7 @@ const FunctionsView = ({ )} diff --git a/src/components/FunctionsPage/functions.scss b/src/components/FunctionsPage/functions.scss index bacdf5ce64..50d3a180c3 100644 --- a/src/components/FunctionsPage/functions.scss +++ b/src/components/FunctionsPage/functions.scss @@ -1,5 +1,5 @@ @use 'igz-controls/scss/variables'; -@use '/src/scss/mixins'; +@use '@/scss/mixins'; $functionsRowHeight: variables.$rowHeight; $functionsHeaderRowHeight: variables.$headerRowHeight; diff --git a/src/components/FunctionsPage/functions.util.jsx b/src/components/FunctionsPage/functions.util.jsx index 6371618c3c..40206dcc51 100644 --- a/src/components/FunctionsPage/functions.util.jsx +++ b/src/components/FunctionsPage/functions.util.jsx @@ -25,7 +25,7 @@ import { FUNCTION_CREATING_STATE, ERROR_STATE, FUNCTION_INITIALIZED_STATE, - FUNCTION_PENDINDG_STATE, + FUNCTION_PENDING_STATE, FUNCTION_READY_STATE, FUNCTION_RUN_KINDS, FUNCTION_RUNNING_STATE, @@ -50,8 +50,8 @@ import { getFunctionLogs, getFunctionNuclioLogs } from '../../utils/getFunctionL import { parseFunction } from '../../utils/parseFunction' import { parseIdentifier } from '../../utils' import { setJobFunction } from '../../reducers/jobReducer' -import { setNotification } from '../../reducers/notificationReducer' -import { showErrorNotification } from '../../utils/notifications.util' +import { setNotification } from 'igz-controls/reducers/notificationReducer' +import { showErrorNotification } from 'igz-controls/utils/notification.util' import Delete from 'igz-controls/images/delete.svg?react' import Run from 'igz-controls/images/run.svg?react' @@ -95,7 +95,7 @@ export const infoHeaders = [ { label: 'Image', id: 'image' }, { label: 'Description', id: 'description' } ] -export const TRANSIENT_FUNCTION_STATUSES = [FUNCTION_PENDINDG_STATE, FUNCTION_RUNNING_STATE] +export const TRANSIENT_FUNCTION_STATUSES = [FUNCTION_PENDING_STATE, FUNCTION_RUNNING_STATE] const handleFetchFunctionLogs = ( dispatch, diff --git a/src/components/FunctionsPageOld/FunctionsOld.jsx b/src/components/FunctionsPageOld/FunctionsOld.jsx index 8621af6d8e..dd7061ca82 100644 --- a/src/components/FunctionsPageOld/FunctionsOld.jsx +++ b/src/components/FunctionsPageOld/FunctionsOld.jsx @@ -67,8 +67,8 @@ import { openPopUp, getScssVariableValue } from 'igz-controls/utils/common.util' import { parseFunctions } from '../../utils/parseFunctions' import { runNewJob } from '../../reducers/jobReducer' import { setFilters } from '../../reducers/filtersReducer' -import { setNotification } from '../../reducers/notificationReducer' -import { showErrorNotification } from '../../utils/notifications.util' +import { setNotification } from 'igz-controls/reducers/notificationReducer' +import { showErrorNotification } from 'igz-controls/utils/notification.util' import { toggleYaml } from '../../reducers/appReducer' import { useFiltersFromSearchParams } from '../../hooks/useFiltersFromSearchParams.hook' import { useGroupContent } from '../../hooks/groupContent.hook' @@ -196,6 +196,8 @@ const Functions = () => { }) } } + }).catch(() => { + setFunctions([]) }) }, [ @@ -228,7 +230,7 @@ const Functions = () => { return { ...state, [funcIdentifier]: { - content: content[func.name].map(contentItem => + content: content[funcIdentifier].map(contentItem => createFunctionsRowData(contentItem, params.projectName, false, false, true) ) } diff --git a/src/components/FunctionsPageOld/FunctionsViewOld.jsx b/src/components/FunctionsPageOld/FunctionsViewOld.jsx index fe17e01448..d29cb7f2ab 100644 --- a/src/components/FunctionsPageOld/FunctionsViewOld.jsx +++ b/src/components/FunctionsPageOld/FunctionsViewOld.jsx @@ -26,10 +26,9 @@ import Breadcrumbs from '../../common/Breadcrumbs/Breadcrumbs' import FunctionsFilters from '../FunctionsPage/FunctionsFilters' import FunctionsPanel from '../FunctionsPanel/FunctionsPanel' import FunctionsTableRowOld from '../../elements/FunctionsTableRow/FunctionsTableRowOld' -import Loader from '../../common/Loader/Loader' import NoData from '../../common/NoData/NoData' import Table from '../Table/Table' -import { ConfirmDialog } from 'igz-controls/components' +import { ConfirmDialog, Loader } from 'igz-controls/components' import { FUNCTIONS_PAGE, @@ -38,7 +37,8 @@ import { PANEL_EDIT_MODE } from '../../constants' import { PRIMARY_BUTTON } from 'igz-controls/constants' -import { FILTERS_CONFIG, VIRTUALIZATION_CONFIG } from '../../types' +import { VIRTUALIZATION_CONFIG } from 'igz-controls/types' +import { FILTERS_CONFIG } from '../../types' import { getNoDataMessage } from '../../utils/getNoDataMessage' import { isRowRendered } from '../../hooks/useVirtualization.hook' diff --git a/src/components/FunctionsPageOld/functionsOld.util.jsx b/src/components/FunctionsPageOld/functionsOld.util.jsx index ac0c25886c..b2a6f81a6a 100644 --- a/src/components/FunctionsPageOld/functionsOld.util.jsx +++ b/src/components/FunctionsPageOld/functionsOld.util.jsx @@ -25,7 +25,7 @@ import { FUNCTION_CREATING_STATE, ERROR_STATE, FUNCTION_INITIALIZED_STATE, - FUNCTION_PENDINDG_STATE, + FUNCTION_PENDING_STATE, FUNCTION_READY_STATE, FUNCTION_RUN_KINDS, FUNCTION_RUNNING_STATE, @@ -43,8 +43,8 @@ import functionsApi from '../../api/functions-api' import tasksApi from '../../api/tasks-api' import { BG_TASK_FAILED, BG_TASK_SUCCEEDED, pollTask } from '../../utils/poll.util' import { parseFunction } from '../../utils/parseFunction' -import { setNotification } from '../../reducers/notificationReducer' -import { showErrorNotification } from '../../utils/notifications.util' +import { setNotification } from 'igz-controls/reducers/notificationReducer' +import { showErrorNotification } from 'igz-controls/utils/notification.util' import { getFunctionLogs, getFunctionNuclioLogs } from '../../utils/getFunctionLogs' import { setJobFunction } from '../../reducers/jobReducer' @@ -89,7 +89,7 @@ export const infoHeaders = [ { label: 'Image', id: 'image' }, { label: 'Description', id: 'description' } ] -export const TRANSIENT_FUNCTION_STATUSES = [FUNCTION_PENDINDG_STATE, FUNCTION_RUNNING_STATE] +export const TRANSIENT_FUNCTION_STATUSES = [FUNCTION_PENDING_STATE, FUNCTION_RUNNING_STATE] const handleFetchFunctionLogs = ( dispatch, diff --git a/src/components/FunctionsPanel/FunctionsPanel.jsx b/src/components/FunctionsPanel/FunctionsPanel.jsx index a6de059def..03bc6da589 100644 --- a/src/components/FunctionsPanel/FunctionsPanel.jsx +++ b/src/components/FunctionsPanel/FunctionsPanel.jsx @@ -90,15 +90,15 @@ const FunctionsPanel = ({ ) const params = useParams() const navigate = useNavigate() - const formRef = React.useRef( - createForm({ + const [form] = useState(() => { + return createForm({ initialValues: { labels: parseChipsData(defaultData?.labels || {}, frontendSpec.internal_labels) }, mutators: { ...arrayMutators, setFieldState }, onSubmit: () => {} }) - ) + }) const dispatch = useDispatch() const functionsStore = useSelector(store => store.functionsStore) const appStore = useSelector(store => store.appStore) @@ -306,7 +306,7 @@ const FunctionsPanel = ({ } return createPortal( - {}}> + {}}> {formState => { return ( <> diff --git a/src/components/FunctionsPanel/FunctionsPanelView.jsx b/src/components/FunctionsPanel/FunctionsPanelView.jsx index 14d15a18cc..2f8d66223b 100644 --- a/src/components/FunctionsPanel/FunctionsPanelView.jsx +++ b/src/components/FunctionsPanel/FunctionsPanelView.jsx @@ -22,16 +22,14 @@ import PropTypes from 'prop-types' import { useDispatch } from 'react-redux' import Accordion from '../../common/Accordion/Accordion' -import ErrorMessage from '../../common/ErrorMessage/ErrorMessage' import FunctionsPanelCode from '../../elements/FunctionsPanelCode/FunctionsPanelCode' import FunctionsPanelEnvironmentVariables from '../../elements/FunctionsPanelEnvironmentVariables/FunctionsPanelEnvironmentVariables' import FunctionsPanelGeneral from '../../elements/FunctionsPanelGeneral/FunctionsPanelGeneral' import FunctionsPanelResources from '../../elements/FunctionsPanelResources/FunctionsPanelResources' import FunctionsPanelRuntime from '../../elements/FunctionsPanelRuntime/FunctionsPanelRuntime' import FunctionsPanelTitle from '../../elements/FunctionsPanelTitle/FunctionsPanelTitle' -import Loader from '../../common/Loader/Loader' import PanelCredentialsAccessKey from '../../elements/PanelCredentialsAccessKey/PanelCredentialsAccessKey' -import { Button, ConfirmDialog } from 'igz-controls/components' +import { Button, ConfirmDialog, ErrorMessage, Loader } from 'igz-controls/components' import { removeFunctionsError, diff --git a/src/components/FunctionsPanel/functionsPanel.scss b/src/components/FunctionsPanel/functionsPanel.scss index be5b458e08..0cd25a6647 100644 --- a/src/components/FunctionsPanel/functionsPanel.scss +++ b/src/components/FunctionsPanel/functionsPanel.scss @@ -1,7 +1,6 @@ @use 'igz-controls/scss/colors'; @use 'igz-controls/scss/borders'; @use 'igz-controls/scss/mixins'; - @include mixins.newItemSidePanel; .functions-panel { diff --git a/src/components/JobWizard/JobWizard.jsx b/src/components/JobWizard/JobWizard.jsx index da8727b86d..5ffa315e02 100644 --- a/src/components/JobWizard/JobWizard.jsx +++ b/src/components/JobWizard/JobWizard.jsx @@ -34,9 +34,8 @@ import JobWizardHyperparameterStrategy from './JobWizardSteps/JobWizardHyperpara import JobWizardParameters from './JobWizardSteps/JobWizardParameters/JobWizardParameters' import JobWizardResources from './JobWizardSteps/JobWizardResources/JobWizardResources' import JobWizardRunDetails from './JobWizardSteps/JobWizardRunDetails/JobWizardRunDetails' -import Loader from '../../common/Loader/Loader' import ScheduleWizard from '../SheduleWizard/ScheduleWizard' -import { Wizard } from 'igz-controls/components' +import { Wizard, Loader } from 'igz-controls/components' import { ADVANCED_STEP, @@ -44,6 +43,9 @@ import { FUNCTION_SELECTION_STEP, HYPERPARAMETER_STRATEGY_STEP, JOB_WIZARD_FILTERS, + JOBS_MONITORING_JOBS_TAB, + JOBS_MONITORING_PAGE, + JOBS_MONITORING_SCHEDULED_TAB, MONITOR_JOBS_TAB, PANEL_CREATE_MODE, PANEL_EDIT_MODE, @@ -73,8 +75,8 @@ import { editJob, removeJobFunction, runNewJob } from '../../reducers/jobReducer import { fetchProject } from '../../reducers/projectReducer' import { resetModalFilter } from '../../reducers/filtersReducer' import { setFieldState, isSubmitDisabled } from 'igz-controls/utils/form.util' -import { setNotification } from '../../reducers/notificationReducer' -import { showErrorNotification } from '../../utils/notifications.util' +import { setNotification } from 'igz-controls/reducers/notificationReducer' +import { showErrorNotification } from 'igz-controls/utils/notification.util' import { useModalBlockHistory } from '../../hooks/useModalBlockHistory.hook' import './jobWizard.scss' @@ -82,6 +84,7 @@ import './jobWizard.scss' const JobWizard = ({ defaultData = {}, isBatchInference = false, + isCrossProjects = false, isOpen, isTrain = false, mode = PANEL_CREATE_MODE, @@ -92,13 +95,13 @@ const JobWizard = ({ prePopulatedData = {}, wizardTitle = 'Batch run' }) => { - const formRef = React.useRef( - createForm({ + const [form] = useState(() => { + return createForm({ onSubmit: () => {}, mutators: { ...arrayMutators, setFieldState }, initialValues: {} }) - ) + }) const isEditMode = useMemo(() => mode === PANEL_EDIT_MODE || mode === PANEL_RERUN_MODE, [mode]) const isRunMode = useMemo(() => mode === PANEL_FUNCTION_CREATE_MODE, [mode]) const projectIsLoading = useSelector(store => store.projectStore.project.loading) @@ -131,7 +134,7 @@ const JobWizard = ({ onWizardClose && onWizardClose() }, [dispatch, onResolve, onWizardClose, showSchedule]) - const { handleCloseModal, resolveModal } = useModalBlockHistory(closeModal, formRef.current) + const { handleCloseModal, resolveModal } = useModalBlockHistory(closeModal, form) useEffect(() => { if (!isEditMode) { @@ -185,9 +188,11 @@ const JobWizard = ({ useEffect(() => { if (!isEmpty(jobsStore.jobFunc)) { - setSelectedFunctionData({ - name: jobsStore.jobFunc.metadata.name, - functions: [jobsStore.jobFunc] + queueMicrotask(() => { + setSelectedFunctionData({ + name: jobsStore.jobFunc.metadata.name, + functions: [jobsStore.jobFunc] + }) }) } }, [isEditMode, isRunMode, jobsStore.jobFunc]) @@ -265,19 +270,19 @@ const JobWizard = ({ const stepsConfig = [ { id: FUNCTION_SELECTION_STEP, - label: 'Function Selection', + label: 'Function selection', hidden: isEditMode || isRunMode || isBatchInference || isTrain, nextIsDisabled: isEmpty(selectedFunctionData) }, { id: RUN_DETAILS_STEP, - label: 'Run Details', + label: 'Run details', disabled: isEmpty(selectedFunctionData) || isEmpty(get(formState.initialValues, RUN_DETAILS_STEP)) }, { id: DATA_INPUTS_STEP, - label: 'Data Inputs' + label: 'Data inputs' }, { id: PARAMETERS_STEP, @@ -328,7 +333,7 @@ const JobWizard = ({ setShowSchedule(state => !state) } resolveModal() - onSuccessRequest && onSuccessRequest(true) + onSuccessRequest && onSuccessRequest(true, isSchedule) dispatch( setNotification({ status: 200, @@ -338,15 +343,17 @@ const JobWizard = ({ ) }) .then(() => { - return navigate( - `/projects/${params.projectName}/jobs/${isSchedule ? SCHEDULE_TAB : MONITOR_JOBS_TAB}` + navigate( + isCrossProjects + ? `/projects/*/${JOBS_MONITORING_PAGE}/${isSchedule ? JOBS_MONITORING_SCHEDULED_TAB : JOBS_MONITORING_JOBS_TAB}` + : `/projects/${params.projectName}/jobs/${isSchedule ? SCHEDULE_TAB : MONITOR_JOBS_TAB}` ) }) .catch(error => { showErrorNotification(dispatch, error, '', getNewJobErrorMsg(error)) }) }, - [dispatch, mode, navigate, onSuccessRequest, resolveModal] + [dispatch, mode, navigate, onSuccessRequest, resolveModal, isCrossProjects] ) const editJobHandler = useCallback( @@ -377,8 +384,12 @@ const JobWizard = ({ if (isSchedule) { setShowSchedule(state => !state) } + resolveModal() - onSuccessRequest && onSuccessRequest() + + return onSuccessRequest && onSuccessRequest(isSchedule, true) + }) + .then(() => { dispatch( setNotification({ status: 200, @@ -387,14 +398,11 @@ const JobWizard = ({ }) ) }) - .then(() => { - navigate(`/projects/${params.projectName}/jobs/${SCHEDULE_TAB}${window.location.search}`) - }) .catch(error => { showErrorNotification(dispatch, error, '', getSaveJobErrorMsg(error)) }) }, - [dispatch, mode, navigate, onSuccessRequest, resolveModal] + [dispatch, mode, onSuccessRequest, resolveModal] ) const submitRequest = useCallback( @@ -422,7 +430,7 @@ const JobWizard = ({ { id: 'schedule-btn', label: isBatchInference - ? 'Schedule Infer' + ? 'Schedule infer' : isTrain ? 'Schedule training job' : 'Schedule for later', @@ -461,7 +469,7 @@ const JobWizard = ({ ) return ( - {}}> + {}}> {formState => { formStateRef.current = formState @@ -472,9 +480,7 @@ const JobWizard = ({ formState={formState} id="jobWizard" isWizardOpen={isOpen} - onWizardResolve={() => { - handleCloseModal() - }} + onWizardResolve={handleCloseModal} previewText={isBatchInference ? 'Tech Preview' : ''} size={MODAL_MAX} stepsConfig={getStepsConfig(formState)} @@ -554,6 +560,7 @@ const JobWizard = ({ JobWizard.propTypes = { defaultData: PropTypes.object, isBatchInference: PropTypes.bool, + isCrossProjects: PropTypes.bool, isOpen: PropTypes.bool.isRequired, isTrain: PropTypes.bool, mode: JOB_WIZARD_MODE, diff --git a/src/components/JobWizard/JobWizard.util.js b/src/components/JobWizard/JobWizard.util.js index f41c20071f..85c29df8e0 100644 --- a/src/components/JobWizard/JobWizard.util.js +++ b/src/components/JobWizard/JobWizard.util.js @@ -86,7 +86,7 @@ import { generateObjectFromKeyValue, parseObjectToKeyValue } from 'igz-controls/ import { getDefaultSchedule, scheduleDataInitialState } from '../SheduleWizard/scheduleWizard.util' import { getErrorDetail } from 'igz-controls/utils/common.util' import { getPreemptionMode } from '../../utils/getPreemptionMode' -import { trimSplit } from '../../utils' +import { trimSplit } from 'igz-controls/utils/string.util' const volumeTypesMap = { [CONFIG_MAP_VOLUME_TYPE]: 'configMap', @@ -1153,7 +1153,7 @@ export const getNewJobErrorMsg = error => { } export const getSaveJobErrorMsg = error => { - return error.response.status === FORBIDDEN_ERROR_STATUS_CODE + return error?.response?.status === FORBIDDEN_ERROR_STATUS_CODE ? 'You do not have permission to run a new job.' : getErrorDetail(error) || 'Unable to save the job.' } diff --git a/src/components/JobWizard/JobWizardSteps/JobWizardAdvanced/jobWizardAdvanced.scss b/src/components/JobWizard/JobWizardSteps/JobWizardAdvanced/jobWizardAdvanced.scss index d4dbe92516..be91e46cc2 100644 --- a/src/components/JobWizard/JobWizardSteps/JobWizardAdvanced/jobWizardAdvanced.scss +++ b/src/components/JobWizard/JobWizardSteps/JobWizardAdvanced/jobWizardAdvanced.scss @@ -1,5 +1,5 @@ .job-wizard__advanced { .access-key-checkbox { - margin: 30px 10px 0 10px; + margin: 30px 10px 0; } } diff --git a/src/components/JobWizard/JobWizardSteps/JobWizardDataInputs/JobWizardDataInputs.jsx b/src/components/JobWizard/JobWizardSteps/JobWizardDataInputs/JobWizardDataInputs.jsx index 235c555a98..2ff525ccfb 100644 --- a/src/components/JobWizard/JobWizardSteps/JobWizardDataInputs/JobWizardDataInputs.jsx +++ b/src/components/JobWizard/JobWizardSteps/JobWizardDataInputs/JobWizardDataInputs.jsx @@ -28,7 +28,7 @@ const JobWizardDataInputs = ({ formState, params, stepIsActive = false }) => { return (
-
Data Inputs
+
Data inputs
{ + setFunctions([]) + }) + //TODO: formState.initialValues[FUNCTION_SELECTION_STEP].projectName = currentValue } @@ -420,7 +423,11 @@ const JobWizardFunctionSelection = ({
- +
{!loading && diff --git a/src/components/JobWizard/JobWizardSteps/JobWizardFunctionSelection/jobWizardFunctionSelection.scss b/src/components/JobWizard/JobWizardSteps/JobWizardFunctionSelection/jobWizardFunctionSelection.scss index ea94067e61..c6b6037317 100644 --- a/src/components/JobWizard/JobWizardSteps/JobWizardFunctionSelection/jobWizardFunctionSelection.scss +++ b/src/components/JobWizard/JobWizardSteps/JobWizardFunctionSelection/jobWizardFunctionSelection.scss @@ -24,8 +24,8 @@ } .content-menu { - margin-bottom: 15px; min-width: unset; + margin-bottom: 15px; } .form-row__project-name { diff --git a/src/components/JobWizard/JobWizardSteps/JobWizardHyperparameterStrategy/jobWizardHyperparametersStrategy.scss b/src/components/JobWizard/JobWizardSteps/JobWizardHyperparameterStrategy/jobWizardHyperparametersStrategy.scss index 0c25490871..e13f0163f0 100644 --- a/src/components/JobWizard/JobWizardSteps/JobWizardHyperparameterStrategy/jobWizardHyperparametersStrategy.scss +++ b/src/components/JobWizard/JobWizardSteps/JobWizardHyperparameterStrategy/jobWizardHyperparametersStrategy.scss @@ -1,9 +1,6 @@ .job-wizard__hyperparameter-strategy { .grid-container { display: grid; - gap: 15px; - align-items: center; - grid-template-columns: 20% 20% 20% 20%; grid-template-areas: 'strategy-grid-item strategy-grid-item . .' 'max-iterations-grid-item max-errors-grid-item . .' @@ -13,19 +10,22 @@ 'stop-condition-grid-item stop-condition-grid-item . .' 'parallelism-title-grid-item parallelism-title-grid-item . .' 'parallel-runs-grid-item dask-cluster-uri-grid-item dask-cluster-uri-grid-item teardown-dask-grid-item'; + grid-template-columns: 20% 20% 20% 20%; + gap: 15px; + align-items: center; .strategy-grid-item { grid-area: strategy-grid-item; } .max-iterations-grid-item { - min-width: 100px; grid-area: max-iterations-grid-item; + min-width: 100px; } .max-errors-grid-item { - min-width: 100px; grid-area: max-errors-grid-item; + min-width: 100px; } .ranking-title-grid-item { diff --git a/src/components/JobWizard/JobWizardSteps/JobWizardRunDetails/JobWizardRunDetails.jsx b/src/components/JobWizard/JobWizardSteps/JobWizardRunDetails/JobWizardRunDetails.jsx index 646f18487e..37b5114fee 100644 --- a/src/components/JobWizard/JobWizardSteps/JobWizardRunDetails/JobWizardRunDetails.jsx +++ b/src/components/JobWizard/JobWizardSteps/JobWizardRunDetails/JobWizardRunDetails.jsx @@ -43,7 +43,7 @@ import { } from '../../../../constants' import { PRIMARY_BUTTON, TERTIARY_BUTTON } from 'igz-controls/constants' import { areFormValuesChanged } from 'igz-controls/utils/form.util' -import { getChipOptions } from '../../../../utils/getChipOptions' +import { getChipOptions } from 'igz-controls/utils/chips.util' import { getValidationRules, getInternalLabelsValidationRule @@ -202,7 +202,7 @@ const JobWizardRunDetails = ({ } }, header: 'Are you sure?', - message: 'Changes made to the Data Inputs and Parameters sections will be lost' + message: 'Changes made to the data inputs and parameters sections will be lost' }) } else { handleHandlerChange(currentHandler) @@ -213,7 +213,7 @@ const JobWizardRunDetails = ({ !isEmpty(jobAdditionalData) && (
-
Run Details
+
Run details
{!isBatchInference && (
diff --git a/src/components/Jobs/Jobs.jsx b/src/components/Jobs/Jobs.jsx index 29eab255a4..bf4a916c07 100644 --- a/src/components/Jobs/Jobs.jsx +++ b/src/components/Jobs/Jobs.jsx @@ -24,9 +24,8 @@ import { defaultsDeep, isEmpty } from 'lodash' import Breadcrumbs from '../../common/Breadcrumbs/Breadcrumbs' import ContentMenu from '../../elements/ContentMenu/ContentMenu' -import Loader from '../../common/Loader/Loader' import PreviewModal from '../../elements/PreviewModal/PreviewModal' -import { ConfirmDialog } from 'igz-controls/components' +import { ConfirmDialog, Loader } from 'igz-controls/components' import { INACTIVE_JOBS_TAB, @@ -163,13 +162,15 @@ const Jobs = () => { }, [getWorkflows, handleRefreshJobs, initialTabData, refreshScheduled]) useLayoutEffect(() => { - setSelectedTab( - location.pathname.includes(`${JOBS_PAGE_PATH}/${MONITOR_JOBS_TAB}`) - ? MONITOR_JOBS_TAB - : location.pathname.includes(`${JOBS_PAGE_PATH}/${SCHEDULE_TAB}`) - ? SCHEDULE_TAB - : MONITOR_WORKFLOWS_TAB - ) + queueMicrotask(() => { + setSelectedTab( + location.pathname.includes(`${JOBS_PAGE_PATH}/${MONITOR_JOBS_TAB}`) + ? MONITOR_JOBS_TAB + : location.pathname.includes(`${JOBS_PAGE_PATH}/${SCHEDULE_TAB}`) + ? SCHEDULE_TAB + : MONITOR_WORKFLOWS_TAB + ) + }) }, [location.pathname]) useEffect(() => { @@ -253,7 +254,9 @@ const Jobs = () => { setSearchParams={setSearchParams} tab={selectedTab} withAutoRefresh={selectedTab === MONITOR_JOBS_TAB} - withInternalAutoRefresh={Boolean(selectedTab === MONITOR_JOBS_TAB && params.jobName)} + withInternalAutoRefresh={Boolean( + selectedTab === MONITOR_JOBS_TAB && params.jobName + )} withRefreshButton withoutExpandButton > diff --git a/src/components/Jobs/JobsPage.test.js b/src/components/Jobs/JobsPage.test.js index c34249195e..32cf36f264 100644 --- a/src/components/Jobs/JobsPage.test.js +++ b/src/components/Jobs/JobsPage.test.js @@ -33,7 +33,7 @@ jest.mock('igz-controls/images/arrow.svg', () => ({ ReactComponent: 'arrow-icon' })) -jest.spyOn(mainHttpClient, 'delete').mockImplementation(path => { +jest.spyOn(mainHttpClient, 'delete').mockImplementation(() => { return Promise.resolve([]) }) diff --git a/src/components/Jobs/MonitorJobs/JobsFilters.jsx b/src/components/Jobs/MonitorJobs/JobsFilters.jsx index 147b7c5aea..0f20676b25 100644 --- a/src/components/Jobs/MonitorJobs/JobsFilters.jsx +++ b/src/components/Jobs/MonitorJobs/JobsFilters.jsx @@ -21,9 +21,9 @@ import React from 'react' import { useForm } from 'react-final-form' import { FormInput, FormOnChange, FormSelect } from 'igz-controls/components' -import StatusFilter from '../../../common/StatusFilter/StatusFilter' +import MultiSelectFilter from '../../../common/MultiSelectFilter/MultiSelectFilter' -import { JOBS_MONITORING_JOBS_TAB, LABELS_FILTER, STATUS_FILTER_NAME } from '../../../constants' +import { JOBS_MONITORING_JOBS_TAB, LABELS_FILTER, STATUS_FILTER_NAME, TYPE_FILTER } from '../../../constants' import { generateTypeFilter, jobsStatuses } from '../../FilterMenu/filterMenu.settings' const JobsFilters = () => { @@ -36,12 +36,12 @@ const JobsFilters = () => { return (
- +
diff --git a/src/components/Jobs/MonitorWorkflows/WorkflowsFilters.jsx b/src/components/Jobs/MonitorWorkflows/WorkflowsFilters.jsx index 32586df3ca..1f3f90fead 100644 --- a/src/components/Jobs/MonitorWorkflows/WorkflowsFilters.jsx +++ b/src/components/Jobs/MonitorWorkflows/WorkflowsFilters.jsx @@ -21,7 +21,7 @@ import React from 'react' import { useForm } from 'react-final-form' import { FormInput, FormOnChange } from 'igz-controls/components' -import StatusFilter from '../../../common/StatusFilter/StatusFilter' +import MultiSelectFilter from '../../../common/MultiSelectFilter/MultiSelectFilter' import { LABELS_FILTER, STATUS_FILTER_NAME } from '../../../constants' import { workflowsStatuses } from '../../FilterMenu/filterMenu.settings' @@ -38,7 +38,7 @@ const WorkflowsFilters = () => { return (
- +
{isDemoMode && (
diff --git a/src/components/Jobs/MonitorWorkflows/monitorWorkflows.util.jsx b/src/components/Jobs/MonitorWorkflows/monitorWorkflows.util.jsx index 93dabd6609..f60ad19256 100644 --- a/src/components/Jobs/MonitorWorkflows/monitorWorkflows.util.jsx +++ b/src/components/Jobs/MonitorWorkflows/monitorWorkflows.util.jsx @@ -18,15 +18,18 @@ under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ import React from 'react' -import { debounce } from 'lodash' +import { debounce, isNil } from 'lodash' import { FUNCTIONS_PAGE, + FUNCTION_RUNNING_STATE, GROUP_BY_NONE, GROUP_BY_WORKFLOW, JOBS_PAGE, PENDING_STATE, - UNKNOWN_STATE + UNKNOWN_STATE, + RUNNING_STATE, + TERMINATING_STATE } from '../../../constants' import { getJobsDetailsMenu, @@ -46,7 +49,8 @@ import { isEveryObjectValueEmpty } from '../../../utils/isEveryObjectValueEmpty' import MonitorIcon from 'igz-controls/images/monitor-icon.svg?react' import Run from 'igz-controls/images/run.svg?react' -import Cancel from 'igz-controls/images/close.svg?react' +import Cancel from 'igz-controls/images/cancel.svg?react' +import Close from 'igz-controls/images/close.svg?react' import Yaml from 'igz-controls/images/yaml.svg?react' import Delete from 'igz-controls/images/delete.svg?react' import Rerun from 'igz-controls/images/rerun.svg?react' @@ -83,8 +87,11 @@ export const generateActionsMenu = ( jobs_dashboard_url, handleMonitoring, abortable_function_kinds, + ce, handleConfirmAbortJob, handleConfirmDeleteJob, + handleConfirmTerminateWorkflow, + accessibleProjectsMap, toggleConvertedYaml, handleRerun, rerunIsDisabled @@ -115,7 +122,7 @@ export const generateActionsMenu = ( }, { label: 'Abort', - icon: , + icon: , onClick: handleConfirmAbortJob, tooltip: jobKindIsAbortable ? jobIsAborting @@ -140,7 +147,8 @@ export const generateActionsMenu = ( ] ] } else { - const runningStates = ['running', 'pending'] + const accessKeyExists = !isNil(job?.access_key) + const runningStates = [RUNNING_STATE, PENDING_STATE, TERMINATING_STATE] return [ [ @@ -151,13 +159,21 @@ export const generateActionsMenu = ( }, { disabled: rerunIsDisabled || [PENDING_STATE, UNKNOWN_STATE].includes(job?.state?.value), - hidden: runningStates.includes(job?.state?.value), + hidden: runningStates.includes(job?.state?.value) || accessKeyExists, icon: , label: 'Retry', onClick: () => handleRerun(job), - tooltip: - [PENDING_STATE, UNKNOWN_STATE].includes(job?.state?.value) && - 'Retry is unavailable while workflow status is pending, refresh the display to check for updates.' + tooltip: [PENDING_STATE, UNKNOWN_STATE].includes(job?.state?.value) + ? 'Retry is unavailable while workflow status is pending, refresh the display to check for updates.' + : '' + }, + { + label: 'Terminate', + icon: , + className: 'danger', + onClick: handleConfirmTerminateWorkflow, + hidden: (!ce && !accessibleProjectsMap[job?.project]) || accessKeyExists, + disabled: job?.state?.value !== FUNCTION_RUNNING_STATE } ] ] diff --git a/src/components/Jobs/ScheduledJobs/ScheduledJobs.jsx b/src/components/Jobs/ScheduledJobs/ScheduledJobs.jsx index 1364052fe8..bc46676375 100644 --- a/src/components/Jobs/ScheduledJobs/ScheduledJobs.jsx +++ b/src/components/Jobs/ScheduledJobs/ScheduledJobs.jsx @@ -30,7 +30,7 @@ import { setFilters } from '../../../reducers/filtersReducer' import { useFiltersFromSearchParams } from '../../../hooks/useFiltersFromSearchParams.hook' const ScheduledJobs = () => { - const [dataIsLoaded, setDataIsLoaded] = useState(false) + const [, setDataIsLoaded] = useState(false) const { abortControllerRef, initialTabData, @@ -48,11 +48,15 @@ const ScheduledJobs = () => { ) useEffect(() => { - if (!dataIsLoaded) { - refreshJobs(filters) - setDataIsLoaded(true) - } - }, [dataIsLoaded, filters, refreshJobs]) + setDataIsLoaded((prevState) => { + if (!prevState) { + refreshJobs(filters) + return true + } else { + return prevState + } + }) + }, [filters, refreshJobs]) useEffect(() => { const abortControllerRefCurrent = abortControllerRef.current diff --git a/src/components/Jobs/ScheduledJobs/ScheduledJobsFilters.jsx b/src/components/Jobs/ScheduledJobs/ScheduledJobsFilters.jsx index 69163fbeb4..ef6c4952de 100644 --- a/src/components/Jobs/ScheduledJobs/ScheduledJobsFilters.jsx +++ b/src/components/Jobs/ScheduledJobs/ScheduledJobsFilters.jsx @@ -20,9 +20,10 @@ such restriction. import React from 'react' import { useForm } from 'react-final-form' -import { FormInput, FormOnChange, FormSelect } from 'igz-controls/components' +import MultiSelectFilter from '../../../common/MultiSelectFilter/MultiSelectFilter' +import { FormInput, FormOnChange } from 'igz-controls/components' -import { JOBS_MONITORING_SCHEDULED_TAB, LABELS_FILTER } from '../../../constants' +import { JOBS_MONITORING_SCHEDULED_TAB, LABELS_FILTER, TYPE_FILTER } from '../../../constants' import { generateTypeFilter } from '../../FilterMenu/filterMenu.settings' const ScheduledJobsFilters = () => { @@ -35,11 +36,7 @@ const ScheduledJobsFilters = () => { return (
- +
{ const infoHeaders = [ { label: 'UID', id: 'uid' }, { label: 'Start time', id: 'startTime' }, - { label: 'Last Updated', id: 'updated' }, + { label: 'Last updated', id: 'updated' }, { label: 'Run on spot', id: 'runOnSpot' }, { label: 'Node selector', @@ -72,7 +79,17 @@ export const getInfoHeaders = (isSpark, selectedJob) => { { label: 'Labels', id: 'labels' }, { label: 'Log level', id: LOG_LEVEL_ID }, { label: 'Output path', id: 'outputPath' }, - { label: 'Total iterations', id: 'iterations' } + { label: 'Total iterations', id: 'iterations' }, + { + label: 'Attempt count', + id: 'retryCountWithInitialAttempt', + tip: 'Number of attempts to run Kubernetes jobs' + }, + { + label: 'Maximum attempts', + id: 'maxRetriesWithInitialAttempt', + tip: 'Maximum number of attempts to run Kubernetes jobs' + } ] if (isSpark) { @@ -87,8 +104,8 @@ export const getInfoHeaders = (isSpark, selectedJob) => { } export const actionButtonHeader = 'Batch run' -export const JOB_STEADY_STATES = ['completed', ERROR_STATE, 'aborted', FAILED_STATE] -export const JOB_RUNNING_STATES = ['running', 'pending'] +export const JOB_STEADY_STATES = [COMPLETED_STATE, ERROR_STATE, ABORTED_STATE, FAILED_STATE] +export const JOB_RUNNING_STATES = [RUNNING_STATE, PENDING_STATE, PENDING_RETRY_STATE] export const getJobsDetailsMenu = (job = {}) => { return [ @@ -133,7 +150,7 @@ export const isJobKindAbortable = (job, abortableFunctionKinds) => .some(kindLabel => job?.labels?.includes(kindLabel)) export const isJobAborting = (currentJob = {}) => { - return currentJob?.state?.value === 'aborting' + return currentJob?.state?.value === ABORTING_STATE } export const isJobKindDask = (jobLabels = []) => { diff --git a/src/components/LLMPrompts/LLMPrompts.jsx b/src/components/LLMPrompts/LLMPrompts.jsx index 29dc82c0f5..3340486212 100644 --- a/src/components/LLMPrompts/LLMPrompts.jsx +++ b/src/components/LLMPrompts/LLMPrompts.jsx @@ -27,7 +27,12 @@ import Artifacts from '../Artifacts/Artifacts' import { LLM_PROMPT_TYPE, LLM_PROMPTS_PAGE } from '../../constants' import { createLLMPromptsRowData } from '../../utils/createArtifactsContent' import { fetchLLMPrompts, removeDataSets } from '../../reducers/artifactsReducer' -import { generateActionsMenu, generatePageData, handleApplyDetailsChanges } from './llmPrompts.util' +import { + generateActionsMenu, + generatePageData, + getFiltersConfig, + handleApplyDetailsChanges +} from './llmPrompts.util' const LLMPrompts = ({ isAllVersions }) => { const artifactsStore = useSelector(store => store.artifactsStore) @@ -47,6 +52,7 @@ const LLMPrompts = ({ isAllVersions }) => { generateActionsMenu={generateActionsMenu} generateDetailsFormInitialValues={generateDetailsFormInitialValues} generatePageData={generatePageData} + getArtifactFiltersConfig={getFiltersConfig} handleApplyDetailsChanges={handleApplyDetailsChanges} isAllVersions={isAllVersions} page={LLM_PROMPTS_PAGE} diff --git a/src/components/LLMPrompts/llmPrompts.util.jsx b/src/components/LLMPrompts/llmPrompts.util.jsx index a00532803d..0b56f35d09 100644 --- a/src/components/LLMPrompts/llmPrompts.util.jsx +++ b/src/components/LLMPrompts/llmPrompts.util.jsx @@ -21,25 +21,29 @@ import React from 'react' import { ARTIFACT_MAX_DOWNLOAD_SIZE, - FULL_VIEW_MODE, - LLM_PROMPT_TYPE, - LLM_PROMPTS_PAGE + ITERATIONS_FILTER, + LABELS_FILTER, + LLM_PROMPTS_PAGE, + MODEL_NAME_FILTER, + MODEL_TAG_FILTER, + NAME_FILTER, + SHOW_ITERATIONS, + TAG_FILTER, + TAG_FILTER_ALL_ITEMS, + TAG_FILTER_LATEST } from '../../constants' -import { getIsTargetPathValid } from '../../utils/createArtifactsContent' import { applyTagChanges, chooseOrFetchArtifact } from '../../utils/artifacts.util' -import { setDownloadItem, setShowDownloadsList } from '../../reducers/downloadReducer' import { copyToClipboard } from '../../utils/copyToClipboard' import { generateUri } from '../../utils/resources' -import { openDeleteConfirmPopUp, openPopUp } from 'igz-controls/utils/common.util' -import DeleteArtifactPopUp from '../../elements/DeleteArtifactPopUp/DeleteArtifactPopUp' -import { handleDeleteArtifact } from '../../utils/handleDeleteArtifact' +import { getIsTargetPathValid } from '../../utils/createArtifactsContent' +import { setDownloadItem, setShowDownloadsList } from '../../reducers/downloadReducer' import { showArtifactsPreview } from '../../reducers/artifactsReducer' +import { FULL_VIEW_MODE } from 'igz-controls/constants' import TagIcon from 'igz-controls/images/tag-icon.svg?react' import YamlIcon from 'igz-controls/images/yaml.svg?react' import ArtifactView from 'igz-controls/images/eye-icon.svg?react' import Copy from 'igz-controls/images/copy-to-clipboard-icon.svg?react' -import Delete from 'igz-controls/images/delete.svg?react' import DownloadIcon from 'igz-controls/images/download.svg?react' import HistoryIcon from 'igz-controls/images/history.svg?react' @@ -49,17 +53,19 @@ export const detailsMenu = [ id: 'overview' }, { - label: 'prompt-template', - id: 'Prompt template' + label: 'Prompt template', + id: 'prompt-template' }, { - label: 'generation-configuration', - id: 'Generation configuration' + label: 'Invocation configuration', + id: 'invocation-configuration' } ] export const infoHeaders = [ { label: 'Key', id: 'db_key' }, + { label: 'Description', id: 'description' }, + { label: 'Model name', id: 'model_artifact' }, { label: 'Hash', id: 'hash', @@ -75,14 +81,14 @@ export const infoHeaders = [ { label: 'Labels', id: 'labels' } ] -export const generatePageData = viewMode => { +export const generatePageData = (viewMode, isDetailsPopUp = false) => { return { page: LLM_PROMPTS_PAGE, details: { type: LLM_PROMPTS_PAGE, menu: detailsMenu, infoHeaders, - hideBackBtn: viewMode === FULL_VIEW_MODE, + hideBackBtn: viewMode === FULL_VIEW_MODE && !isDetailsPopUp, withToggleViewBtn: true } } @@ -114,8 +120,9 @@ export const generateActionsMenu = ( isDetailsPopUp = false ) => { const isTargetPathValid = getIsTargetPathValid(llmPromptMin ?? {}, frontendSpec) - const datasetDataCouldBeDeleted = - llmPromptMin?.target_path?.endsWith('.pq') || llmPromptMin?.target_path?.endsWith('.parquet') + //TODO: uncomment when MEP delete will be implemented + // const llmPromptDataCouldBeDeleted = + // llmPromptMin?.target_path?.endsWith('.pq') || llmPromptMin?.target_path?.endsWith('.parquet') const getFullLLMPrompt = llmPromptMin => { return chooseOrFetchArtifact(dispatch, LLM_PROMPTS_PAGE, null, selectedLLMPrompt, llmPromptMin) @@ -166,66 +173,68 @@ export const generateActionsMenu = ( label: 'View YAML', icon: , onClick: llmPromptMin => getFullLLMPrompt(llmPromptMin).then(toggleConvertedYaml) - }, - { - label: 'Delete', - icon: , - hidden: isDetailsPopUp, - className: 'danger', - onClick: () => - datasetDataCouldBeDeleted - ? openPopUp(DeleteArtifactPopUp, { - artifact: llmPromptMin, - artifactType: LLM_PROMPT_TYPE, - category: LLM_PROMPT_TYPE, - filters: llmPromptsFilters, - refreshArtifacts, - refreshAfterDeleteCallback - }) - : openDeleteConfirmPopUp( - 'Delete LLM Prompt?', - `Do you want to delete the LLM Prompt "${llmPromptMin.db_key}"? Deleted LLM Prompt can not be restored.`, - () => { - handleDeleteArtifact( - dispatch, - projectName, - llmPromptMin.db_key, - llmPromptMin.uid, - refreshArtifacts, - refreshAfterDeleteCallback, - llmPromptsFilters, - LLM_PROMPT_TYPE - ) - } - ), - allowLeaveWarning: true - }, - { - label: 'Delete all versions', - icon: , - hidden: isDetailsPopUp || isAllVersions, - className: 'danger', - onClick: () => - openDeleteConfirmPopUp( - 'Delete LLM Prompt?', - `Do you want to delete all versions of the LLM Prompt "${llmPromptMin.db_key}"? Deleted LLM prompt can not be restored.`, - () => { - handleDeleteArtifact( - dispatch, - projectName, - llmPromptMin.db_key, - llmPromptMin.uid, - refreshArtifacts, - refreshAfterDeleteCallback, - llmPromptsFilters, - LLM_PROMPT_TYPE, - LLM_PROMPT_TYPE, - true - ) - } - ), - allowLeaveWarning: true } + //TODO: uncomment when MEP delete will be implemented, + // correct delete confirmation message ( currently it's shown as Llm-prompt deleted, should be LLM prompt deleted ) + // { + // label: 'Delete', + // icon: , + // hidden: isDetailsPopUp, + // className: 'danger', + // onClick: () => + // llmPromptDataCouldBeDeleted + // ? openPopUp(DeleteArtifactPopUp, { + // artifact: llmPromptMin, + // artifactType: LLM_PROMPT_TYPE, + // category: LLM_PROMPT_TYPE, + // filters: llmPromptsFilters, + // refreshArtifacts, + // refreshAfterDeleteCallback + // }) + // : openDeleteConfirmPopUp( + // 'Delete LLM Prompt?', + // `Do you want to delete the LLM Prompt "${llmPromptMin.db_key}"? Deleted LLM Prompt can not be restored.`, + // () => { + // handleDeleteArtifact( + // dispatch, + // projectName, + // llmPromptMin.db_key, + // llmPromptMin.uid, + // refreshArtifacts, + // refreshAfterDeleteCallback, + // llmPromptsFilters, + // LLM_PROMPT_TYPE + // ) + // } + // ), + // allowLeaveWarning: true + // }, + // { + // label: 'Delete all versions', + // icon: , + // hidden: isDetailsPopUp || isAllVersions, + // className: 'danger', + // onClick: () => + // openDeleteConfirmPopUp( + // 'Delete LLM Prompt?', + // `Do you want to delete all versions of the LLM Prompt "${llmPromptMin.db_key}"? Deleted LLM prompt can not be restored.`, + // () => { + // handleDeleteArtifact( + // dispatch, + // projectName, + // llmPromptMin.db_key, + // llmPromptMin.uid, + // refreshArtifacts, + // refreshAfterDeleteCallback, + // llmPromptsFilters, + // LLM_PROMPT_TYPE, + // LLM_PROMPT_TYPE, + // true + // ) + // } + // ), + // allowLeaveWarning: true + // } ], [ { @@ -237,7 +246,7 @@ export const generateActionsMenu = ( }, { label: 'Preview', - id: 'llm-prompt-preview', + id: 'artifact-preview', disabled: !isTargetPathValid, icon: , onClick: llmPromptMin => { @@ -256,3 +265,28 @@ export const generateActionsMenu = ( ] ] } + +export const getFiltersConfig = isAllVersions => ({ + [NAME_FILTER]: { label: 'Name:', initialValue: '', hidden: isAllVersions }, + [TAG_FILTER]: { + label: 'LLM prompt version tag:', + initialValue: isAllVersions ? TAG_FILTER_ALL_ITEMS : TAG_FILTER_LATEST, + isModal: true + }, + [LABELS_FILTER]: { label: 'Labels:', initialValue: '', isModal: true }, + [ITERATIONS_FILTER]: { + label: 'Show best iteration only', + initialValue: isAllVersions ? '' : SHOW_ITERATIONS, + isModal: true + }, + [MODEL_NAME_FILTER]: { + label: 'Model name:', + initialValue: '', + isModal: true + }, + [MODEL_TAG_FILTER]: { + label: 'Model version tag:', + initialValue: '', + isModal: true + } +}) diff --git a/src/components/ModelsPage/ModelEndpoints/ModelEndpoints.jsx b/src/components/ModelsPage/ModelEndpoints/ModelEndpoints.jsx index 00f0757b07..f1e6bc8d2f 100644 --- a/src/components/ModelsPage/ModelEndpoints/ModelEndpoints.jsx +++ b/src/components/ModelsPage/ModelEndpoints/ModelEndpoints.jsx @@ -20,15 +20,14 @@ such restriction. import React, { useState, useRef, useCallback, useEffect, useMemo } from 'react' import { useDispatch, useSelector } from 'react-redux' import { useLocation, useNavigate, useParams, useSearchParams } from 'react-router-dom' -import { isEmpty } from 'lodash' import ActionBar from '../../ActionBar/ActionBar' import ArtifactsTableRow from '../../../elements/ArtifactsTableRow/ArtifactsTableRow' -import Loader from '../../../common/Loader/Loader' import ModelEndpointsFilters from './ModelEndpointsFilters' import ModelsPageTabs from '../ModelsPageTabs/ModelsPageTabs' import NoData from '../../../common/NoData/NoData' import Table from '../../Table/Table' +import { Loader } from 'igz-controls/components' import { GROUP_BY_NONE, @@ -36,7 +35,12 @@ import { MODELS_PAGE, REQUEST_CANCELED } from '../../../constants' -import { chooseOrFetchModelEndpoint, filtersConfig, generatePageData } from './modelEndpoints.util' +import { + chooseOrFetchModelEndpoint, + filtersConfig, + generateActionsMenu, + generatePageData +} from './modelEndpoints.util' import { createModelEndpointsRowData } from '../../../utils/createArtifactsContent' import { fetchModelEndpoints, removeModelEndpoints } from '../../../reducers/artifactsReducer' import { getNoDataMessage } from '../../../utils/getNoDataMessage' @@ -44,21 +48,18 @@ import { getScssVariableValue } from 'igz-controls/utils/common.util' import { isDetailsTabExists } from '../../../utils/link-helper.util' import { isRowRendered, useVirtualization } from '../../../hooks/useVirtualization.hook' import { setFilters } from '../../../reducers/filtersReducer' +import { clearMetricsOptions } from '../../../reducers/detailsReducer' import { useFiltersFromSearchParams } from '../../../hooks/useFiltersFromSearchParams.hook' import { useInitialTableFetch } from '../../../hooks/useInitialTableFetch.hook' import { useModelsPage } from '../ModelsPage.context' import { useSortTable } from '../../../hooks/useSortTable.hook' -import MonitorIcon from 'igz-controls/images/monitor-icon.svg?react' -import Yaml from 'igz-controls/images/yaml.svg?react' - import './modelEndpoints.scss' const ModelEndpoints = () => { const [requestErrorMessage, setRequestErrorMessage] = useState('') const [modelEndpoints, setModelEndpoints] = useState([]) const [selectedModelEndpoint, setSelectedModelEndpoint] = useState({}) - const frontendSpec = useSelector(store => store.appStore.frontendSpec) const artifactsStore = useSelector(store => store.artifactsStore) const filtersStore = useSelector(store => store.filtersStore) const params = useParams() @@ -70,7 +71,7 @@ const ModelEndpoints = () => { const [, setSearchParams] = useSearchParams() const filters = useFiltersFromSearchParams(filtersConfig) - const { handleMonitoring, toggleConvertedYaml } = useModelsPage() + const { handleMonitoring, toggleConvertedYaml, frontendSpec } = useModelsPage() const modelEndpointsRowHeight = useMemo( () => getScssVariableValue('--modelEndpointsRowHeight'), @@ -95,34 +96,20 @@ const ModelEndpoints = () => { ) const actionsMenu = useMemo( - () => [ - [ - { - label: 'Monitoring', - icon: , - tooltip: !frontendSpec.model_monitoring_dashboard_url - ? 'Grafana service unavailable' - : '', - disabled: !frontendSpec.model_monitoring_dashboard_url, - onClick: handleMonitoring, - hidden: !isEmpty(selectedModelEndpoint) - }, - { - label: 'View YAML', - icon: , - onClick: modelEndpointMin => - chooseOrFetchModelEndpoint(dispatch, selectedModelEndpoint, modelEndpointMin).then( - toggleConvertedYaml - ) - } - ] - ], + () => + generateActionsMenu( + frontendSpec.model_monitoring_dashboard_url, + handleMonitoring, + toggleConvertedYaml, + selectedModelEndpoint, + dispatch + ), [ dispatch, - frontendSpec.model_monitoring_dashboard_url, handleMonitoring, selectedModelEndpoint, - toggleConvertedYaml + toggleConvertedYaml, + frontendSpec.model_monitoring_dashboard_url ] ) @@ -191,6 +178,12 @@ const ModelEndpoints = () => { } }, [dispatch, params.projectName]) + useEffect(() => { + return () => { + dispatch(clearMetricsOptions()) + } + }, [dispatch]) + useEffect(() => { if (params.name && modelEndpoints.length > 0) { const searchItem = modelEndpoints.find(item => item.metadata?.uid === params.tag) diff --git a/src/components/ModelsPage/ModelEndpoints/ModelEndpointsFilters.jsx b/src/components/ModelsPage/ModelEndpoints/ModelEndpointsFilters.jsx index 7505a6a7b7..e4134e48ca 100644 --- a/src/components/ModelsPage/ModelEndpoints/ModelEndpointsFilters.jsx +++ b/src/components/ModelsPage/ModelEndpoints/ModelEndpointsFilters.jsx @@ -17,9 +17,10 @@ such restriction. import React from 'react' import { useForm } from 'react-final-form' -import { FormInput, FormOnChange } from 'igz-controls/components' +import { FormInput, FormOnChange, FormSelect } from 'igz-controls/components' -import { LABELS_FILTER } from '../../../constants' +import { modelEndpointsModesList } from '../../FilterMenu/filterMenu.settings' +import { LABELS_FILTER, ME_MODE_FILTER } from '../../../constants' const ModelEndpointsFilters = () => { const form = useForm() @@ -30,6 +31,9 @@ const ModelEndpointsFilters = () => { return (
+
+ +
{ + return [ + { label: 'UID', id: 'uid' }, + { label: 'Model class', id: 'model_class' }, + { + label: model_path.includes('llm-prompts') ? 'LLM prompt artifact' : 'Model artifact', + id: 'model_artifact' + }, + { label: 'Function URI', id: 'function_uri' }, + { label: 'Function tag', id: 'function_tag' }, + { label: 'Feature set', id: 'monitoring_feature_set_uri' }, + { label: 'Sampling percentage', id: 'sampling_percentage' }, + { label: 'Last prediction', id: 'last_prediction' }, + { label: 'Error count', id: 'error_count' } + ] +} const detailsMenu = [ { @@ -60,8 +75,7 @@ const detailsMenu = [ { label: 'alerts', id: 'alerts', - icon: , - query: '?entity-type=model-endpoint-result' //TODO: temp solution for query params + icon: } ] @@ -74,7 +88,7 @@ export const generatePageData = ( hidePageActionMenu: true, details: { menu: detailsMenu, - infoHeaders, + infoHeaders: generateInfoHeaders(selectedItem?.spec?.model_path || ''), type: MODEL_ENDPOINTS_TAB, actionButton: { label: 'Resource monitoring', @@ -87,6 +101,35 @@ export const generatePageData = ( } }) +export const generateActionsMenu = ( + modelMonitoringDashboardUrl, + handleMonitoring, + toggleConvertedYaml, + selectedModelEndpoint, + dispatch +) => { + return [ + [ + { + label: 'Monitoring', + icon: , + tooltip: !modelMonitoringDashboardUrl ? 'Grafana service unavailable' : '', + disabled: !modelMonitoringDashboardUrl, + onClick: handleMonitoring, + hidden: !isEmpty(selectedModelEndpoint) + }, + { + label: 'View YAML', + icon: , + onClick: modelEndpointMin => + chooseOrFetchModelEndpoint(dispatch, selectedModelEndpoint, modelEndpointMin).then( + toggleConvertedYaml + ) + } + ] + ] +} + export const monitorModelEndpoint = (model_monitoring_dashboard_url, item, projectName) => { let redirectUrl = model_monitoring_dashboard_url .replace('{project}', projectName) diff --git a/src/components/ModelsPage/Models/models.util.jsx b/src/components/ModelsPage/Models/models.util.jsx index 4443779221..d040bb3190 100644 --- a/src/components/ModelsPage/Models/models.util.jsx +++ b/src/components/ModelsPage/Models/models.util.jsx @@ -27,21 +27,32 @@ import { MODELS_PAGE, MODELS_TAB, TAG_LATEST, - FULL_VIEW_MODE, MODEL_TYPE, ARTIFACT_MAX_DOWNLOAD_SIZE } from '../../../constants' +import { + getErrorMsg, + openPopUp, + openDeleteConfirmPopUp, + copyToClipboard +} from 'igz-controls/utils/common.util' import { showArtifactsPreview, updateArtifact } from '../../../reducers/artifactsReducer' -import { FORBIDDEN_ERROR_STATUS_CODE } from 'igz-controls/constants' -import { applyTagChanges, chooseOrFetchArtifact } from '../../../utils/artifacts.util' +import { FORBIDDEN_ERROR_STATUS_CODE, FULL_VIEW_MODE } from 'igz-controls/constants' +import { + applyTagChanges, + chooseOrFetchArtifact, + processActionAfterTagUniquesValidation +} from '../../../utils/artifacts.util' import { convertChipsData } from '../../../utils/convertChipsData' -import { copyToClipboard } from '../../../utils/copyToClipboard' import { getIsTargetPathValid } from '../../../utils/createArtifactsContent' import { generateUri } from '../../../utils/resources' -import { getErrorMsg, openPopUp, openDeleteConfirmPopUp } from 'igz-controls/utils/common.util' import { handleDeleteArtifact } from '../../../utils/handleDeleteArtifact' import { setDownloadItem, setShowDownloadsList } from '../../../reducers/downloadReducer' -import { showErrorNotification } from '../../../utils/notifications.util' +import { showErrorNotification } from 'igz-controls/utils/notification.util' +import { + decreaseDetailsLoadingCounter, + increaseDetailsLoadingCounter +} from '../../../reducers/detailsReducer' import TagIcon from 'igz-controls/images/tag-icon.svg?react' import YamlIcon from 'igz-controls/images/yaml.svg?react' @@ -105,13 +116,13 @@ export const generateModelsDetailsMenu = selectedModel => [ } ] -export const generatePageData = (viewMode, selectedItem) => ({ +export const generatePageData = (viewMode, isDetailsPopUp = false, selectedItem) => ({ page: MODELS_PAGE, details: { menu: generateModelsDetailsMenu(selectedItem), infoHeaders, type: MODELS_TAB, - hideBackBtn: viewMode === FULL_VIEW_MODE, + hideBackBtn: viewMode === FULL_VIEW_MODE && !isDetailsPopUp, withToggleViewBtn: true } }) @@ -129,56 +140,69 @@ export const handleApplyDetailsChanges = ( setNotification, dispatch ) => { - const isNewFormat = - selectedItem.ui.originalContent.metadata && selectedItem.ui.originalContent.spec - const artifactItem = cloneDeep( - isNewFormat ? selectedItem.ui.originalContent : omit(selectedItem, ['ui']) - ) + const updateModel = () => { + const isNewFormat = + selectedItem.ui.originalContent.metadata && selectedItem.ui.originalContent.spec + const artifactItem = cloneDeep( + isNewFormat ? selectedItem.ui.originalContent : omit(selectedItem, ['ui']) + ) + + if (!isEmpty(omit(changes.data, ['tag']))) { + Object.keys(changes.data).forEach(key => { + if (key === 'labels') { + isNewFormat + ? (artifactItem.metadata[key] = changes.data[key].currentFieldValue) + : (artifactItem[key] = changes.data[key].currentFieldValue) + } + }) + + const labels = convertChipsData(artifactItem.metadata?.labels || artifactItem.labels) - if (!isEmpty(omit(changes.data, ['tag']))) { - Object.keys(changes.data).forEach(key => { - if (key === 'labels') { - isNewFormat - ? (artifactItem.metadata[key] = changes.data[key].currentFieldValue) - : (artifactItem[key] = changes.data[key].currentFieldValue) + if (isNewFormat) { + artifactItem.metadata.labels = labels + } else { + artifactItem.labels = labels } - }) - const labels = convertChipsData(artifactItem.metadata?.labels || artifactItem.labels) + return dispatch(updateArtifact({ project: projectName, data: artifactItem })) + .unwrap() + .then(response => { + dispatch( + setNotification({ + status: response.status, + id: Math.random(), + message: 'Model was updated successfully' + }) + ) + }) + .catch(error => { + const customErrorMsg = + error.response?.status === FORBIDDEN_ERROR_STATUS_CODE + ? 'Permission denied' + : getErrorMsg(error, 'Failed to update the model') - if (isNewFormat) { - artifactItem.metadata.labels = labels + showErrorNotification(dispatch, error, '', customErrorMsg, () => + handleApplyDetailsChanges(changes, projectName, selectedItem, setNotification, dispatch) + ) + }) + .finally(() => { + return applyTagChanges(changes, selectedItem, projectName, dispatch, setNotification) + }) } else { - artifactItem.labels = labels + return applyTagChanges(changes, selectedItem, projectName, dispatch, setNotification) } - - return dispatch(updateArtifact({ project: projectName, data: artifactItem })) - .unwrap() - .then(response => { - dispatch( - setNotification({ - status: response.status, - id: Math.random(), - message: 'Model was updated successfully' - }) - ) - }) - .catch(error => { - const customErrorMsg = - error.response?.status === FORBIDDEN_ERROR_STATUS_CODE - ? 'Permission denied' - : getErrorMsg(error, 'Failed to update the model') - - showErrorNotification(dispatch, error, '', customErrorMsg, () => - handleApplyDetailsChanges(changes, projectName, selectedItem, setNotification, dispatch) - ) - }) - .finally(() => { - return applyTagChanges(changes, selectedItem, projectName, dispatch, setNotification) - }) - } else { - return applyTagChanges(changes, selectedItem, projectName, dispatch, setNotification) } + + return processActionAfterTagUniquesValidation({ + tag: changes?.data?.tag?.currentFieldValue, + artifact: selectedItem, + projectName, + dispatch, + actionCallback: updateModel, + throwError: true, + showLoader: () => dispatch(increaseDetailsLoadingCounter()), + hideLoader: () => dispatch(decreaseDetailsLoadingCounter()) + }).finally(() => {}) } export const generateActionsMenu = ( @@ -217,6 +241,7 @@ export const generateActionsMenu = ( disabled: !isTargetPathValid || modelMin.size > + modelMin.size > (frontendSpec?.artifact_limits?.max_download_size ?? ARTIFACT_MAX_DOWNLOAD_SIZE), icon: , onClick: modelMin => { @@ -253,6 +278,10 @@ export const generateActionsMenu = ( icon: , className: 'danger', hidden: isDetailsPopUp, + disabled: modelMin?.has_children, + tooltip: modelMin?.has_children + ? 'There are llm-prompt artifacts pointing to this model. The model cannot be deleted' + : null, onClick: () => openDeleteConfirmPopUp( 'Delete model?', @@ -276,6 +305,10 @@ export const generateActionsMenu = ( label: 'Delete all versions', icon: , hidden: isAllVersions || isDetailsPopUp, + disabled: modelMin?.has_children, + tooltip: modelMin?.has_children + ? 'There are llm-prompt artifacts pointing to this model. The model cannot be deleted' + : null, className: 'danger', onClick: () => openDeleteConfirmPopUp( diff --git a/src/components/ModelsPage/ModelsPage.context.jsx b/src/components/ModelsPage/ModelsPage.context.jsx index 4d5bae7d58..404644ecaf 100644 --- a/src/components/ModelsPage/ModelsPage.context.jsx +++ b/src/components/ModelsPage/ModelsPage.context.jsx @@ -50,7 +50,8 @@ export const ModelsPageProvider = ({ children }) => { {children} diff --git a/src/components/ModelsPage/ModelsPage.jsx b/src/components/ModelsPage/ModelsPage.jsx index 3c97271d62..d1d2233fed 100644 --- a/src/components/ModelsPage/ModelsPage.jsx +++ b/src/components/ModelsPage/ModelsPage.jsx @@ -22,8 +22,8 @@ import { Outlet } from 'react-router-dom' import { useSelector } from 'react-redux' import Breadcrumbs from '../../common/Breadcrumbs/Breadcrumbs' -import Loader from '../../common/Loader/Loader' import PreviewModal from '../../elements/PreviewModal/PreviewModal' +import { Loader } from 'igz-controls/components' import { ModelsPageProvider } from './ModelsPage.context' diff --git a/src/components/ModelsPage/RealTimePipelines/RealTimePipelines.jsx b/src/components/ModelsPage/RealTimePipelines/RealTimePipelines.jsx index e8ba7af382..d1a164222b 100644 --- a/src/components/ModelsPage/RealTimePipelines/RealTimePipelines.jsx +++ b/src/components/ModelsPage/RealTimePipelines/RealTimePipelines.jsx @@ -24,12 +24,12 @@ import classnames from 'classnames' import { isNil } from 'lodash' import ActionBar from '../../ActionBar/ActionBar' -import Loader from '../../../common/Loader/Loader' import ModelsPageTabs from '../ModelsPageTabs/ModelsPageTabs' import NoData from '../../../common/NoData/NoData' import Pipeline from '../../Pipeline/Pipeline' import RealTimePipelinesTableRow from '../../../elements/RealTimePipelinesTableRow/RealTimePipelinesTableRow' import Table from '../../Table/Table' +import { Loader } from 'igz-controls/components' import { GROUP_BY_NAME, diff --git a/src/components/ModelsPage/RealTimePipelines/realTimePipelines.scss b/src/components/ModelsPage/RealTimePipelines/realTimePipelines.scss index 29665dc152..0a1c0739cb 100644 --- a/src/components/ModelsPage/RealTimePipelines/realTimePipelines.scss +++ b/src/components/ModelsPage/RealTimePipelines/realTimePipelines.scss @@ -1,5 +1,5 @@ @use 'igz-controls/scss/variables'; -@use '/src/scss/mixins'; +@use '@/scss/mixins'; $pipelinesRowHeight: variables.$rowHeight; $pipelinesHeaderRowHeight: variables.$headerRowHeight; diff --git a/src/components/ModelsPage/RealTimePipelines/realTimePipelines.util.js b/src/components/ModelsPage/RealTimePipelines/realTimePipelines.util.js index c0211d6984..919ea26f9e 100644 --- a/src/components/ModelsPage/RealTimePipelines/realTimePipelines.util.js +++ b/src/components/ModelsPage/RealTimePipelines/realTimePipelines.util.js @@ -19,7 +19,7 @@ such restriction. */ import { MODELS_PAGE, NAME_FILTER } from '../../../constants' import { parseFunction } from '../../../utils/parseFunction' -import { showErrorNotification } from '../../../utils/notifications.util' +import { showErrorNotification } from 'igz-controls/utils/notification.util' import { fetchFunction } from '../../../reducers/functionReducer' export const filtersConfig = { diff --git a/src/components/ModelsPage/modelsPage.scss b/src/components/ModelsPage/modelsPage.scss index 42aec12289..c61d799516 100644 --- a/src/components/ModelsPage/modelsPage.scss +++ b/src/components/ModelsPage/modelsPage.scss @@ -24,9 +24,9 @@ pre { width: 800px; - overflow-x: scroll; - padding: 20px 0; margin: 0; + padding: 20px 0; + overflow-x: scroll; } } } diff --git a/src/components/MonitoringApplicationsPage/MonitoringApplications/MEPsWithDetections.jsx b/src/components/MonitoringApplicationsPage/MonitoringApplications/MEPsWithDetections.jsx new file mode 100644 index 0000000000..72bab9a527 --- /dev/null +++ b/src/components/MonitoringApplicationsPage/MonitoringApplications/MEPsWithDetections.jsx @@ -0,0 +1,161 @@ +/* +Copyright 2019 Iguazio Systems Ltd. + +Licensed under the Apache License, Version 2.0 (the "License") with +an addition restriction as set forth herein. You may not use this +file except in compliance with the License. You may obtain a copy of +the License at http://www.apache.org/licenses/LICENSE-2.0. + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +In addition, you may not use the software for any purposes that are +illegal under applicable law, and the grant of the foregoing license +under the Apache 2.0 license is conditioned upon your compliance with +such restriction. +*/ +import React, { memo, useMemo, useRef, useState } from 'react' +import classNames from 'classnames' + +import MlChart from '../../../common/MlChart/MlChart' +import NoData from '../../../common/NoData/NoData' +import { Loader, Tip } from 'igz-controls/components' + +import { MONITORING_APPLICATIONS_NO_DATA_MESSAGE } from '../MonitoringApplicationsPage.util' +import { getMEPsWithDetectionChartConfig } from '../../../utils/getChartConfig' +import { groupDataToBins } from './monitoringApplications.util' +import { useSelector } from 'react-redux' + +const MEPsWithDetections = () => { + const [isLoading, setIsLoading] = useState(true) + const chartRef = useRef() + const chartYAxisRef = useRef() + const chartWrapperRef = useRef() + const barConfig = useMemo(() => getMEPsWithDetectionChartConfig(), []) + const { + endpointsWithDetections: { data: endpointsWithDetectionsData, loading, error } + } = useSelector(store => store.monitoringApplicationsStore) + + const renderPlugin = useMemo(() => { + let savedCopyWidth = 0 + let savedCopyHeight = 0 + + return { + id: 'renderTracker', + afterDatasetsDraw(chart) { + const copyWidth = chart.scales.x.left + const copyHeight = chart.scales.y.height + 20 + + if ( + (copyWidth !== savedCopyWidth || copyHeight !== savedCopyHeight) && + chartYAxisRef.current && + chartWrapperRef.current + ) { + savedCopyWidth = copyWidth + savedCopyHeight = copyHeight + const sourceCanvas = chart.ctx.canvas + const copyWidthWithRatio = copyWidth * chart.currentDevicePixelRatio + const copyHeightWithRatio = copyHeight * chart.currentDevicePixelRatio + const yAxisCtx = chartYAxisRef.current.getContext('2d') + const spaceForBar = 32 + yAxisCtx.canvas.width = copyWidthWithRatio + yAxisCtx.canvas.height = copyHeightWithRatio + yAxisCtx.canvas.style.width = `${chart.currentDevicePixelRatio === 1 ? yAxisCtx.canvas.width : copyWidth}px` + yAxisCtx.canvas.style.height = `${chart.currentDevicePixelRatio === 1 ? yAxisCtx.canvas.height : copyHeight}px` + + yAxisCtx.drawImage( + sourceCanvas, + 0, + 0, + copyWidthWithRatio, + copyHeightWithRatio, + 0, + 0, + copyWidthWithRatio, + copyHeightWithRatio + ) + + chartWrapperRef.current.style.width = `${copyWidth + (chart.scales.x?.ticks?.length || 1) * spaceForBar}px` + } + } + } + }, []) + + const barChartConfig = useMemo(() => { + const { labels, values, dates } = groupDataToBins( + endpointsWithDetectionsData.values, + endpointsWithDetectionsData.start, + endpointsWithDetectionsData.end + ) + + return { + ...barConfig, + options: { + ...barConfig.options, + plugins: { + ...barConfig.options.plugins, + renderTracker: {} + }, + animation: { + ...barConfig.options.animation, + onComplete: () => { + setIsLoading(false) + } + } + }, + data: { + labels, + datasets: [ + { + data: values, + dates, + chartType: 'bar', + tension: 0.2, + borderWidth: 2, + backgroundColor: '#13bbb1', + borderColor: '#13bbb1' + } + ] + }, + plugins: [renderPlugin] + } + }, [barConfig, endpointsWithDetectionsData, renderPlugin]) + + return ( +
+
+ Model endpoints with suspected/detected issue + +
+ {endpointsWithDetectionsData.values?.length === 0 && !(isLoading || loading) ? ( + + ) : ( +
+
+ {(isLoading || loading) && } +
+ +
+ +
+
Time range
+
+
+
+ )} +
+ ) +} + +export default memo(MEPsWithDetections) diff --git a/src/components/MonitoringApplicationsPage/MonitoringApplications/MonitoringApplication/MonitoringApplication.jsx b/src/components/MonitoringApplicationsPage/MonitoringApplications/MonitoringApplication/MonitoringApplication.jsx index 2dfa54aa50..e93ce64f8a 100644 --- a/src/components/MonitoringApplicationsPage/MonitoringApplications/MonitoringApplication/MonitoringApplication.jsx +++ b/src/components/MonitoringApplicationsPage/MonitoringApplications/MonitoringApplication/MonitoringApplication.jsx @@ -22,12 +22,8 @@ import { Link, useParams } from 'react-router-dom' import { useDispatch, useSelector } from 'react-redux' import NoData from '../../../../common/NoData/NoData' -import { Tip } from 'igz-controls/components' import SectionTable from '../../../../elements/SectionTable/SectionTable' - -import { removeMonitoringApplication } from '../../../../reducers/monitoringApplicationsReducer' -import { removeArtifacts } from '../../../../reducers/artifactsReducer' -import { FILES_PAGE, NAME_FILTER } from '../../../../constants' +import { Tip } from 'igz-controls/components' import { generateArtifactsTableContent, @@ -35,122 +31,22 @@ import { generateResultsTableContent, generateShardsStatusTableContent } from './MonitoringApplication.util' +import { FILES_PAGE, LABELS_FILTER } from '../../../../constants' import { MONITORING_APPLICATIONS_NO_DATA_MESSAGE } from '../../MonitoringApplicationsPage.util' +import { removeArtifacts } from '../../../../reducers/artifactsReducer' +import { removeMonitoringApplication } from '../../../../reducers/monitoringApplicationsReducer' import './monitoringApplication.scss' const MonitoringApplication = () => { const dispatch = useDispatch() - // const { artifacts } = useSelector(store => store.artifactsStore) - const artifactsMock = useMemo( - () => [ - { - kind: '', - project: 'default', - uid: '5a44b12b-9ef3-4239-87e8-e0cbdae-2', - key: 'content', - iter: 0, - tree: '1f8b29a5-cdab-4b84-aad7-7f9bc20daf0b', - updated: '2021-08-29T20:01:03.457008+00:00', - tag: 'latest', - labels: { - 'my-key': 'my-value', - 'mlrun/app-name': 'monitorAppV1', - owner: 'admin', - v3io_user: 'admin' - }, - created: '2021-08-29T20:01:03.457008+00:00', - target_path: 'v3io://artifacts/image_mock_data.png', - size: 20480, - db_key: 'download_content', - producer: { - name: 'download', - kind: 'run', - uri: 'default/59f8e3d6f3db4dd8ab890c4bf84a0a23', - owner: 'admin', - workflow: '1f8b29a5-cdab-4b84-aad7-7f9bc20daf0b' - }, - sources: [ - { - name: 'archive_url', - path: 'https://s3.wasabisys.com/iguazio/data/image-classification/catsndogs.zip' - } - ], - status: {} - }, - { - kind: '', - project: 'default', - uid: '5a44b12b-9ef3-4239-87e8-e0cbdae-2', - key: 'content', - iter: 0, - tree: '1f8b29a5-cdab-4b84-aad7-7f9bc20daf0b', - updated: '2021-08-29T20:01:03.457008+00:00', - tag: 'latest', - labels: { - 'my-key': 'my-value', - 'mlrun/app-name': 'monitorAppV1', - owner: 'admin', - v3io_user: 'admin' - }, - created: '2021-08-29T20:01:03.457008+00:00', - target_path: 'v3io://artifacts/image_mock_data.png', - size: 20480, - db_key: 'download_content', - producer: { - name: 'download', - kind: 'run', - uri: 'default/59f8e3d6f3db4dd8ab890c4bf84a0a23', - owner: 'admin', - workflow: '1f8b29a5-cdab-4b84-aad7-7f9bc20daf0b' - }, - sources: [ - { - name: 'archive_url', - path: 'https://s3.wasabisys.com/iguazio/data/image-classification/catsndogs.zip' - } - ], - status: {} - }, - { - kind: 'dataset', - hash: '1bc83ed07eecbc358d0de91598dfc1d4', - description: '', - framework: '', - project: 'default', - uid: '5a44b12b-9ef3-4239-87e8-e0cbdae-24', - key: 'cleaned_data', - iter: 0, - tree: '27ec4218-34c8-4315-a053-236e326ed645', - labels: { - 'my-key': 'my-value', - v3io_user: 'admin', - owner: 'admin', - type: 'dataset', - 'mlrun/app-name': 'monitorAppV1' - }, - updated: '2022-07-18T14:20:04.121Z', - tag: 'latest', - created: '2022-07-18T14:20:04.121Z', - target_path: 'path', - size: null, - db_key: 'cleaned_data', - producer: { - kind: 'api', - uri: 'localhost:3000' - }, - sources: [], - status: {} - } - ], - [] - ) - const { monitoringApplication } = useSelector(store => store.monitoringApplicationsStore) + const { artifacts } = useSelector(store => store.artifactsStore) + const { monitoringApplication, loading } = useSelector(store => store.monitoringApplicationsStore) const params = useParams() const artifactsTable = useMemo(() => { - return generateArtifactsTableContent(artifactsMock) - }, [artifactsMock]) + return generateArtifactsTableContent(artifacts) + }, [artifacts]) const resultsTable = useMemo(() => { return generateResultsTableContent(monitoringApplication?.stats?.metrics) }, [monitoringApplication?.stats?.metrics]) @@ -158,7 +54,7 @@ const MonitoringApplication = () => { return generateMetricsTableContent(monitoringApplication?.stats?.metrics) }, [monitoringApplication?.stats?.metrics]) const shardsTable = useMemo(() => { - return generateShardsStatusTableContent(monitoringApplication?.stats?.shards) + return generateShardsStatusTableContent(monitoringApplication?.stats?.stream_stats) }, [monitoringApplication]) useEffect(() => { @@ -166,7 +62,7 @@ const MonitoringApplication = () => { dispatch(removeArtifacts()) dispatch(removeMonitoringApplication()) } - }, [dispatch]) + }, [dispatch, params.projectName]) return (
@@ -175,14 +71,14 @@ const MonitoringApplication = () => {
Artifacts
- {artifactsMock.length === 0 ? ( + {artifacts.length === 0 && !loading ? ( ) : ( <> - + See all @@ -194,22 +90,23 @@ const MonitoringApplication = () => {
Results +
- {resultsTable.body.length === 0 ? ( + {resultsTable.body.length === 0 && !loading ? ( ) : ( - + )}
Metrics - +
- {metricsTable.body.length === 0 ? ( + {metricsTable.body.length === 0 && !loading ? ( ) : ( - + )}
@@ -219,10 +116,10 @@ const MonitoringApplication = () => { Shards/partitions status
- {shardsTable.body.length === 0 ? ( + {shardsTable.body.length === 0 && !loading ? ( ) : ( - + )}
diff --git a/src/components/MonitoringApplicationsPage/MonitoringApplications/MonitoringApplication/MonitoringApplication.util.jsx b/src/components/MonitoringApplicationsPage/MonitoringApplications/MonitoringApplication/MonitoringApplication.util.jsx index 06aed80dd0..648d3eec29 100644 --- a/src/components/MonitoringApplicationsPage/MonitoringApplications/MonitoringApplication/MonitoringApplication.util.jsx +++ b/src/components/MonitoringApplicationsPage/MonitoringApplications/MonitoringApplication/MonitoringApplication.util.jsx @@ -18,11 +18,12 @@ under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ import prettyBytes from 'pretty-bytes' -import { capitalize, isNumber } from 'lodash' +import { isNumber } from 'lodash' -import { parseChipsData } from '../../../../utils/convertChipsData' -import { formatDatetime } from '../../../../utils' import { METRIC_TYPE, RESULT_TYPE } from '../../../../constants' +import { formatDatetime } from 'igz-controls/utils/datetime.util' +import { getDriftStatusData } from '../../../../utils/createArtifactsContent' +import { parseChipsData } from '../../../../utils/convertChipsData' export const generateArtifactsTableContent = (artifacts = []) => { const tableHeaders = [ @@ -30,8 +31,8 @@ export const generateArtifactsTableContent = (artifacts = []) => { value: 'Name', className: 'table-cell_big' }, - { value: 'Type', className: 'table-cell_medium' }, - { value: 'Labels', className: 'table-cell_medium' }, + { value: 'Type', className: 'table-cell_small' }, + { value: 'Labels', className: 'table-cell_big' }, { value: 'Producer', className: 'table-cell_small' }, { value: 'Owner', className: 'table-cell_small' }, { value: 'Updated', className: 'table-cell_medium' }, @@ -41,16 +42,17 @@ export const generateArtifactsTableContent = (artifacts = []) => { const tableBody = artifacts.map(artifact => { return { name: { - value: capitalize(artifact.db_key), - className: 'table-cell_big' + value: artifact.db_key, + tag: artifact.tag, + className: 'table-cell_big table-cell_with-tag' }, artifactType: { value: artifact.kind || 'artifact', - className: 'table-cell_medium' + className: 'table-cell_small' }, labels: { value: parseChipsData(artifact.labels), - className: 'table-cell_medium' + className: 'table-cell_big' }, producer: { value: artifact.producer.name, @@ -78,23 +80,16 @@ export const generateArtifactsTableContent = (artifacts = []) => { } export const generateResultsTableContent = (metrics = []) => { - const tableHeaders = [ - { - value: 'Name', - className: 'table-cell_medium' - }, - { value: 'Kind', className: 'table-cell_medium' }, - { value: 'Value (latest result)', className: 'table-cell_medium' }, - { value: 'Time (latest result)', className: 'table-cell_medium' }, - { value: 'Status', className: 'table-cell_small' } - ] - + let timeColumnIsHidden = false const tableBody = metrics .filter(metric => metric.type === RESULT_TYPE) .map(result => { + const driftStatusData = getDriftStatusData(result.status) + timeColumnIsHidden = !result.time + return { name: { - value: capitalize(result.name), + value: result.result_name, className: 'table-cell_medium' }, kind: { @@ -106,15 +101,27 @@ export const generateResultsTableContent = (metrics = []) => { className: 'table-cell_medium' }, time: { - value: result.time, + hidden: timeColumnIsHidden, + value: formatDatetime(result.time, 'N/A'), className: 'table-cell_medium' }, status: { - value: result.status, - className: 'table-cell_small' + value: driftStatusData.value, + className: 'table-cell_small', + tooltip: driftStatusData.tooltip } } }) + const tableHeaders = [ + { + value: 'Name', + className: 'table-cell_medium' + }, + { value: 'Kind', className: 'table-cell_medium' }, + { value: 'Value (latest)', className: 'table-cell_medium' }, + { value: 'Time (latest result)', className: 'table-cell_medium', hidden: timeColumnIsHidden }, + { value: 'Status', className: 'table-cell_small' } + ] return { header: tableHeaders, @@ -123,21 +130,15 @@ export const generateResultsTableContent = (metrics = []) => { } export const generateMetricsTableContent = (metrics = []) => { - const tableHeaders = [ - { - value: 'Name', - className: 'table-cell_medium' - }, - { value: 'Value (latest result)', className: 'table-cell_medium' }, - { value: 'Time (latest result)', className: 'table-cell_medium' } - ] - + let timeColumnIsHidden = false const tableBody = metrics .filter(metric => metric.type === METRIC_TYPE) .map(metric => { + timeColumnIsHidden = !metric.time + return { name: { - value: capitalize(metric.name), + value: metric.metric_name, className: 'table-cell_medium' }, value: { @@ -145,11 +146,20 @@ export const generateMetricsTableContent = (metrics = []) => { className: 'table-cell_medium' }, time: { + hidden: timeColumnIsHidden, value: formatDatetime(metric.time, 'N/A'), className: 'table-cell_medium' } } }) + const tableHeaders = [ + { + value: 'Name', + className: 'table-cell_medium' + }, + { value: 'Value (latest)', className: 'table-cell_medium' }, + { value: 'Time (latest metric)', className: 'table-cell_medium', hidden: timeColumnIsHidden} + ] return { header: tableHeaders, diff --git a/src/components/MonitoringApplicationsPage/MonitoringApplications/MonitoringApplication/monitoringApplication.scss b/src/components/MonitoringApplicationsPage/MonitoringApplications/MonitoringApplication/monitoringApplication.scss index c5776e65fa..0b78609868 100644 --- a/src/components/MonitoringApplicationsPage/MonitoringApplications/MonitoringApplication/monitoringApplication.scss +++ b/src/components/MonitoringApplicationsPage/MonitoringApplications/MonitoringApplication/monitoringApplication.scss @@ -4,6 +4,6 @@ } .monitoring-app__see-all-link { - text-align: right; margin-top: 8px; + text-align: right; } diff --git a/src/components/MonitoringApplicationsPage/MonitoringApplications/MonitoringApplicationCounters/MonitoringApplicationCard/MonitoringApplicationCard.jsx b/src/components/MonitoringApplicationsPage/MonitoringApplications/MonitoringApplicationCounters/MonitoringApplicationCard/MonitoringApplicationCard.jsx index 3245eba66f..6c74682fc8 100644 --- a/src/components/MonitoringApplicationsPage/MonitoringApplications/MonitoringApplicationCounters/MonitoringApplicationCard/MonitoringApplicationCard.jsx +++ b/src/components/MonitoringApplicationsPage/MonitoringApplications/MonitoringApplicationCounters/MonitoringApplicationCard/MonitoringApplicationCard.jsx @@ -19,10 +19,11 @@ such restriction. */ import React from 'react' import PropTypes from 'prop-types' +import { isNil } from 'lodash' -import Loader from '../../../../../common/Loader/Loader' import StatsCard from '../../../../../common/StatsCard/StatsCard' -import { Tooltip, TextTooltipTemplate } from 'igz-controls/components' +import { Tooltip, TextTooltipTemplate, Loader } from 'igz-controls/components' +import { Link } from 'react-router-dom' const MonitoringApplicationCard = ({ counterData, @@ -47,11 +48,18 @@ const MonitoringApplicationCard = ({ hidden={!counter.tooltipText} template={} > -
-
- {loading ? : error ? 'N/A' : counter.title} -
-
+ + {loading ? ( + + ) : error || isNil(counter.title) ? ( + 'N/A' + ) : counter.link ? ( + {counter.title} + ) : ( + counter.title + )} + {counter.status && } + {counter.subtitle && (
} > {counter.subtitle} - + {counter.subtitleStatus && ( + + )}
)} diff --git a/src/components/MonitoringApplicationsPage/MonitoringApplications/MonitoringApplicationCounters/monitoringApplicationCounters.scss b/src/components/MonitoringApplicationsPage/MonitoringApplications/MonitoringApplicationCounters/monitoringApplicationCounters.scss index 007ac616a7..3303de6ac8 100644 --- a/src/components/MonitoringApplicationsPage/MonitoringApplications/MonitoringApplicationCounters/monitoringApplicationCounters.scss +++ b/src/components/MonitoringApplicationsPage/MonitoringApplications/MonitoringApplicationCounters/monitoringApplicationCounters.scss @@ -2,14 +2,15 @@ .monitoring-application__statistics-section { display: flex; - gap: 15px; flex-direction: row; - margin-bottom: 25px; + gap: 15px; width: 100%; + margin-bottom: 25px; .monitoring-stats { flex: 1; padding: 15px; + border: 1px solid colors.$frenchLilac; &__alert { background-color: colors.$carouselPink; @@ -20,22 +21,36 @@ cursor: pointer; } + &__link:hover { + color: colors.$topaz; + text-decoration: underline; + text-underline-offset: 1px; + text-decoration-thickness: 1px; + } + .stats-card__row:last-child { padding-bottom: 10px; } .stats__counter { - font-weight: 500; + display: flex; + align-items: center; + justify-content: center; color: colors.$primary; + font-weight: 500; font-size: 28px; } + .stats__failed > .stats__counter { + color: colors.$amaranth; + } + .stats__status { margin-bottom: 10px; } - .stats__subtitle { - margin-right: 5px; + [class^='state'] { + margin-left: 5px; } } } diff --git a/src/components/MonitoringApplicationsPage/MonitoringApplications/MonitoringApplicationCounters/monitoringApplicationCounters.util.jsx b/src/components/MonitoringApplicationsPage/MonitoringApplications/MonitoringApplicationCounters/monitoringApplicationCounters.util.jsx index a3ed39f4f0..e1afda171e 100644 --- a/src/components/MonitoringApplicationsPage/MonitoringApplications/MonitoringApplicationCounters/monitoringApplicationCounters.util.jsx +++ b/src/components/MonitoringApplicationsPage/MonitoringApplications/MonitoringApplicationCounters/monitoringApplicationCounters.util.jsx @@ -17,9 +17,20 @@ illegal under applicable law, and the grant of the foregoing license under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ -import { capitalize } from 'lodash' +import { capitalize, isEmpty } from 'lodash' +import classNames from 'classnames' +import { aggregateApplicationStatuses } from '../../../../utils/applications.utils' import { formatMinutesToString } from '../../../../utils/measureTime' +import { + BATCH_FILTER, + FAILED_STATE, + ME_MODE_FILTER, + MODEL_ENDPOINTS_TAB, + MODELS_PAGE, + REAL_TIME_FILTER, + RUNNING_STATE +} from '../../../../constants' export const generateCountersContent = (params, monitoringApplicationsStore) => { const { @@ -29,69 +40,91 @@ export const generateCountersContent = (params, monitoringApplicationsStore) => loading: monitoringApplicationIsLoading, error: monitoringApplicationError } = monitoringApplicationsStore + const { ready: appReady, error: appError } = aggregateApplicationStatuses( + monitoringApplications.applications + ) const applicationsCountersContent = [ { - id: 'applications', + id: 'applicationsStatus', title: 'Applications', counterData: [ { - title: - monitoringApplications.operatingFunctions.length + - monitoringApplications.applications.length + id: 'applications', + title: monitoringApplicationError ? null : monitoringApplications.applications.length } ] }, { id: 'appsStatus', - title: 'Apps Status', + title: 'Apps status', counterData: [ { - id: 'running', - title: applicationsSummary.running_model_monitoring_functions, + id: RUNNING_STATE, + title: appReady, + tooltipText: 'Running', subtitle: 'Running', - status: 'running' + subtitleStatus: RUNNING_STATE }, { - id: 'failed', - title: applicationsSummary.failed_model_monitoring_functions, + id: FAILED_STATE, + counterClassName: classNames({ + stats__failed: appError > 0 + }), + title: appError, + tooltipText: 'Error, Unhealthy', subtitle: 'Failed', - status: 'failed' + subtitleStatus: FAILED_STATE } ] }, { - id: 'endpoints', + id: 'endpointsStatus', title: 'Endpoints', counterData: [ { - id: 'batch', + id: BATCH_FILTER, title: applicationsSummary.batch_model_endpoint_count, + link: `/projects/${params.projectName}/${MODELS_PAGE}/${MODEL_ENDPOINTS_TAB}?${ME_MODE_FILTER}=${BATCH_FILTER}`, subtitle: 'Batch' }, { - id: 'realTime', + id: REAL_TIME_FILTER, title: applicationsSummary.real_time_model_endpoint_count, + link: `/projects/${params.projectName}/${MODELS_PAGE}/${MODEL_ENDPOINTS_TAB}?${ME_MODE_FILTER}=${REAL_TIME_FILTER}`, subtitle: 'Real-time' } ] }, { - id: 'runningFrequency', - title: 'Running frequency', + id: 'runningFrequencyStatus', + title: 'Running interval', counterData: [ { - title: `Every ${formatMinutesToString(monitoringApplications.applications?.[0]?.base_period)}` + id: 'interval', + title: monitoringApplicationError + ? null + : `Every ${formatMinutesToString(monitoringApplications.applications?.[0]?.base_period)}` } ] } ] + const aggregatedStreamStats = !isEmpty(monitoringApplication?.stats?.stream_stats) + ? Object.values(monitoringApplication.stats.stream_stats).reduce( + (acc, { committed, lag }) => { + acc.committed += committed + acc.lag += lag + + return acc + }, + { committed: 0, lag: 0 } + ) + : { committed: 'N/A', lag: 'N/A' } const applicationCountersContent = [ { id: 'appStatus', - title: 'App Status', - tip: 'Some tip', + title: 'App status', counterData: [ { id: 'appStatus', @@ -111,26 +144,26 @@ export const generateCountersContent = (params, monitoringApplicationsStore) => { id: 'detections', title: 'Detections', - counterData: [{ id: 'detections', title: monitoringApplication?.stats?.detections }] + counterData: [{ id: 'detections', title: monitoringApplication?.stats?.detected }] }, { id: 'possibleDetections', - title: 'Possible Detections', + title: 'Possible detections', counterData: [ - { id: 'possibleDetections', title: monitoringApplication?.stats?.potential_detections } + { id: 'possibleDetections', title: monitoringApplication?.stats?.potential_detection } ] }, { id: 'lag', title: 'Lag', tip: "Number of messages currently waiting in the app's queue", - counterData: [{ id: 'lag', title: monitoringApplication?.stats?.lag }] + counterData: [{ id: 'lag', title: aggregatedStreamStats.lag }] }, { id: 'commitedOffset', - title: 'Commited Offset', + title: 'Commited offset', tip: 'Total number of messages handled by the app', - counterData: [{ id: 'commitedOffset', title: monitoringApplication?.stats?.committed_offset }] + counterData: [{ id: 'commitedOffset', title: aggregatedStreamStats.committed }] } ] @@ -142,7 +175,7 @@ export const generateCountersContent = (params, monitoringApplicationsStore) => } : { content: applicationsCountersContent, - loading: applicationsSummary.loading, + loading: applicationsSummary.loading || monitoringApplicationIsLoading, error: applicationsSummary.error } } diff --git a/src/components/MonitoringApplicationsPage/MonitoringApplications/MonitoringApplications.jsx b/src/components/MonitoringApplicationsPage/MonitoringApplications/MonitoringApplications.jsx index 335b304a99..f673e9cbc7 100644 --- a/src/components/MonitoringApplicationsPage/MonitoringApplications/MonitoringApplications.jsx +++ b/src/components/MonitoringApplicationsPage/MonitoringApplications/MonitoringApplications.jsx @@ -21,16 +21,23 @@ import React, { useEffect, useMemo } from 'react' import { useDispatch, useSelector } from 'react-redux' import { useNavigate, useParams } from 'react-router-dom' -import Table from '../../Table/Table' +import ApplicationTableRow from '../../../elements/ApplicationTableRow/ApplicationTableRow' +import MEPsWithDetections from './MEPsWithDetections' import NoData from '../../../common/NoData/NoData' import SectionTable from '../../../elements/SectionTable/SectionTable' -import { Tip } from 'igz-controls/components' -import ApplicationTableRow from '../../../elements/ApplicationTableRow/ApplicationTableRow' +import Table from '../../Table/Table' +import { Loader, Tip } from 'igz-controls/components' +import { MODEL_ENDPOINTS_TAB, MONITORING_APP_PAGE } from '../../../constants' import { MONITORING_APPLICATIONS_NO_DATA_MESSAGE } from '../MonitoringApplicationsPage.util' -import { generateOperatingFunctionsTable } from './monitoringApplications.util' import { createApplicationContent } from '../../../utils/createApplicationContent' -import { removeMonitoringApplications } from '../../../reducers/monitoringApplicationsReducer' +import { generateOperatingFunctionsTable } from './monitoringApplications.util' +import { + removeMonitoringApplications, + removeMEPWithDetections +} from '../../../reducers/monitoringApplicationsReducer' +import { saveAndTransformSearchParams } from 'igz-controls/utils/filter.util' + import PresentMetricsIcon from 'igz-controls/images/present-metrics-icon.svg?react' const MonitoringApplications = () => { @@ -38,7 +45,9 @@ const MonitoringApplications = () => { const params = useParams() const navigate = useNavigate() const { - monitoringApplications: { applications = [], operatingFunctions = [] } + monitoringApplications: { applications = [], operatingFunctions = [] }, + loading, + error } = useSelector(store => store.monitoringApplicationsStore) const applicationsTableActionsMenu = useMemo( @@ -49,19 +58,27 @@ const MonitoringApplications = () => { id: 'open-metrics', label: 'Open metrics', icon: , - onClick: data => navigate(data.name) + onClick: data => + navigate( + `/projects/${params.projectName}/${MONITORING_APP_PAGE}/${data.name}/${MODEL_ENDPOINTS_TAB}${saveAndTransformSearchParams( + window.location.search, + true + )}` + ) } ] ], - [navigate] + [navigate, params.projectName] ) const operatingFunctionsTable = useMemo( - () => generateOperatingFunctionsTable(operatingFunctions), - [operatingFunctions] + () => generateOperatingFunctionsTable(operatingFunctions, params.projectName), + [operatingFunctions, params.projectName] ) const applicationsTableContent = useMemo(() => { - return applications.map(contentItem => createApplicationContent(contentItem)) - }, [applications]) + return applications.map(contentItem => + createApplicationContent(contentItem, params.projectName) + ) + }, [applications, params.projectName]) const applicationsTableHeaders = useMemo( () => applicationsTableContent[0]?.content ?? [], @@ -71,38 +88,47 @@ const MonitoringApplications = () => { useEffect(() => { return () => { dispatch(removeMonitoringApplications()) + dispatch(removeMEPWithDetections()) } }, [dispatch, params.projectName]) return (
+
- Controller calls - -
- -
-
-
- Operating functions + System functions
- {operatingFunctions.length === 0 ? ( - + {operatingFunctions.length === 0 && !loading ? ( + ) : ( - + )}
- All Applications + All applications
- {applications.length === 0 ? ( - + {applications.length === 0 && !loading ? ( + + ) : loading ? ( + ) : (
{ +export const generateOperatingFunctionsTable = (functions, projectName) => { const tableHeaders = [ { value: 'Name', @@ -30,7 +31,7 @@ export const generateOperatingFunctionsTable = functions => { }, { value: 'Status', className: 'table-cell_small' }, { - value: 'Started at', + value: 'Updated', className: 'table-cell_medium' }, { @@ -46,26 +47,28 @@ export const generateOperatingFunctionsTable = functions => { ] const tableBody = functions.map(func => { + const nuclioFunctionName = `${projectName}-${func.name.toLowerCase()}`.slice(0, 63) + return { name: { - value: capitalize(func.name), - link: generateNuclioLink(`/projects/${func.nuclio_function_uri}`), + value: func.name, + href: generateNuclioLink(`/projects/${projectName}/functions/${nuclioFunctionName}`), className: 'table-cell_big' }, status: { value: func.status, className: classnames('table-cell_small', 'status', `state-${func.status}`) }, - startedAt: { - value: formatDatetime(func.started_at, 'N/A'), + updatedTime: { + value: formatDatetime(func.updated_time, 'N/A'), className: 'table-cell_medium' }, lag: { - value: func.stats.lag, + value: func.stats.stream_stats.lag, className: 'table-cell_small' }, commitedOffset: { - value: func.stats.committed_offset, + value: func.stats.stream_stats.committed, className: 'table-cell_small' } } @@ -76,3 +79,102 @@ export const generateOperatingFunctionsTable = functions => { body: tableBody } } + +export function groupDataToBins(data, startTime, endTime) { + const grouped = new Map() + const allowedDeviation = 1000 + const DAY = 'day' + const HOUR = 'hour' + const MINUTES = 'minutes' // "minutes" represents 10 minutes + const timeDiffInHours = (new Date(endTime) - new Date(startTime) - allowedDeviation) / (1000 * 60 * 60) + const basePeriod = timeDiffInHours > 72 ? DAY : timeDiffInHours > 6 ? HOUR : MINUTES + + const roundDate = date => { + const dateToRound = new Date(date) + + if (basePeriod === HOUR) { + dateToRound.setMinutes(0, 0, 0) + } else if (basePeriod === MINUTES) { + const mins = dateToRound.getMinutes() + const roundedMins = Math.floor(mins / 10) * 10 + dateToRound.setMinutes(roundedMins, 0, 0) + } else { + dateToRound.setHours(0, 0, 0, 0) + } + + return dateToRound + } + + const incrementPeriod = period => { + if (basePeriod === HOUR) { + period.setHours(period.getHours() + 1) + } else if (basePeriod === MINUTES) { + period.setMinutes(period.getMinutes() + 10) + } else { + period.setDate(period.getDate() + 1) + } + + return period + } + // generate bins + for (const period = roundDate(startTime); period.getTime() <= endTime; incrementPeriod(period)) { + grouped.set(period.toISOString(), 0) + } + + data.forEach(([timestamp, value]) => { + const timestampDate = new Date(timestamp) + + // ignore potential data beyond selected time range + if (timestampDate >= startTime && timestampDate <= endTime) { + const date = roundDate(timestamp) + const dateKey = date.toISOString() + + grouped.set(dateKey, grouped.get(dateKey) + value) + } + }) + + const getLabel = (from, to) => { + const fromDate = moment(from) + const toDate = moment(to || from) + const shortFormatString = + basePeriod === MINUTES ? 'hh:mm A' : basePeriod === HOUR ? 'MM/DD, hh:mm A' : 'MM/DD/YY' + const fullFormatString = 'MM/DD/YY, hh:mm A' + + if (!to) { + toDate.add(basePeriod === MINUTES ? 10 : 1, basePeriod) + } + + return { + label: `${fromDate.format(shortFormatString)}`, + fullDate: `${fromDate.format(fullFormatString)} - ${toDate.format(fullFormatString)}` + } + } + + const groupedData = Array.from(grouped.entries()) + const dataset = groupedData.reduce( + (dataset, [date, value], index) => { + if (index === 0) { + // cut the first bin if it is not full + if (startTime > new Date(date)) return dataset + } + + const labelData = getLabel(date) + + dataset.values.push(value) + dataset.labels.push(labelData.label) + dataset.dates.push(labelData.fullDate) + + return dataset + }, + { values: [], labels: [], dates: [] } + ) + + // cut the last bin if it is not full + if (dataset.values.length && endTime > new Date(groupedData[groupedData.length - 1][0])) { + dataset.values.pop() + dataset.labels.pop() + dataset.dates.pop() + } + + return dataset +} diff --git a/src/components/MonitoringApplicationsPage/MonitoringApplicationsPage.jsx b/src/components/MonitoringApplicationsPage/MonitoringApplicationsPage.jsx index baa93432ce..bfa38a40e1 100644 --- a/src/components/MonitoringApplicationsPage/MonitoringApplicationsPage.jsx +++ b/src/components/MonitoringApplicationsPage/MonitoringApplicationsPage.jsx @@ -17,28 +17,28 @@ illegal under applicable law, and the grant of the foregoing license under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ -import React, { useCallback, useMemo } from 'react' -import { Outlet, useParams, useSearchParams } from 'react-router-dom' -import { useDispatch, useSelector } from 'react-redux' +import React, { useCallback, useEffect, useMemo, useRef } from 'react' +import { Outlet, useNavigate, useParams, useSearchParams } from 'react-router-dom' +import { useDispatch } from 'react-redux' import ActionBar from '../ActionBar/ActionBar' -import Loader from '../../common/Loader/Loader' -import TableTop from '../../elements/TableTop/TableTop' import Breadcrumbs from '../../common/Breadcrumbs/Breadcrumbs' import MonitoringApplicationCounters from './MonitoringApplications/MonitoringApplicationCounters/MonitoringApplicationCounters' +import TableTop from '../../elements/TableTop/TableTop' -import { getFiltersConfig } from './MonitoringApplicationsPage.util' -import { showErrorNotification } from '../../utils/notifications.util' -import { useFiltersFromSearchParams } from '../../hooks/useFiltersFromSearchParams.hook' import { + fetchMEPWithDetections, fetchMonitoringApplication, fetchMonitoringApplications, fetchMonitoringApplicationsSummary } from '../../reducers/monitoringApplicationsReducer' -import { fetchArtifacts } from '../../reducers/artifactsReducer' - +import { MODEL_ENDPOINTS_TAB, MONITORING_APP_PAGE } from '../../constants' import { PRIMARY_BUTTON } from 'igz-controls/constants' -import { MONITORING_APP_PAGE } from '../../constants' +import { fetchArtifacts } from '../../reducers/artifactsReducer' +import { getFiltersConfig } from './MonitoringApplicationsPage.util' +import { showErrorNotification } from 'igz-controls/utils/notification.util' +import { useFiltersFromSearchParams } from '../../hooks/useFiltersFromSearchParams.hook' +import { getSavedSearchParams } from 'igz-controls/utils/filter.util' import PresentMetricsIcon from 'igz-controls/images/present-metrics-icon.svg?react' @@ -47,77 +47,108 @@ import './monitoringApplicationsPage.scss' const MonitoringApplicationsPage = () => { const dispatch = useDispatch() const params = useParams() - const monitoringApplicationsStore = useSelector(store => store.monitoringApplicationsStore) + const navigate = useNavigate() const filtersConfig = useMemo(() => getFiltersConfig(), []) const filters = useFiltersFromSearchParams(filtersConfig) const [, setSearchParams] = useSearchParams() + const contentRef = useRef(null) const refreshMonitoringApplications = useCallback( - filters => { - dispatch(fetchMonitoringApplicationsSummary({ project: params.projectName })) - .unwrap() - .catch(error => { - showErrorNotification(dispatch, error, '', 'Failed to fetch applications summary') - }) - dispatch(fetchMonitoringApplications({ project: params.projectName, filters })) - .unwrap() - .catch(error => { - showErrorNotification(dispatch, error, '', 'Failed to fetch monitoring applications') - }) + (filters, isFilterApplyAction) => { + if (!isFilterApplyAction) { + dispatch(fetchMonitoringApplicationsSummary({ project: params.projectName })) + .unwrap() + .catch(error => { + showErrorNotification(dispatch, error, '', 'Failed to fetch applications summary') + }) + dispatch(fetchMonitoringApplications({ project: params.projectName, filters })) + .unwrap() + .catch(error => { + showErrorNotification(dispatch, error, '', 'Failed to fetch monitoring applications') + }) + dispatch( + fetchMEPWithDetections({ + project: params.projectName, + filters: filters + }) + ) + .unwrap() + .catch(error => { + showErrorNotification( + dispatch, + error, + '', + 'Failed to fetch model endpoints with suspected/detected issue' + ) + }) + } }, [dispatch, params.projectName] ) const refreshMonitoringApplication = useCallback( - filters => { - dispatch( - fetchArtifacts({ - project: params.projectName, - filters: { - ...filters, - labels: `mlrun/app-name=${params.name}` - } - }) - ) - .unwrap() - .catch(error => { - showErrorNotification(dispatch, error, '', 'Failed to fetch artifacts') - }) - dispatch( - fetchMonitoringApplication({ - project: params.projectName, - functionName: params.name, - filters - }) - ) - .unwrap() - .catch(error => { - showErrorNotification(dispatch, error, '', 'Failed to fetch monitoring application') - }) + (filters, isFilterApplyAction) => { + if (!isFilterApplyAction) { + dispatch( + fetchArtifacts({ + project: params.projectName, + filters: { + ...filters, + labels: `mlrun/app-name=${params.name}` + }, + config: { params: { page: 1, 'page-size': 50, format: 'minimal'} } // limit to 50 artifacts the same as we have on Artifacts page per 1 FE page to avoid overload + }) + ) + .unwrap() + .catch(error => { + showErrorNotification(dispatch, error, '', 'Failed to fetch artifacts') + }) + + dispatch( + fetchMonitoringApplication({ + project: params.projectName, + functionName: params.name, + filters + }) + ) + .unwrap() + .catch(error => { + showErrorNotification(dispatch, error, '', 'Failed to fetch monitoring application') + navigate( + `/projects/${params.projectName}/${MONITORING_APP_PAGE}${window.location.search}`, + { replace: true } + ) + }) + } }, - [dispatch, params.name, params.projectName] + [dispatch, navigate, params.name, params.projectName] ) - // TODO: uncomment in ML-10005 - // useEffect(() => { - // if (params.name) { - // refreshMonitoringApplication(filters) - // } else { - // refreshMonitoringApplications(filters) - // } - // }, [params.name, refreshMonitoringApplications, refreshMonitoringApplication, filters]) + useEffect(() => { + if (params.name) { + refreshMonitoringApplication(filters) + } else { + refreshMonitoringApplications(filters) + } + }, [params.name, refreshMonitoringApplications, refreshMonitoringApplication, filters]) + + useEffect(() => { + if (contentRef.current) { + contentRef.current.scrollTo(0, 0) + } + }, [params.name]) return (
-
+
{params.name && ( )} @@ -129,7 +160,11 @@ const MonitoringApplicationsPage = () => { label: 'Application metrics', className: 'action-button', hidden: !params.name, - onClick: () => {}, + onClick: () => { + navigate( + `/projects/${params.projectName}/${MONITORING_APP_PAGE}/${params.name}/${MODEL_ENDPOINTS_TAB}${window.location.search}` + ) + }, icon: } ]} @@ -143,7 +178,6 @@ const MonitoringApplicationsPage = () => { withoutExpandButton /> - {monitoringApplicationsStore.loading && }
diff --git a/src/components/MonitoringApplicationsPage/MonitoringApplicationsPage.util.jsx b/src/components/MonitoringApplicationsPage/MonitoringApplicationsPage.util.jsx index 62a7ed250c..61a324ffd1 100644 --- a/src/components/MonitoringApplicationsPage/MonitoringApplicationsPage.util.jsx +++ b/src/components/MonitoringApplicationsPage/MonitoringApplicationsPage.util.jsx @@ -31,7 +31,6 @@ export const MONITORING_APPLICATIONS_NO_DATA_MESSAGE = 'No data is available for export const getFiltersConfig = () => ({ [DATES_FILTER]: { customOptions: datePickerPastOptions, - excludeCustomRange: true, label: 'Time range:', timeFrameLimit: TIME_FRAME_LIMITS.MONTH, initialValue: getDatePickerFilterValue(datePickerPastOptions, PAST_24_HOUR_DATE_OPTION, true) diff --git a/src/components/MonitoringApplicationsPage/monitoringApplicationsPage.scss b/src/components/MonitoringApplicationsPage/monitoringApplicationsPage.scss index 06a08a1faa..6eea95bfa7 100644 --- a/src/components/MonitoringApplicationsPage/monitoringApplicationsPage.scss +++ b/src/components/MonitoringApplicationsPage/monitoringApplicationsPage.scss @@ -1,67 +1,120 @@ @use 'igz-controls/scss/colors'; @use 'igz-controls/scss/shadows'; @use 'igz-controls/scss/variables'; -@use '/src/scss/mixins'; +@use '@/scss/mixins'; $applicationRowHeight: variables.$rowHeight; $applicationHeaderRowHeight: variables.$headerRowHeight; $applicationRowHeightExtended: variables.$rowHeightExtended; -.monitoring-apps-title { - color: colors.$primary; - font-weight: 400; - font-size: 2.1em; -} - -.content__action-bar-wrapper { - margin-bottom: 15px; -} - -.monitoring-apps { - flex: 1; -} - -.monitoring-app__section { - display: grid; - gap: 15px; - margin-bottom: 25px; - - &.section_small { - grid-template-columns: repeat(2, 1fr); - min-height: 200px; +.monitoring-app-content { + .monitoring-apps-title { + color: colors.$primary; + font-weight: 400; + font-size: 2.1em; } - &.section_big { - min-height: 300px; + .monitoring-apps { + flex: 1; } - .monitoring-app__section-item { - display: flex; - flex-direction: column; - border: 1px solid colors.$frenchLilac; - color: colors.$topaz; - background-color: colors.$white; - border-radius: 8px; - box-shadow: shadows.$previewBoxShadowInit; - padding: 20px; - transition: all 0.3s ease-in-out; - - .section-item_title { - display: flex; - align-items: center; - color: colors.$primary; - font-size: 1rem; - line-height: 23px; - margin-bottom: 20px; + .monitoring-app__section { + display: grid; + gap: 15px; + margin-bottom: 25px; + + &.section_small { + grid-template-columns: repeat(2, 1fr); + min-height: 200px; } - .section-table { - width: 100%; - height: auto; + &.section_big { + min-height: 300px; } - .applications-table { - @include mixins.rowsHeight($applicationHeaderRowHeight, $applicationRowHeight, $applicationRowHeightExtended); + .monitoring-app__section-item { + display: flex; + flex-direction: column; + padding: 20px; + color: colors.$topaz; + background-color: colors.$white; + border: 1px solid colors.$frenchLilac; + border-radius: 8px; + box-shadow: shadows.$previewBoxShadowInit; + transition: all 0.3s ease-in-out; + + .section-item_title { + display: flex; + align-items: center; + margin-bottom: 20px; + color: colors.$primary; + font-size: 1rem; + line-height: 23px; + } + + .section-table { + width: 100%; + height: auto; + } + + .applications-table { + @include mixins.rowsHeight( + $applicationHeaderRowHeight, + $applicationRowHeight, + $applicationRowHeightExtended + ); + } + + .section-item_chart-wrapper { + position: relative; + width: 100%; + height: 268px; + + .section-item_chart { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + + .loader-wrapper { + position: absolute; + } + + .section-item_chart-area { + height: 100%; + padding-bottom: 25px; + overflow-x: auto; + + &_x-axis-label { + position: absolute; + bottom: 10px; + left: 50%; + font-weight: 500; + font-size: 13px; + transform: translate(-50%, 0); + } + + &.loading { + visibility: hidden; + } + + .section-item_ml-chart-wrapper { + width: 100%; + min-width: 100%; + height: 100%; + } + + & > canvas#chart-y-axis { + position: absolute; + top: 0; + left: 0; + background-color: colors.$white; + pointer-events: none; + } + } + } + } } } } diff --git a/src/components/Pipeline/Pipeline.jsx b/src/components/Pipeline/Pipeline.jsx index 42af4b3e76..e206fa3985 100644 --- a/src/components/Pipeline/Pipeline.jsx +++ b/src/components/Pipeline/Pipeline.jsx @@ -20,32 +20,41 @@ such restriction. import React, { useEffect, useState } from 'react' import PropTypes from 'prop-types' import classnames from 'classnames' -import { groupBy, forEach, isEmpty, map, concat } from 'lodash' +import { groupBy, forEach, isEmpty, map, concat, mapValues } from 'lodash' import { Link, useParams } from 'react-router-dom' import { useDispatch, useSelector } from 'react-redux' -import MlReactFlow from '../../common/ReactFlow/MlReactFlow' +import { Tooltip, TextTooltipTemplate, RoundedIcon, Loader } from 'igz-controls/components' +import Accordion from '../../common/Accordion/Accordion' +import ArtifactPopUp from '../../elements/DetailsPopUp/ArtifactPopUp/ArtifactPopUp' import CodeBlock from '../../common/CodeBlock/CodeBlock' +import MlReactFlow from '../../common/ReactFlow/MlReactFlow' +import ModelEndpointPopUp from '../../elements/DetailsPopUp/ModelEndpointPopUp/ModelEndpointPopUp' import NoData from '../../common/NoData/NoData' -import { Tooltip, TextTooltipTemplate, RoundedIcon } from 'igz-controls/components' -import Loader from '../../common/Loader/Loader' import { DEFAULT_EDGE, FLOATING_EDGE, GREY_NODE, ML_EDGE, + ML_MODEL_RUNNER_NODE, ML_NODE, + MODEL_RUNNER_STEP_KIND, PRIMARY_NODE, REAL_TIME_PIPELINES_TAB, ROUNDED_RECTANGLE_NODE_SHAPE, SECONDARY_NODE } from '../../constants' -import { getLayoutedElements } from '../../common/ReactFlow/mlReactFlow.util' import { fetchAndParseFunction } from '../ModelsPage/RealTimePipelines/realTimePipelines.util' +import { getLayoutedElements } from '../../common/ReactFlow/mlReactFlow.util' +import { openPopUp } from 'igz-controls/utils/common.util' +import { parseUri } from '../../utils' +import { useModelsPage } from '../ModelsPage/ModelsPage.context' +import Arrow from 'igz-controls/images/arrow.svg?react' import Back from 'igz-controls/images/back-arrow.svg?react' import CloseIcon from 'igz-controls/images/close.svg?react' +import ConnectionIcon from 'igz-controls/images/connections-icon.svg?react' import './pipeline.scss' @@ -54,11 +63,12 @@ const Pipeline = ({ content }) => { const [edges, setEdges] = useState([]) const [pipeline, setPipeline] = useState({}) const [selectedStep, setSelectedStep] = useState({}) - const [selectedStepData, setSelectedStepData] = useState([]) + const [selectedStepData, setSelectedStepData] = useState({}) const [stepIsSelected, setStepIsSelected] = useState(false) const params = useParams() const dispatch = useDispatch() const functionsStore = useSelector(store => store.functionsStore) + const { handleMonitoring, toggleConvertedYaml, frontendSpec } = useModelsPage() useEffect(() => { const selectedFunction = content.find(contentItem => contentItem.hash === params.pipelineId) @@ -72,44 +82,87 @@ const Pipeline = ({ content }) => { useEffect(() => { if (selectedStep.data) { - const selectedStepData = selectedStep.data.customData - - setSelectedStepData([ - { - label: 'Type:', - value: selectedStepData.kind - }, - { - label: 'After:', - value: selectedStepData.after?.[0] - }, - { - label: 'Class name:', - value: selectedStepData.class_name - }, - { - label: 'Function name:', - value: selectedStepData.function - }, - { - label: 'Handler:', - value: selectedStepData.handler - }, - { - label: 'Arguments:', - value: selectedStepData.class_args, - type: 'codeblock' - }, - { - label: 'Input path:', - value: '' - }, - { - label: 'Result path:', - value: '' - } - ]) + const selectedStepCustomData = selectedStep.data.customData + + setSelectedStepData({ + general: [ + { + label: 'Type:', + value: selectedStepCustomData.kind + }, + { + label: 'Class name:', + value: selectedStepCustomData.class_name + }, + { + label: 'Function name:', + value: selectedStepCustomData.function + }, + { + label: 'Handler:', + value: selectedStepCustomData.handler, + hidden: selectedStepCustomData.kind === MODEL_RUNNER_STEP_KIND + }, + { + label: 'Arguments:', + value: selectedStepCustomData.class_args, + type: 'codeblock' + }, + { + label: 'Input path:', + value: selectedStepCustomData.input_path + }, + { + label: 'Result path:', + value: selectedStepCustomData.result_path + } + ], + runningModels: mapValues( + selectedStepCustomData?.class_args?.monitoring_data ?? {}, + (runningModelData, runningModelName) => { + return [ + { + label: 'Model endpoint:', + value: runningModelData.model_endpoint_uid, + additionalData: { + modelEndpointName: runningModelName + }, + type: 'pop-up' + }, + { + label: 'Model artifact:', + value: runningModelData.model_path, + type: 'pop-up' + }, + { + label: 'Class name:', + value: runningModelData.model_class + }, + { + label: 'Input path:', + value: runningModelData.input_path + }, + { + label: 'Result path:', + value: runningModelData.result_path + }, + { + label: 'Outputs:', + value: runningModelData.outputs.join(', ') + }, + { + label: 'Execution mechanism:', + value: + selectedStepCustomData?.class_args?.execution_mechanism_by_model_name?.[ + runningModelName + ] ?? '' + } + ] + } + ) + }) } + setStepIsSelected(Boolean(selectedStep.id)) }, [selectedStep]) @@ -143,18 +196,21 @@ const Pipeline = ({ content }) => { } forEach(steps, (step, stepName) => { + if (!step.kind) return + + let nodeType = step.kind === MODEL_RUNNER_STEP_KIND ? ML_MODEL_RUNNER_NODE : ML_NODE const subLabel = step.kind === 'queue' ? '« queue »' : step.kind === 'router' ? '« router »' : '' newNodes.push({ id: stepName, - type: ML_NODE, + type: nodeType, data: { subType: PRIMARY_NODE, label: stepName, subLabel: subLabel, isSelectable: true, - customData: step + customData: { ...step, track_models: graph.track_models } }, className: classnames(selectedStep.id === stepName && 'selected'), position: { x: 0, y: 0 } @@ -269,6 +325,22 @@ const Pipeline = ({ content }) => { } }, [pipeline, selectedStep]) + const openModelRunnerPopUp = modelRunnerRowData => { + if (modelRunnerRowData.value.startsWith('store://')) { + openPopUp(ArtifactPopUp, { + artifactData: parseUri(modelRunnerRowData.value) + }) + } else { + openPopUp(ModelEndpointPopUp, { + modelEndpointUid: modelRunnerRowData.value, + modelEndpointName: modelRunnerRowData.additionalData.modelEndpointName, + frontendSpec, + handleMonitoring, + toggleConvertedYaml + }) + } + } + return (
@@ -306,28 +378,94 @@ const Pipeline = ({ content }) => {
{stepIsSelected && (
-
- {selectedStep.id} - setSelectedStep({})} tooltipText="Close"> - - -
- {selectedStepData.map(rowData => ( -
- {rowData.type === 'codeblock' ? ( - - ) : ( - <> -
{rowData.label}
-
- }> - {rowData.value} - -
- +
+
+ {selectedStep.type === ML_MODEL_RUNNER_NODE && ( +
+ +
)} + + setSelectedStep({})} tooltipText="Close"> + +
- ))} +
+
General
+ {selectedStepData.general.map( + rowData => + !rowData.hidden && ( +
+
{rowData.label}
+ {rowData.type === 'codeblock' ? ( + + ) : ( +
+ }> + {rowData.value} + +
+ )} +
+ ) + )} +
+ {Object.keys(selectedStepData.runningModels).length > 0 && ( +
+
+ Running models ({Object.keys(selectedStepData.runningModels).length}) +
+ {Object.entries(selectedStepData.runningModels).map( + ([modelRunnerName, modelRunnerData]) => ( + } + iconClassName="graph-pane__expand-icon" + > +
{modelRunnerName}
+
+ {modelRunnerData.map(rowData => { + return ( +
+
{rowData.label}
+
openModelRunnerPopUp(rowData) + : null + } + > + } + className={classnames({ link: rowData.type === 'pop-up' })} + > + {rowData.value} + +
+
+ ) + })} +
+
+ ) + )} +
+ )} +
)}
diff --git a/src/components/Pipeline/pipeline.scss b/src/components/Pipeline/pipeline.scss index 6ae61b1ad7..c39016158f 100644 --- a/src/components/Pipeline/pipeline.scss +++ b/src/components/Pipeline/pipeline.scss @@ -24,30 +24,88 @@ &__title { margin: 0 5px; - font-size: 24px; overflow: hidden; font-weight: bold; + font-size: 24px; } } } .pipeline-content { .graph-pane { + &__section { + padding: 15px 0; + + & + .graph-pane__section { + border-top: borders.$secondaryBorder; + } + + &-title { + font-size: 16px; + font-weight: bold; + padding: 5px 25px; + } + } + &__row { display: flex; align-items: center; - margin: 5px 25px; + margin: 8px 25px; + + &_wrap { + flex-wrap: wrap; + } &-label { margin-right: 10px; - color: colors.$spunPearl; - font-weight: bold; white-space: nowrap; } &-value { overflow: hidden; + color: colors.$topaz; + } + } + + .graph-pane__expand-item { + height: unset; + margin-left: 20px; + margin-right: 20px; + border-bottom: borders.$secondaryBorder; + + .graph-pane__row { + margin-left: 0; + margin-right: 0; + } + + .graph-pane__expand-title { + margin-left: 45px; + padding: 8px 0; + font-weight: bold; + font-size: 15px; + } + + .graph-pane__expand-content { + display: none; + margin: 5px 0 20px 45px; } + + &.open { + height: auto; + + .graph-pane__expand-content { + display: block; + } + } + + .graph-pane__expand-icon { + position: absolute; + left: 0; + } + } + + .code-block { + margin-top: 5px; } } } diff --git a/src/components/Project/ProjectAction/ProjectAction.scss b/src/components/Project/ProjectAction/ProjectAction.scss index b4f4153484..2f154cb00b 100644 --- a/src/components/Project/ProjectAction/ProjectAction.scss +++ b/src/components/Project/ProjectAction/ProjectAction.scss @@ -5,27 +5,27 @@ flex-flow: row wrap; align-items: flex-start; justify-content: flex-start; + width: 100%; margin: 0; padding: 0; list-style-type: none; - width: 100%; transition: height 0.5s ease-in-out; &__item { display: flex; - justify-content: center; flex: 1 0 auto; + justify-content: center; max-width: 33%; margin: 0 0 1.5em; text-align: center; &-wrapper { + position: relative; display: flex; flex-flow: column nowrap; align-items: center; - position: relative; - margin: 0 1.2em; min-width: 105px; + margin: 0 1.2em; cursor: pointer; &:hover, @@ -53,8 +53,8 @@ justify-content: center; width: 68px; height: 68px; - margin-bottom: 0.5rem; margin-right: 0; + margin-bottom: 0.5rem; background-color: colors.$selago; border-radius: 50%; transition: background-color 0.3s ease-in-out; diff --git a/src/components/Project/ProjectMonitor.jsx b/src/components/Project/ProjectMonitor.jsx index ef5d50a382..2c4a49732a 100644 --- a/src/components/Project/ProjectMonitor.jsx +++ b/src/components/Project/ProjectMonitor.jsx @@ -38,7 +38,7 @@ import { import { fetchProject, fetchProjectFunctions, - fetchProjectSummary, + fetchProjectSummaryAndNuclioFuncs, removeProjectData, removeProjectSummary } from '../../reducers/projectReducer' @@ -46,12 +46,13 @@ import { areNuclioStreamsEnabled } from '../../utils/helper' import { fetchNuclioV3ioStreams } from '../../reducers/nuclioReducer' import { generateCreateNewOptions, handleFetchProjectError } from './project.utils' import { openPopUp } from 'igz-controls/utils/common.util' +import { generateNuclioLink } from '../../utils' import { removeFunctionsError, removeNewFunction } from '../../reducers/functionReducer' import { removeNewFeatureSet } from '../../reducers/featureStoreReducer' -import { setNotification } from '../../reducers/notificationReducer' -import { showErrorNotification } from '../../utils/notifications.util' -import { useMode } from '../../hooks/mode.hook' +import { setNotification } from 'igz-controls/reducers/notificationReducer' +import { showErrorNotification } from 'igz-controls/utils/notification.util' import { useNuclioMode } from '../../hooks/nuclioMode.hook' +import { useMode } from '../../hooks/mode.hook' const ProjectMonitor = () => { const [createFeatureSetPanelIsOpen, setCreateFeatureSetPanelIsOpen] = useState(false) @@ -60,12 +61,13 @@ const ProjectMonitor = () => { const [confirmData, setConfirmData] = useState(null) const navigate = useNavigate() const params = useParams() - const { isDemoMode } = useMode() const dispatch = useDispatch() const { isNuclioModeDisabled } = useNuclioMode() + const { isDemoMode } = useMode() const projectAbortControllerRef = useRef(new AbortController()) const projectSummariesAbortControllerRef = useRef(new AbortController()) const v3ioStreamsAbortControllerRef = useRef(new AbortController()) + const nuclioFunctionsAbortControllerRef = useRef(new AbortController()) const frontendSpec = useSelector(state => state.appStore.frontendSpec) const functionsStore = useSelector(store => store.functionsStore) const projectStore = useSelector(store => store.projectStore) @@ -87,6 +89,13 @@ const ProjectMonitor = () => { [frontendSpec] ) + const openRegisterModelModal = useCallback(() => { + openPopUp(RegisterModelModal, { + params: params, + refresh: () => navigate(registerArtifactLink(MODEL_TYPE)) + }) + }, [params, navigate, registerArtifactLink]) + const openRegisterArtifactModal = useCallback( artifactKind => { openPopUp(RegisterArtifactModal, { @@ -98,19 +107,13 @@ const ProjectMonitor = () => { }, [navigate, params, registerArtifactLink] ) - - const openRegisterModelModal = useCallback(() => { - openPopUp(RegisterModelModal, { - params: params, - refresh: () => navigate(registerArtifactLink(MODEL_TYPE)) - }) - }, [params, navigate, registerArtifactLink]) - const { createNewOptions } = useMemo(() => { const createNewOptions = generateCreateNewOptions( navigate, params, openRegisterArtifactModal, + generateNuclioLink, + openPopUp, openRegisterModelModal, setCreateFeatureSetPanelIsOpen, setIsNewFunctionPopUpOpen, @@ -120,11 +123,12 @@ const ProjectMonitor = () => { return { createNewOptions } - }, [isDemoMode, navigate, params, openRegisterArtifactModal, openRegisterModelModal]) + }, [navigate, params, openRegisterArtifactModal, openRegisterModelModal, isDemoMode]) const fetchProjectDataAndSummary = useCallback(() => { projectAbortControllerRef.current = new AbortController() projectSummariesAbortControllerRef.current = new AbortController() + nuclioFunctionsAbortControllerRef.current = new AbortController() Promise.all([ dispatch( @@ -135,9 +139,10 @@ const ProjectMonitor = () => { }) ).unwrap(), dispatch( - fetchProjectSummary({ + fetchProjectSummaryAndNuclioFuncs({ project: params.projectName, - signal: projectSummariesAbortControllerRef.current.signal + projectSummarySignal: projectSummariesAbortControllerRef.current.signal, + functionsSignal: nuclioFunctionsAbortControllerRef.current.signal }) ).unwrap() ]).catch(error => { @@ -154,6 +159,7 @@ const ProjectMonitor = () => { projectAbortControllerRef.current.abort(REQUEST_CANCELED) projectSummariesAbortControllerRef.current.abort(REQUEST_CANCELED) v3ioStreamsAbortControllerRef.current.abort(REQUEST_CANCELED) + nuclioFunctionsAbortControllerRef.current.abort(REQUEST_CANCELED) } }, [params.projectName]) diff --git a/src/components/Project/ProjectMonitorView.jsx b/src/components/Project/ProjectMonitorView.jsx index ec06b0e911..269a7b7931 100644 --- a/src/components/Project/ProjectMonitorView.jsx +++ b/src/components/Project/ProjectMonitorView.jsx @@ -21,22 +21,21 @@ import React from 'react' import PropTypes from 'prop-types' import { isEmpty } from 'lodash' -import AlertsCounters from '../../elements/ProjectsMonitoringCounters/AlertsCounters' import Breadcrumbs from '../../common/Breadcrumbs/Breadcrumbs' import FeatureSetsPanel from '../FeatureSetsPanel/FeatureSetsPanel' import FunctionsPanel from '../FunctionsPanel/FunctionsPanel' -import Loader from '../../common/Loader/Loader' import NewFunctionPopUp from '../../elements/NewFunctionPopUp/NewFunctionPopUp' import NoData from '../../common/NoData/NoData' -import ProjectFunctions from '../../elements/ProjectFunctions/ProjectFunctions' import ProjectDetailsHeader from '../../common/ProjectDetailsHeader/ProjectDetailsHeader' +import ProjectFunctions from '../../elements/ProjectFunctions/ProjectFunctions' import ProjectJobs from '../../elements/ProjectJobs/ProjectJobs' -import ProjectSummaryCard from '../../elements/ProjectSummaryCard/ProjectSummaryCard' +import ProjectsMonitoring from '../ProjectsPage/ProjectsMonitoring/ProjectsMonitoring' import Select from '../../common/Select/Select' -import { ConfirmDialog, RoundedIcon } from 'igz-controls/components' + +import { ConfirmDialog, RoundedIcon, Loader } from 'igz-controls/components' import { PANEL_CREATE_MODE } from '../../constants' -import { launchIDEOptions, generateTipMessageForCounter } from './project.utils' +import { launchIDEOptions } from './project.utils' import RefreshIcon from 'igz-controls/images/refresh.svg?react' @@ -57,15 +56,14 @@ const ProjectMonitorView = ({ nuclioStreamsAreEnabled, params, project, - projectSummary, refresh, setIsNewFunctionPopUpOpen, setShowFunctionsPanel, showFunctionsPanel }) => { return ( -
-
+
+
{project.loading ? ( @@ -91,13 +89,10 @@ const ProjectMonitorView = ({ ) : isEmpty(project.data) ? ( ) : ( -
+
-
- Counters use a caching mechanism, and are not auto-refreshed. -
- - {content.map(({ headerLabel, headerId, isSortable, ...tableItem }, index) => { - return tableItem.type !== 'hidden' && !tableItem.hidden && !tableItem.headerIsHidden ? ( - - ) : null - })} - {!hideActionsMenu && - - ) - } -) - -TableHead.displayName = 'TableHead' - -TableHead.propTypes = { - content: PropTypes.array.isRequired, - hideActionsMenu: PropTypes.bool, - mainRowItemsCount: PropTypes.number.isRequired, - selectedItem: PropTypes.object.isRequired, - sortProps: SORT_PROPS -} - -export default TableHead diff --git a/src/components/Table/TableView.jsx b/src/components/Table/TableView.jsx deleted file mode 100644 index a118977482..0000000000 --- a/src/components/Table/TableView.jsx +++ /dev/null @@ -1,151 +0,0 @@ -/* -Copyright 2019 Iguazio Systems Ltd. - -Licensed under the Apache License, Version 2.0 (the "License") with -an addition restriction as set forth herein. You may not use this -file except in compliance with the License. You may obtain a copy of -the License at http://www.apache.org/licenses/LICENSE-2.0. - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -implied. See the License for the specific language governing -permissions and limitations under the License. - -In addition, you may not use the software for any purposes that are -illegal under applicable law, and the grant of the foregoing license -under the Apache 2.0 license is conditioned upon your compliance with -such restriction. -*/ -import React from 'react' -import PropTypes from 'prop-types' -import { isEmpty } from 'lodash' -import classnames from 'classnames' - -import Details from '../Details/Details' -import TableHead from './TableHead' - -import { ACTIONS_MENU, VIRTUALIZATION_CONFIG } from '../../types' -import { FULL_VIEW_MODE, MAIN_TABLE_BODY_ID, MAIN_TABLE_ID } from '../../constants' -import { SORT_PROPS } from 'igz-controls/types' - -const TableView = ({ - actionsMenu, - applyDetailsChanges = () => {}, - applyDetailsChangesCallback = () => {}, - children, - detailsFormInitialValues, - getCloseDetailsLink = null, - handleCancel, - hideActionsMenu, - isTablePanelOpen, - mainRowItemsCount, - pageData, - selectedItem, - skipTableWrapper = false, - sortProps = null, - tab, - tableBodyRef, - tableClassName, - tableContentRef, - tableHeadRef, - tableHeaders, - tablePanelRef, - tableRef, - viewMode, - virtualizationConfig, - withActionMenu -}) => { - const tableClass = classnames( - 'table', - 'table-main', - !isEmpty(selectedItem) && 'table-with-details', - tableClassName && tableClassName - ) - const tableWrapperClass = classnames(!skipTableWrapper && 'table__wrapper') - - return ( -
-
-
-
sortProps.sortTable(headerId) : null} - > - }> - - - - {tableItem.tip && } - } -
- {tableHeaders?.length > 0 && ( - - )} - - {children} - -
- {isTablePanelOpen && ( -
-
{pageData.tablePanel}
-
- )} -
- {!isEmpty(selectedItem) && viewMode !== FULL_VIEW_MODE && ( -
- )} -
-
- ) -} - -TableView.propTypes = { - actionsMenu: ACTIONS_MENU.isRequired, - applyDetailsChanges: PropTypes.func, - applyDetailsChangesCallback: PropTypes.func, - children: PropTypes.node.isRequired, - detailsFormInitialValues: PropTypes.object.isRequired, - getCloseDetailsLink: PropTypes.func, - handleCancel: PropTypes.func.isRequired, - hideActionsMenu: PropTypes.bool.isRequired, - isTablePanelOpen: PropTypes.bool.isRequired, - mainRowItemsCount: PropTypes.number.isRequired, - pageData: PropTypes.object.isRequired, - selectedItem: PropTypes.object.isRequired, - skipTableWrapper: PropTypes.bool, - sortProps: SORT_PROPS, - tab: PropTypes.string, - tableBodyRef: PropTypes.object.isRequired, - tableClassName: PropTypes.string.isRequired, - tableContentRef: PropTypes.object.isRequired, - tableHeadRef: PropTypes.object, - tableHeaders: PropTypes.array, - tablePanelRef: PropTypes.object, - tableRef: PropTypes.object.isRequired, - viewMode: PropTypes.string.isRequired, - virtualizationConfig: VIRTUALIZATION_CONFIG.isRequired, - withActionMenu: PropTypes.bool -} - -export default TableView diff --git a/src/components/Table/table.scss b/src/components/Table/table.scss deleted file mode 100644 index 88a69e481c..0000000000 --- a/src/components/Table/table.scss +++ /dev/null @@ -1,283 +0,0 @@ -@use 'igz-controls/scss/variables'; -@use 'igz-controls/scss/colors'; -@use 'igz-controls/scss/mixins'; -@use 'igz-controls/scss/borders'; -@use 'igz-controls/scss/shadows'; - -@mixin tableCellWidth { - flex: 0 0 auto; - min-width: 75px; -} - -.table { - &__flex { - display: flex; - flex: 1; - flex-flow: row wrap; - } - - &__content { - position: relative; - flex: 1; - - [class*='icon'] { - flex-wrap: nowrap; - } - - .text-bold { - font-weight: 500; - } - } - - &__wrapper { - .content & { - position: absolute; - top: 0; - right: 0; - z-index: 2; - display: flex; - width: 100%; - height: 100%; - overflow-y: auto; - color: colors.$mulledWine; - background-color: colors.$white; - } - } - - & [class*='table-cell-'] { - @include tableCellWidth; - } - - .table-row { - .table-cell { - &-1 { - flex: 1; - } - - &-2 { - flex: 2; - } - - &-3 { - flex: 3; - } - - &-4 { - flex: 4; - } - - &-5 { - flex: 5; - } - - &-6 { - flex: 6; - } - - &-7 { - flex: 7; - } - - &-8 { - flex: 8; - } - - &-9 { - flex: 9; - } - - &-10 { - flex: 10; - } - - &-extra-small { - flex: 1; - max-width: 85px; - } - - &-small { - flex: 1; - max-width: 150px; - } - } - - &:has(.actions-menu__container-active) { - background-color: colors.$ghostWhite; - } - } - - &.table { - &__scrolled { - .table-cell-name { - &::after { - position: absolute; - top: 0; - right: 0; - bottom: 0; - width: 5px; - background-color: inherit; - border-right: borders.$secondaryBorder; - box-shadow: 2px 0 2px -1px rgba(colors.$black, 0.2); - content: ''; - } - } - - .parent-row_expanded { - .row_grouped-by { - .table-cell-name { - border-right: none; - box-shadow: none; - } - } - } - } - } - - .targets-cell { - flex-wrap: nowrap; - min-width: 130px; - - svg { - margin: 0 5px; - - &:first-child { - margin-left: 0; - } - } - } - - &__panel-container { - position: sticky; - top: 0; - z-index: 1; - width: auto; - border-left: borders.$primaryBorder; - box-shadow: shadows.$tablePanelShadow; - - &.hidden { - display: none; - } - } - - &__panel { - height: 100%; - overflow: hidden auto; - } - - .error-message { - justify-content: center; - width: 100%; - } - - .table { - &-header { - &__cell { - @include tableCellWidth; - - &.buttonPopout, - &.buttonDownload { - @include mixins.tableColumnFlex(0.5, 80px); - } - - &.align-right { - justify-content: flex-end; - } - - .tip-container { - margin-left: 2px; - } - } - - .icons-container { - min-width: 150px; - } - } - - &-body { - color: colors.$mulledWine; - - &__cell { - @include tableCellWidth; - - &_hidden { - font-size: 0; - - * { - visibility: hidden; - } - - .chip { - visibility: hidden; - } - } - - .cell_name { - position: relative; - display: flex; - flex: 1; - flex-direction: column; - margin: 0; - } - - .text_small { - min-width: 100%; - max-width: 50px; - } - - &.align-right { - justify-content: flex-end; - } - - &_type { - display: inline-flex; - text-transform: capitalize; - } - - a { - position: relative; - width: 100%; - margin: 0; - text-decoration: none; - - span { - display: block; - width: 100%; - } - } - - i { - margin-right: 5px; - } - - button { - display: flex; - font-size: 15px; - background-color: transparent; - border: none; - - &:disabled { - cursor: default; - } - - &:not(:disabled) { - cursor: pointer; - } - } - - .path-tooltip { - cursor: pointer; - } - - .chip_short { - max-width: 100px; - } - - .alert-icon-cell { - display: flex; - gap: 4px; - align-items: center; - } - } - } - } -} diff --git a/src/components/Workflow/JobsFunctionsTableRow/JobsFunctionsTableRow.jsx b/src/components/Workflow/JobsFunctionsTableRow/JobsFunctionsTableRow.jsx index 3ab4f8cea1..b11e2c38ba 100644 --- a/src/components/Workflow/JobsFunctionsTableRow/JobsFunctionsTableRow.jsx +++ b/src/components/Workflow/JobsFunctionsTableRow/JobsFunctionsTableRow.jsx @@ -22,7 +22,7 @@ import PropTypes from 'prop-types' import classnames from 'classnames' import { useParams } from 'react-router-dom' -import TableCell from '../../../elements/TableCell/TableCell' +import { TableCell } from 'igz-controls/components' import { DETAILS_OVERVIEW_TAB } from '../../../constants' import { isWorkflowJobSelected } from '../workflow.util' @@ -41,7 +41,7 @@ const JobsFunctionsTableRow = ({ handleSelectItem = () => {}, rowItem, selectedI return ( !rowItemProp.hidden && ( store.appStore.frontendSpec?.ce?.version) + const accessibleProjectsMap = useSelector(state => state.projectStore.accessibleProjectsMap) + + useEffect(() => { + fetchMissingProjectPermission(projectName, accessibleProjectsMap, dispatch) + }, [dispatch, projectName, accessibleProjectsMap]) const graphViewClassNames = classnames( 'graph-view', @@ -218,31 +231,44 @@ const Workflow = ({ return (
-
- - } - > - - + + +
+ {(ce || accessibleProjectsMap[projectName]) && ( +
@@ -296,6 +322,7 @@ Workflow.propTypes = { actionsMenu: ACTIONS_MENU.isRequired, backLink: PropTypes.string.isRequired, handleCancel: PropTypes.func.isRequired, + handleConfirmTerminateWorkflow: PropTypes.func, itemIsSelected: PropTypes.bool.isRequired, pageData: PropTypes.object.isRequired, selectedFunction: PropTypes.object, diff --git a/src/components/Workflow/workflow.scss b/src/components/Workflow/workflow.scss index a83c2c7a9c..085e7c0b14 100644 --- a/src/components/Workflow/workflow.scss +++ b/src/components/Workflow/workflow.scss @@ -6,6 +6,21 @@ flex-direction: column; width: 100%; + .workflow__actions { + &-container { + display: flex; + flex-direction: row; + gap: 2px; + align-items: center; + } + + svg { + width: 14px; + height: 14px; + padding: 0; + } + } + .workflow-content { flex-direction: column; diff --git a/src/components/Workflow/workflow.util.js b/src/components/Workflow/workflow.util.js index 34becccec6..3d8871b6ac 100644 --- a/src/components/Workflow/workflow.util.js +++ b/src/components/Workflow/workflow.util.js @@ -19,13 +19,24 @@ such restriction. */ import { cloneDeep, forEach, isEmpty, set } from 'lodash' -import { page } from '../Jobs/jobs.util' +import { + BG_TASK_FAILED, + BG_TASK_SUCCEEDED, + isBackgroundTaskRunning, + pollTask +} from '../../utils/poll.util' import { DETAILS_OVERVIEW_TAB, JOBS_MONITORING_PAGE, JOBS_MONITORING_WORKFLOWS_TAB, WORKFLOW_TYPE_SKIPPED } from '../../constants' +import projectsIguazioApi from '../../api/projects-iguazio-api' +import tasksApi from '../../api/tasks-api' +import workflowsApi from '../../api/workflow-api' +import { page } from '../Jobs/jobs.util' +import { setAccessibleProjectsMap } from '../../reducers/projectReducer' +import { setNotification } from 'igz-controls/reducers/notificationReducer' const DAG_WORFLOW_STEP = 'DAG' const SKIPPED_PHASE = 'Skipped' @@ -241,3 +252,96 @@ export const parseWorkflow = workflow => { return newWorkflow } + +export const handleTerminateWorkflow = async (job, dispatch) => { + try { + const response = await workflowsApi.terminateWorkflow(job.project, job.id) + const { data } = response + + if (!isBackgroundTaskRunning(response)) { + dispatch( + setNotification({ + status: 400, + id: Math.random(), + message: `Workflow "${job.name} was not terminated since it already reached its end state` + }) + ) + return + } + + const taskId = data.metadata.name + + const pollMethod = () => tasksApi.getProjectBackgroundTask(job.project, taskId) + + const isDone = task => { + const state = task?.data?.status?.state + return [BG_TASK_SUCCEEDED, BG_TASK_FAILED].includes(state) + } + + const finalResult = await pollTask(pollMethod, isDone) + const finalState = finalResult?.data?.status?.state + + const success = finalState === BG_TASK_SUCCEEDED + + dispatch( + setNotification({ + status: success ? 200 : 400, + id: Math.random(), + message: success + ? `A request to terminate workflow "${job.name}" was issued` + : `Workflow "${job.name}" was not terminated because it already reached its end state` + }) + ) + } catch { + dispatch( + setNotification({ + status: 400, + id: Math.random(), + message: `Workflow "${job.name} was not terminated since it already reached its end state` + }) + ) + } +} + +export const fetchMissingProjectsPermissions = async (projectNames, currentMap, dispatch) => { + const uniqueProjects = [...new Set(projectNames)] + const missingProjects = uniqueProjects.filter(projectName => !(projectName in currentMap)) + if (missingProjects.length === 0) return + + const newMap = Object.fromEntries( + await Promise.all( + missingProjects.map(async projectName => { + try { + await projectsIguazioApi.getProjectOwnerVisibility(projectName) + return [projectName, true] + } catch { + try { + await projectsIguazioApi.getProjectWorkflowsUpdateAuthorization(projectName) + return [projectName, true] + } catch { + return [projectName, false] + } + } + }) + ) + ) + + const mergedMap = { ...currentMap, ...newMap } + dispatch(setAccessibleProjectsMap(mergedMap)) +} + +export const fetchMissingProjectPermission = async (projectName, currentMap, dispatch) => { + if (projectName in currentMap) return + + const hasPermission = await projectsIguazioApi + .getProjectOwnerVisibility(projectName) + .then(() => true) + .catch(() => + projectsIguazioApi + .getProjectWorkflowsUpdateAuthorization(projectName) + .then(() => true) + .catch(() => false) + ) + + dispatch(setAccessibleProjectsMap({ [projectName]: hasPermission })) +} diff --git a/src/constants.js b/src/constants.js index a03e10ffc6..17c3761e3e 100644 --- a/src/constants.js +++ b/src/constants.js @@ -34,13 +34,6 @@ export const V3IO_INPUT_PATH_SCHEME = 'v3io:///' export const TAG_LATEST = 'latest' export const TAG_NA = 'na' -export const DENSITY_DENSE = 'dense' -export const DENSITY_NORMAL = 'normal' -export const DENSITY_MEDIUM = 'medium' -export const DENSITY_CHUNKY = 'chunky' - -export const FULL_VIEW_MODE = 'full' - export const LARGE_REQUEST_CANCELED = 'Large request canceled' export const REQUEST_CANCELED = 'Request canceled' export const DEFAULT_ABORT_MSG = 'canceled' @@ -53,14 +46,20 @@ export const CANCEL_REQUEST_TIMEOUT = 120000 export const PROJECT_ONLINE_STATUS = 'online' +export const ABORTED_STATE = 'aborted' +export const ABORTING_STATE = 'aborting' +export const COMPLETED_STATE = 'completed' export const ERROR_STATE = 'error' export const FAIL_STATE = 'fail' export const FAILED_STATE = 'failed' export const PENDING_STATE = 'pending' +export const PENDING_RETRY_STATE = 'pendingRetry' +export const RUNNING_STATE = 'running' +export const SUCCEEDED_STATE = 'succeeded' +export const TERMINATING_STATE = 'terminating' +export const UNHEALTHY_STATE = 'unhealthy' export const UNKNOWN_STATE = 'unknown' -export const VIEW_SEARCH_PARAMETER = 'view' - /*=========== PAGINATION =============*/ export const BE_PAGE = 'bePage' @@ -135,6 +134,8 @@ export const MONITORING_APP_PAGE = 'monitoring-app' export const DOCUMENTS_PAGE = 'documents' export const LLM_PROMPTS_PAGE = 'llm-prompts' +export const PROMPT_TAB = 'prompt' +export const ARGUMENTS_TAB = 'arguments' export const PROJECT_MONITOR = 'monitor' @@ -282,16 +283,21 @@ export const FUNCTION_FAILED_TO_DELETE_STATE = 'failedToDelete' export const FUNCTION_ERROR_STATE = 'error' export const FUNCTION_INITIALIZED_STATE = 'initialized' export const FUNCTION_READY_STATE = 'ready' -export const FUNCTION_PENDINDG_STATE = 'pending' +export const FUNCTION_PENDING_STATE = 'pending' export const FUNCTION_RUNNING_STATE = 'running' export const FUNCTION_DEFAULT_HANDLER = 'handler' export const FUNCTION_RUN_KINDS = [FUNCTION_TYPE_JOB] export const FUNCTION_FILTERS = 'FUNCTION_FILTERS' +/*=========== PIPELINES =============*/ + +export const MODEL_RUNNER_STEP_KIND = 'model_runner' + /*=========== ARTIFACTS =============*/ export const ARTIFACTS_TAB = 'artifacts' export const ARTIFACT_PREVIEW_TABLE_ROW_LIMIT = 100 +export const LLM_PROMPT_TITLE = 'LLM prompt' /*=========== DETAILS =============*/ @@ -317,6 +323,8 @@ export const DETAILS_RESULTS_TAB = 'results' export const DETAILS_RETURNED_FEATURES_TAB = 'returned-features' export const DETAILS_STATISTICS_TAB = 'statistics' export const DETAILS_TRANSFORMATIONS_TAB = 'transformations' +export const DETAILS_PROMPT_TEMPLATE_TAB = 'prompt-template' +export const DETAILS_INVOCATION_CONFIGURATION_TAB = 'invocation-configuration' export const FETCH_MODEL_FEATURE_VECTOR_BEGIN = 'FETCH_MODEL_FEATURE_VECTOR_BEGIN' export const FETCH_MODEL_FEATURE_VECTOR_FAILURE = 'FETCH_MODEL_FEATURE_VECTOR_FAILURE' export const FETCH_MODEL_FEATURE_VECTOR_SUCCESS = 'FETCH_MODEL_FEATURE_VECTOR_SUCCESS' @@ -354,10 +362,6 @@ export const KEY_CODES = { /*=========== TABLE =============*/ export const TABLE_CONTAINER = 'table-container' -export const MAIN_TABLE_ID = 'main-table' -export const MAIN_TABLE_BODY_ID = 'main-table-body' - -export const BUTTON_COPY_URI_CELL_TYPE = 'buttonCopyURI' /*=========== FILTERS =============*/ @@ -377,13 +381,18 @@ export const GROUP_BY_FILTER = 'groupBy' export const ITERATIONS_FILTER = 'iter' export const LABELS_FILTER = 'labels' export const NAME_FILTER = 'name' +export const ME_MODE_FILTER = 'me-mode' export const DATES_FILTER = 'dates' export const PROJECT_FILTER = 'project' +export const REAL_TIME_FILTER = 'realTime' +export const BATCH_FILTER = 'batch' export const TYPE_FILTER = 'type' export const SHOW_UNTAGGED_FILTER = 'showUntagged' export const SORT_BY = 'sortBy' export const STATUS_FILTER = 'state' export const TAG_FILTER = 'tag' +export const MODEL_NAME_FILTER = 'model-name' +export const MODEL_TAG_FILTER = 'model-tag' export const AUTO_REFRESH_ID = 'auto-refresh' export const INTERNAL_AUTO_REFRESH_ID = 'internal-auto-refresh' export const AUTO_REFRESH = 'Auto Refresh' @@ -423,6 +432,7 @@ export const PANEL_DEFAULT_ACCESS_KEY = '$generate' /*=========== ML REACT FLOW =============*/ export const ML_NODE = 'ml-node' +export const ML_MODEL_RUNNER_NODE = 'ml-model-runner-node' export const INPUT_NODE = 'input-node' export const OUTPUT_NODE = 'output-node' @@ -501,3 +511,8 @@ export const HTTPS = 'https://' /*========= METRICS TYPES =============*/ export const METRIC_TYPE = 'metric' export const RESULT_TYPE = 'result' + +/*========= GENERAL TEXT =============*/ + +export const COUNTERS_GENERAL_MESSAGE = + 'Counters use a caching mechanism, and are not auto-refreshed.' diff --git a/src/elements/ActionMenuItem/ActionsMenuItem.jsx b/src/elements/ActionMenuItem/ActionsMenuItem.jsx deleted file mode 100644 index fe10a95f5e..0000000000 --- a/src/elements/ActionMenuItem/ActionsMenuItem.jsx +++ /dev/null @@ -1,83 +0,0 @@ -/* -Copyright 2019 Iguazio Systems Ltd. - -Licensed under the Apache License, Version 2.0 (the "License") with -an addition restriction as set forth herein. You may not use this -file except in compliance with the License. You may obtain a copy of -the License at http://www.apache.org/licenses/LICENSE-2.0. - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -implied. See the License for the specific language governing -permissions and limitations under the License. - -In addition, you may not use the software for any purposes that are -illegal under applicable law, and the grant of the foregoing license -under the Apache 2.0 license is conditioned upon your compliance with -such restriction. -*/ -import React from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import { useDispatch, useSelector } from 'react-redux' - -import { Tooltip, TextTooltipTemplate } from 'igz-controls/components' -import { performDetailsActionHelper } from '../../components/Details/details.util' - -import './actionsMenuItem.scss' - -const ActionsMenuItem = ({ dataItem = {}, index, isIconDisplayed, menuItem }) => { - const dispatch = useDispatch() - const changes = useSelector(store => store.detailsStore.changes) - - const iconClassNames = classnames( - 'actions-menu__icon', - isIconDisplayed && 'actions-menu__icon_visible' - ) - const menuClassNames = classnames( - 'actions-menu__option', - menuItem.className && `actions-menu__option_${menuItem.className}`, - menuItem.disabled && 'actions-menu__option_disabled' - ) - - const handleActionClick = async () => { - if (!menuItem.disabled) { - if (menuItem.allowLeaveWarning) { - const actionCanBePerformed = await performDetailsActionHelper(changes, dispatch) - - if (actionCanBePerformed) { - menuItem.onClick(dataItem) - } - } else { - menuItem.onClick(dataItem) - } - } - } - - return ( -
  • - } - hidden={!menuItem.tooltip} - key={menuItem.label} - > - {menuItem.icon} - {menuItem.label} - -
  • - ) -} - -ActionsMenuItem.propTypes = { - dataItem: PropTypes.oneOfType([PropTypes.object, PropTypes.string]), - index: PropTypes.number.isRequired, - isIconDisplayed: PropTypes.bool.isRequired, - menuItem: PropTypes.object.isRequired -} - -export default ActionsMenuItem diff --git a/src/elements/ActionMenuItem/actionsMenuItem.scss b/src/elements/ActionMenuItem/actionsMenuItem.scss deleted file mode 100644 index 53fd421504..0000000000 --- a/src/elements/ActionMenuItem/actionsMenuItem.scss +++ /dev/null @@ -1,66 +0,0 @@ -@use 'igz-controls/scss/shadows'; -@use 'igz-controls/scss/colors'; - -.actions-menu { - &__icon { - display: none; - align-items: center; - justify-content: center; - width: 25px; - height: 25px; - margin-right: 5px; - - svg { - path { - &:first-child { - fill: colors.$topaz; - } - } - } - - &_visible { - display: flex; - } - } - - &__option { - padding: 10px; - color: colors.$primary; - cursor: pointer; - - &:hover { - background-color: colors.$alabaster; - } - - &_danger { - color: colors.$amaranth; - - svg { - path:first-child { - fill: colors.$amaranth; - } - } - } - - &_disabled { - color: colors.$spunPearl; - cursor: not-allowed; - - .actions-menu__icon { - svg { - path:first-child { - fill: rgba(colors.$black, 0.2); - } - } - } - } - - & > * { - display: flex; - flex: 1; - align-items: center; - justify-content: flex-start; - width: 100%; - } - } -} diff --git a/src/elements/AddArtifactTagPopUp/AddArtifactTagPopUp.jsx b/src/elements/AddArtifactTagPopUp/AddArtifactTagPopUp.jsx index 403534164d..8358f79f2d 100644 --- a/src/elements/AddArtifactTagPopUp/AddArtifactTagPopUp.jsx +++ b/src/elements/AddArtifactTagPopUp/AddArtifactTagPopUp.jsx @@ -17,32 +17,31 @@ illegal under applicable law, and the grant of the foregoing license under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ -import React, { useEffect, useState } from 'react' +import React, { useState } from 'react' import PropTypes from 'prop-types' import { useDispatch } from 'react-redux' import { useLocation } from 'react-router-dom' import { Form } from 'react-final-form' import { createForm } from 'final-form' -import { Button, FormInput, Modal } from 'igz-controls/components' -import Loader from '../../common/Loader/Loader' +import { Button, FormInput, Modal, Loader } from 'igz-controls/components' import { DATASET_TYPE, MODEL_TYPE, TAG_LATEST } from '../../constants' import { PRIMARY_BUTTON, TERTIARY_BUTTON } from 'igz-controls/constants' -import { addTag, fetchAllArtifactKindsTags } from '../../reducers/artifactsReducer' +import { addTag } from '../../reducers/artifactsReducer' import { getValidationRules } from 'igz-controls/utils/validation.util' -import { setNotification } from '../../reducers/notificationReducer' -import { showErrorNotification } from '../../utils/notifications.util' +import { setNotification } from 'igz-controls/reducers/notificationReducer' +import { showErrorNotification } from 'igz-controls/utils/notification.util' import { useModalBlockHistory } from '../../hooks/useModalBlockHistory.hook' import { isSubmitDisabled } from 'igz-controls/utils/form.util' +import { processActionAfterTagUniquesValidation } from '../../utils/artifacts.util' const AddArtifactTagPopUp = ({ artifact, isOpen, onAddTag = () => {}, onResolve, projectName }) => { const dispatch = useDispatch() const [initialValues] = useState({ artifactTag: '' }) - const [artifactTags, setArtifactTags] = useState([]) - const [isLoading, setIsLoading] = useState(true) + const [isLoading, setIsLoading] = useState(false) const formRef = React.useRef( createForm({ @@ -73,7 +72,9 @@ const AddArtifactTagPopUp = ({ artifact, isOpen, onAddTag = () => {}, onResolve, } } - dispatch(addTag(addTagArgs)) + resolveModal() + + return dispatch(addTag(addTagArgs)) .unwrap() .then(response => { dispatch( @@ -90,8 +91,20 @@ const AddArtifactTagPopUp = ({ artifact, isOpen, onAddTag = () => {}, onResolve, addArtifactTag(values) ) }) + } - resolveModal() + const addArtifactTagHandler = values => { + return processActionAfterTagUniquesValidation({ + tag: values.artifactTag, + artifact, + projectName, + dispatch, + actionCallback: () => addArtifactTag(values), + getCustomErrorMsg: () => 'Failed to add a tag', + onErrorCallback: resolveModal, + showLoader: () => setIsLoading(true), + hideLoader: () => setIsLoading(false) + }) } const getModalActions = formState => { @@ -112,33 +125,8 @@ const AddArtifactTagPopUp = ({ artifact, isOpen, onAddTag = () => {}, onResolve, return actions.map((action, index) =>
    +
    + ) +} + +DetailsHeaderContainer.propTypes = { + actionButton: ACTION_BUTTON, + actionsMenu: ACTIONS_MENU.isRequired, + applyChanges: PropTypes.func.isRequired, + applyChangesRef: PropTypes.object.isRequired, + cancelChanges: PropTypes.func.isRequired, + commonDetailsStore: PropTypes.object.isRequired, + getCloseDetailsLink: PropTypes.func, + getDefaultCloseDetailsLink: PropTypes.func.isRequired, + handleCancelClick: PropTypes.func.isRequired, + handleRefresh: PropTypes.func, + headerRef: PropTypes.object.isRequired, + isDetailsPopUp: PropTypes.bool, + isDetailsScreen: PropTypes.bool.isRequired, + location: PropTypes.object.isRequired, + navigate: PropTypes.func.isRequired, + pageData: PropTypes.object.isRequired, + params: PropTypes.object.isRequired, + renderCustomElements: PropTypes.func, + renderStatus: PropTypes.func, + renderTitle: PropTypes.func.isRequired, + selectedItem: PropTypes.object.isRequired, + showAllVersions: PropTypes.func, + tab: PropTypes.string, + viewMode: PropTypes.string, + withActionMenu: PropTypes.bool, + withToggleViewBtn: PropTypes.bool +} + +export const useDetailsHeader = ({ handleCancel, handleShowWarning, isDetailsPopUp, pageData }) => { + const commonDetailsStore = useSelector(store => store.commonDetailsStore) + const params = useParams() + const navigate = useNavigate() + const viewMode = getViewMode(window.location.search) + const { actionButton, withToggleViewBtn, showAllVersions } = pageData.details + const headerRef = useRef() + const location = useLocation() + const dispatch = useDispatch() + + const handleBackClick = useCallback(() => { + if (commonDetailsStore.changes.counter > 0) { + handleShowWarning(true) + } else if (handleCancel) { + handleCancel() + } + }, [commonDetailsStore.changes.counter, handleCancel, handleShowWarning]) + + const handleCancelClick = useCallback(() => { + if (handleCancel && (commonDetailsStore.changes.counter === 0 || isDetailsPopUp)) { + handleCancel() + } + }, [commonDetailsStore.changes.counter, handleCancel, isDetailsPopUp]) + + return { + DetailsHeaderContainer, + actionButton, + commonDetailsStore, + dispatch, + handleBackClick, + handleCancelClick, + headerRef, + location, + navigate, + params, + showAllVersions, + viewMode, + withToggleViewBtn + } +} diff --git a/src/hooks/useFiltersFromSearchParams.hook.js b/src/hooks/useFiltersFromSearchParams.hook.js index 6df956c89d..c67611142a 100644 --- a/src/hooks/useFiltersFromSearchParams.hook.js +++ b/src/hooks/useFiltersFromSearchParams.hook.js @@ -18,7 +18,7 @@ under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ import { useMemo } from 'react' -import { mapValues, isNil } from 'lodash' +import { mapValues, isNil, pickBy } from 'lodash' import { DATES_FILTER, ITERATIONS_FILTER, @@ -37,12 +37,15 @@ const defaultParamsParsingCallback = (_, value) => value const getFiltersFromSearchParams = (filtersConfig, searchParams, paramsParsingCallback) => { if (!filtersConfig) return {} - // todo add in 1.10.0 pickBy(filtersConfig, (configValue) => !configValue.) and fix all error where we use hidden configs - return mapValues(filtersConfig, (filterConfig, filterName) => { + const filtersConfigToApply = pickBy( + filtersConfig, + config => !config.hidden || config.applyHidden + ) + + return mapValues(filtersConfigToApply, (filterConfig, filterName) => { const searchParamValue = searchParams.get(filterName)?.trim?.() - // todo remove '|| filterConfig.hidden' after fix above - if (isNil(searchParamValue) || filterConfig.hidden) return filterConfig.initialValue + if (isNil(searchParamValue)) return filterConfig.initialValue let parsedValue = paramsParsingCallback(filterName, searchParamValue) diff --git a/src/hooks/useJobsPageData.js b/src/hooks/useJobsPageData.js index 6499f0d44a..8967b1aa16 100644 --- a/src/hooks/useJobsPageData.js +++ b/src/hooks/useJobsPageData.js @@ -17,7 +17,7 @@ illegal under applicable law, and the grant of the foregoing license under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ -import { useCallback, useMemo, useRef, useState } from 'react' +import { useCallback, useEffect, useMemo, useRef, useState } from 'react' import { useLocation, useParams } from 'react-router-dom' import { useDispatch, useSelector } from 'react-redux' import { isEmpty } from 'lodash' @@ -25,21 +25,22 @@ import { isEmpty } from 'lodash' import { monitorJob, pollAbortingJobs, rerunJob } from '../components/Jobs/jobs.util' import { - BE_PAGE, - BE_PAGE_SIZE, - FILTER_ALL_ITEMS, - GROUP_BY_WORKFLOW, - JOBS_MONITORING_JOBS_TAB, - JOBS_MONITORING_PAGE, - MONITOR_JOBS_TAB, - SCHEDULE_TAB + ABORTING_STATE, + BE_PAGE, + BE_PAGE_SIZE, + FILTER_ALL_ITEMS, + GROUP_BY_WORKFLOW, + JOBS_MONITORING_JOBS_TAB, + JOBS_MONITORING_PAGE, + MONITOR_JOBS_TAB, + SCHEDULE_TAB } from '../constants' import { usePagination } from './usePagination.hook' import { parseJob } from '../utils/parseJob' import { fetchAllJobRuns, fetchJobs, fetchScheduledJobs } from '../reducers/jobReducer' import { fetchWorkflows } from '../reducers/workflowReducer' import { useFiltersFromSearchParams } from './useFiltersFromSearchParams.hook' -import { getSavedSearchParams } from '../utils/filter.util' +import { getSavedSearchParams } from 'igz-controls/utils/filter.util' import { useRefreshAfterDelete } from './useRefreshAfterDelete.hook' export const useJobsPageData = (initialTabData, selectedTab) => { @@ -61,6 +62,7 @@ export const useJobsPageData = (initialTabData, selectedTab) => { const location = useLocation() const appStore = useSelector(store => store.appStore) const lastCheckedJobIdRef = useRef(null) + const refreshJobsRef = useRef() const historyBackLink = useMemo(() => { const queryParams = getSavedSearchParams(location.search) @@ -142,7 +144,7 @@ export const useJobsPageData = (initialTabData, selectedTab) => { if (response?.runs) { const parsedJobs = response.runs.map(job => parseJob(job)) const responseAbortingJobs = parsedJobs.reduce((acc, job) => { - if (job.state.value === 'aborting' && job.abortTaskId) { + if (job.state.value === ABORTING_STATE && job.abortTaskId) { acc[job.abortTaskId] = { uid: job.uid, name: job.name @@ -158,7 +160,7 @@ export const useJobsPageData = (initialTabData, selectedTab) => { filters.project?.toLowerCase?.() || params.projectName || '*', abortJobRef, responseAbortingJobs, - () => refreshJobs(filters), + () => refreshJobsRef.current?.(filters), dispatch ) } @@ -191,12 +193,16 @@ export const useJobsPageData = (initialTabData, selectedTab) => { [dispatch, params.jobName, params.projectName, terminateAbortTasksPolling] ) + useEffect(() => { + refreshJobsRef.current = refreshJobs + }, [refreshJobs]) + const refreshScheduled = useCallback( filters => { setScheduledJobs([]) abortControllerRef.current = new AbortController() - dispatch( + return dispatch( fetchScheduledJobs({ project: filters.project ? filters.project.toLowerCase() : params.projectName || '*', filters, @@ -215,7 +221,7 @@ export const useJobsPageData = (initialTabData, selectedTab) => { .map(job => parseJob(job, SCHEDULE_TAB)) .filter(job => { return ( - !filters.type || filters.type === FILTER_ALL_ITEMS || job.type === filters.type + !filters.type || filters.type === FILTER_ALL_ITEMS || job.type === filters.type || (Array.isArray(filters.type) && filters.type.includes(job.type) || filters.type.includes(FILTER_ALL_ITEMS)) ) }) diff --git a/src/hooks/useModalBlockHistory.hook.js b/src/hooks/useModalBlockHistory.hook.js index 7d903db25d..765fa8b112 100644 --- a/src/hooks/useModalBlockHistory.hook.js +++ b/src/hooks/useModalBlockHistory.hook.js @@ -24,17 +24,20 @@ import { defaultCloseModalHandler } from '../utils/defaultCloseModalHandler' import { areFormValuesChanged } from 'igz-controls/utils/form.util' export const useModalBlockHistory = (closeModal, form) => { - const shouldBlock = useCallback(({ currentLocation, nextLocation }) => { - const { initialValues, values } = form.getState() + const shouldBlock = useCallback( + ({ currentLocation, nextLocation }) => { + const { initialValues, values } = form.getState() - const isFormDirty = areFormValuesChanged(initialValues, values) + const isFormDirty = areFormValuesChanged(initialValues, values) - if (!isFormDirty && currentLocation.pathname !== nextLocation.pathname) { - closeModal() - } + if (!isFormDirty && currentLocation.pathname !== nextLocation.pathname) { + closeModal() + } - return isFormDirty && currentLocation.pathname !== nextLocation.pathname - }, [closeModal, form]) + return isFormDirty && currentLocation.pathname !== nextLocation.pathname + }, + [closeModal, form] + ) let blocker = useBlocker(shouldBlock) diff --git a/src/hooks/useRefreshAlerts.hook.js b/src/hooks/useRefreshAlerts.hook.js index 4836fb319c..46e145b7fd 100644 --- a/src/hooks/useRefreshAlerts.hook.js +++ b/src/hooks/useRefreshAlerts.hook.js @@ -90,7 +90,9 @@ export const useRefreshAlerts = (filters, isAlertsPage) => { ) useEffect(() => { - !isAlertsPage && refreshAlerts(filters) + queueMicrotask(() => { + !isAlertsPage && refreshAlerts(filters) + }) }, [isAlertsPage, refreshAlerts, filters]) return { diff --git a/src/hooks/useSortTable.hook.jsx b/src/hooks/useSortTable.hook.jsx index ea87085c13..34523e8be0 100644 --- a/src/hooks/useSortTable.hook.jsx +++ b/src/hooks/useSortTable.hook.jsx @@ -17,8 +17,8 @@ illegal under applicable law, and the grant of the foregoing license under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ -import { useCallback, useEffect, useState, useMemo } from 'react' -import { isEmpty, isNumber, orderBy, isEqual } from 'lodash' +import { useCallback, useEffect, useMemo, useState } from 'react' +import { isEmpty, isEqual, isNumber, orderBy } from 'lodash' import ArrowIcon from 'igz-controls/images/back-arrow.svg?react' @@ -38,7 +38,9 @@ export const useSortTable = ({ headers, content, sortConfig = {} }) => { useEffect(() => { if (!isEqual(config, sortConfig)) { - setConfig(sortConfig) + queueMicrotask(() => { + setConfig(sortConfig) + }) } }, [sortConfig, config]) @@ -87,16 +89,13 @@ export const useSortTable = ({ headers, content, sortConfig = {} }) => { ) const isSortableByIndex = useCallback(() => { - let isSortByIndex = - isNumber(allowSortBy) || isNumber(excludeSortBy) - ? true - : Array.isArray(allowSortBy) - ? allowSortBy.every(allowedIndex => isNumber(allowedIndex)) - : Array.isArray(excludeSortBy) - ? excludeSortBy.every(allowedIndex => isNumber(allowedIndex)) - : false - - return isSortByIndex + return isNumber(allowSortBy) || isNumber(excludeSortBy) + ? true + : Array.isArray(allowSortBy) + ? allowSortBy.every(allowedIndex => isNumber(allowedIndex)) + : Array.isArray(excludeSortBy) + ? excludeSortBy.every(allowedIndex => isNumber(allowedIndex)) + : false }, [allowSortBy, excludeSortBy]) const isSortable = useCallback( @@ -202,28 +201,32 @@ export const useSortTable = ({ headers, content, sortConfig = {} }) => { } useEffect(() => { - if (direction && selectedColumnName) { - sortTable(selectedColumnName, direction) - } else if (defaultSortBy !== null && (!direction || defaultDirection) && content.length > 0) { - sortTable( - selectedColumnName - ? selectedColumnName - : isNumber(defaultSortBy) - ? headers[defaultSortBy].headerId - : defaultSortBy, - defaultDirection - ) - } else { - setSortedTableContent(content) - } + queueMicrotask(() => { + if (direction && selectedColumnName) { + sortTable(selectedColumnName, direction) + } else if (defaultSortBy !== null && (!direction || defaultDirection) && content.length > 0) { + sortTable( + selectedColumnName + ? selectedColumnName + : isNumber(defaultSortBy) + ? headers[defaultSortBy].headerId + : defaultSortBy, + defaultDirection + ) + } else { + setSortedTableContent(content) + } + }) }, [content, defaultDirection, defaultSortBy, direction, headers, selectedColumnName, sortTable]) useEffect(() => { - if (headers && headers.length > 0 && (excludeSortBy || allowSortBy)) { - const header = getSortableHeaders() + queueMicrotask(() => { + if (headers && headers.length > 0 && (excludeSortBy || allowSortBy)) { + const header = getSortableHeaders() - setSortedTableHeaders(header) - } + setSortedTableHeaders(header) + } + }) }, [allowSortBy, excludeSortBy, getSortableHeaders, headers]) return { sortTable, selectedColumnName, getSortingIcon, sortedTableContent, sortedTableHeaders } diff --git a/src/hooks/useVirtualization.hook.js b/src/hooks/useVirtualization.hook.js index 3f8c42d63a..6882c00ef4 100644 --- a/src/hooks/useVirtualization.hook.js +++ b/src/hooks/useVirtualization.hook.js @@ -19,7 +19,7 @@ such restriction. */ import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react' import { isEmpty, isEqual, sum, throttle } from 'lodash' -import { MAIN_TABLE_ID, MAIN_TABLE_BODY_ID } from '../constants' +import { MAIN_TABLE_ID, MAIN_TABLE_BODY_ID } from 'igz-controls/constants' const HIDDEN_RENDER_ITEMS_LENGTH = 5 const virtualizationConfigInitialState = { @@ -245,7 +245,9 @@ export const useVirtualization = ({ useLayoutEffect(() => { if (isEmpty(rowsData.content) && !isEqual(rowsSizes, rowsSizesLocal)) { - setRowsSizesLocal(rowsSizes) + queueMicrotask(() => { + setRowsSizesLocal(rowsSizes) + }) } }, [rowsSizesLocal, rowsData, rowsSizes]) @@ -260,7 +262,9 @@ export const useVirtualization = ({ ) if (!isEqual(rowsSizesLocal, newRowsSizes)) { - setRowsSizesLocal(newRowsSizes) + queueMicrotask(() => { + setRowsSizesLocal(newRowsSizes) + }) } } }, [ @@ -355,7 +359,9 @@ export const useVirtualization = ({ tableElement.addEventListener('scroll', calculateVirtualizationConfig) window.addEventListener('resize', calculateVirtualizationConfig) } else { - setVirtualizationConfig(virtualizationConfigInitialState) + queueMicrotask(() => { + setVirtualizationConfig(virtualizationConfigInitialState) + }) } return () => { diff --git a/src/layout/Header/Header.jsx b/src/layout/Header/Header.jsx index 86e7c1de81..de57c938ee 100644 --- a/src/layout/Header/Header.jsx +++ b/src/layout/Header/Header.jsx @@ -56,7 +56,7 @@ const Header = () => { target="_blank" rel="noopener noreferrer" > - Function Hub + Function hub * { diff --git a/src/layout/Navbar/Navbar.jsx b/src/layout/Navbar/Navbar.jsx index db383d8b64..8451c1579a 100644 --- a/src/layout/Navbar/Navbar.jsx +++ b/src/layout/Navbar/Navbar.jsx @@ -27,7 +27,6 @@ import { RoundedIcon } from 'igz-controls/components' import { ALERTS_PAGE_PATH, NAVBAR_WIDTH_CLOSED, NAVBAR_WIDTH_OPENED } from '../../constants' import localStorageService from '../../utils/localStorageService' import { getLinks } from './navbar.util' -import { useMode } from '../../hooks/mode.hook' import Alerts from 'igz-controls/images/navbar/alerts-icon.svg?react' import PinIcon from 'igz-controls/images/pin-icon.svg?react' @@ -41,7 +40,6 @@ const Navbar = ({ projectName, setIsNavbarPinned }) => { const [isPinned, setIsPinned] = useState( localStorageService.getStorageValue('mlrunUi.navbarStatic', false) === 'true' ) - const { isDemoMode } = useMode() const navbarClasses = classNames( 'navbar', @@ -55,8 +53,8 @@ const Navbar = ({ projectName, setIsNavbarPinned }) => { } const links = useMemo(() => { - return projectName ? getLinks(projectName, isDemoMode) : [] - }, [isDemoMode, projectName]) + return projectName ? getLinks(projectName) : [] + }, [projectName]) const handlePinClick = () => { setIsPinned(prevIsPinned => { diff --git a/src/layout/Navbar/Navbar.scss b/src/layout/Navbar/Navbar.scss index 408c356510..1c6da5e17d 100644 --- a/src/layout/Navbar/Navbar.scss +++ b/src/layout/Navbar/Navbar.scss @@ -3,14 +3,14 @@ @use 'igz-controls/scss/borders'; .navbar { - display: flex; - flex-grow: 1; - flex-shrink: 0; - flex-flow: column nowrap; position: absolute; top: 0; left: 0; z-index: 11; + display: flex; + flex-flow: column nowrap; + flex-grow: 1; + flex-shrink: 0; height: 100%; background-color: colors.$wildSand; border-right: borders.$tertiaryBorder; @@ -27,8 +27,8 @@ } .navbar__pin-icon { - opacity: 1; visibility: visible; + opacity: 1; } } @@ -47,17 +47,18 @@ &__additional { display: flex; flex: 2 0 auto; + overflow: hidden; .navbar-links { margin-bottom: 20px; &::before { - content: ''; display: block; width: 100%; height: 1px; - border-top: borders.$primaryBorder; margin-bottom: 10px; + border-top: borders.$primaryBorder; + content: ''; } } } @@ -75,8 +76,8 @@ display: flex; justify-content: flex-end; padding: 0.5rem; - opacity: 0; visibility: hidden; + opacity: 0; transition: all 0.3s ease-in-out; button { diff --git a/src/layout/Navbar/navbar.util.jsx b/src/layout/Navbar/navbar.util.jsx index 67a74a3d4c..ea71474e0c 100644 --- a/src/layout/Navbar/navbar.util.jsx +++ b/src/layout/Navbar/navbar.util.jsx @@ -43,7 +43,7 @@ import ModelMonitoringIcon from 'igz-controls/images/navbar/model-monitoring.svg // import RTPiplinesIcon from 'igz-controls/images/timer-outline-icon.svg?react' -export const getLinks = (projectName, isDemoMode) => { +export const getLinks = projectName => { const pathname = `/projects/${projectName}` return [ @@ -57,7 +57,8 @@ export const getLinks = (projectName, isDemoMode) => { icon: , id: PROJECT_QUICK_ACTIONS_PAGE, label: 'Quick actions', - link: `${pathname}/${PROJECT_QUICK_ACTIONS_PAGE}` + link: `${pathname}/${PROJECT_QUICK_ACTIONS_PAGE}`, + hidden: true }, { icon: , @@ -81,8 +82,7 @@ export const getLinks = (projectName, isDemoMode) => { icon: , id: LLM_PROMPTS_PAGE, label: 'LLM prompts', - link: `${pathname}/${LLM_PROMPTS_PAGE}`, - hidden: !isDemoMode + link: `${pathname}/${LLM_PROMPTS_PAGE}` }, { icon: , @@ -100,8 +100,7 @@ export const getLinks = (projectName, isDemoMode) => { icon: , id: 'monitoring-app', label: 'Monitoring app', - link: `${pathname}/monitoring-app`, - hidden: !isDemoMode + link: `${pathname}/monitoring-app` }, { icon: , diff --git a/src/layout/Page/Page.jsx b/src/layout/Page/Page.jsx index 1f2b262b4f..1882191b79 100644 --- a/src/layout/Page/Page.jsx +++ b/src/layout/Page/Page.jsx @@ -27,7 +27,7 @@ import ModalContainer from 'react-modal-promise' import Navbar from '../Navbar/Navbar' import YamlModal from '../../common/YamlModal/YamlModal' -import Loader from '../../common/Loader/Loader' +import { Loader } from 'igz-controls/components' import { getTransitionEndEventName } from 'igz-controls/utils/common.util' import { fetchFrontendSpec, toggleYaml } from '../../reducers/appReducer' @@ -66,14 +66,20 @@ const Page = () => { useEffect(() => { if (projectsList.length === 0 && location.pathname !== '/projects') { - dispatch(fetchProjects({ params: { format: 'minimal' } })) + dispatch(fetchProjects({ params: { format: 'minimal' }, showNotification: false })) .unwrap() .then(projects => { isProjectValid(navigate, projects, projectName, dispatch) setProjectFetched(true) }) + .catch(() => { + setProjectFetched(true) + navigate('/projects') + }) } else { - setProjectFetched(true) + queueMicrotask(() => { + setProjectFetched(true) + }) } }, [dispatch, location.pathname, navigate, projectName, projectsList.length]) diff --git a/src/layout/Page/Page.scss b/src/layout/Page/Page.scss index 2222511699..390dc777d3 100644 --- a/src/layout/Page/Page.scss +++ b/src/layout/Page/Page.scss @@ -7,6 +7,7 @@ display: flex; justify-content: flex-end; width: 100%; + // transform: translateX(variables.$navbarTogglerWidth); transition: all 0.3s ease-in-out; } @@ -17,6 +18,6 @@ flex: 1; flex-flow: column nowrap; align-items: flex-start; - overflow: auto; width: 100%; + overflow: auto; } diff --git a/src/reducers/artifactsReducer.js b/src/reducers/artifactsReducer.js index 18670a58f5..513061bb83 100644 --- a/src/reducers/artifactsReducer.js +++ b/src/reducers/artifactsReducer.js @@ -70,7 +70,8 @@ const initialState = { content: {}, error: null, loading: false - } + }, + promptTemplate: [] }, error: null, files: { @@ -452,6 +453,12 @@ export const replaceTag = createAsyncThunk('replaceTag', ({ project, tag, data } export const updateArtifact = createAsyncThunk('updateArtifact', ({ project, data }) => { return artifactsApi.updateArtifact(project, data) }) +export const fetchLLMPromptTemplate = createAsyncThunk( + 'fetchLLMPromptTemplate', + ({ project, config }) => { + return artifactsApi.getArtifactPreview(project, config) + } +) const artifactsSlice = createSlice({ name: 'artifactsStore', @@ -512,6 +519,9 @@ const artifactsSlice = createSlice({ removePipelines(state) { state.pipelines.allData = initialState.pipelines.allData }, + removeLLMPromptTemplate(state) { + state.LLMPrompts.promptTemplate = initialState.LLMPrompts.promptTemplate + }, showArtifactsPreview(state, action) { state.preview = action.payload } @@ -537,6 +547,9 @@ const artifactsSlice = createSlice({ builder.addCase(updateArtifact.pending, showLoading) builder.addCase(updateArtifact.fulfilled, hideLoading) builder.addCase(updateArtifact.rejected, hideLoading) + builder.addCase(fetchLLMPromptTemplate.fulfilled, (state, action) => { + state.LLMPrompts.promptTemplate = action.payload.data + }) builder.addCase(deleteTag.pending, showLoading) builder.addCase(deleteTag.fulfilled, hideLoading) builder.addCase(deleteTag.rejected, hideLoading) @@ -723,7 +736,8 @@ export const { removeModel, removeModels, removeModelEndpoints, - removePipelines + removePipelines, + removeLLMPromptTemplate } = artifactsSlice.actions export default artifactsSlice.reducer diff --git a/src/reducers/detailsReducer.js b/src/reducers/detailsReducer.js index 7e2b2e6e76..1770702edd 100644 --- a/src/reducers/detailsReducer.js +++ b/src/reducers/detailsReducer.js @@ -31,27 +31,22 @@ import { TIME_FRAME_LIMITS } from '../utils/datePicker.util' import { largeResponseCatchHandler } from '../utils/largeResponseCatchHandler' const initialState = { - changes: { - counter: 0, - data: {} - }, dates: { value: DATE_FILTER_ANY_TIME, selectedOptionId: '', isPredefined: false }, - detailsPopUpInfoContent: {}, detailsJobPods: { loading: true, podsList: [], podsPending: [], podsTooltip: [] }, - editMode: false, error: null, - infoContent: {}, iteration: '', iterationOptions: [], + runAttempt: '0', + runAttemptOptions: [], loadingCounter: 0, modelFeatureVectorData: {}, pods: { @@ -60,8 +55,6 @@ const initialState = { podsPending: [], podsTooltip: [] }, - filtersWasHandled: false, - showWarning: false, metricsOptions: { all: [], lastSelected: [], @@ -105,13 +98,13 @@ export const fetchJobPods = createAsyncThunk('fetchJobPods', ({ project, uid, ki export const fetchModelEndpointMetrics = createAsyncThunk( 'fetchEndpointMetrics', - ({ project, uid }, thunkAPI) => { + ({ project, uid, applicationName = '' }, thunkAPI) => { return modelEndpointsApi .getModelEndpointMetrics(project, uid) .then(({ data = [] }) => { - const metrics = generateMetricsItems(data) + const metrics = generateMetricsItems(data, applicationName) - return { endpointUid: uid, metrics } + return { endpointUid: uid, metrics, applicationName } }) .catch(error => thunkAPI.rejectWithValue(error)) } @@ -159,51 +152,27 @@ const detailsStoreSlice = createSlice({ removeDetailsPods(state) { state.detailsJobPods = initialState.detailsJobPods }, - removeDetailsPopUpInfoContent(state) { - state.detailsPopUpInfoContent = {} - }, - removeInfoContent(state) { - state.infoContent = {} - }, removeModelFeatureVector(state) { state.modelFeatureVectorData = initialState.modelFeatureVectorData }, removePods(state) { state.pods = initialState.pods }, - resetChanges(state) { - state.changes = initialState.changes - }, - setChanges(state, action) { - state.changes = action.payload - }, - setChangesCounter(state, action) { - state.changes.counter = action.payload - }, - setChangesData(state, action) { - state.changes.data = action.payload - }, setDetailsDates(state, action) { state.dates = action.payload }, - setDetailsPopUpInfoContent(state, action) { - state.detailsPopUpInfoContent = action.payload - }, - setEditMode(state, action) { - state.editMode = action.payload - }, - setFiltersWasHandled(state, action) { - state.filtersWasHandled = action.payload - }, - setInfoContent(state, action) { - state.infoContent = action.payload - }, setIteration(state, action) { state.iteration = action.payload }, setIterationOption(state, action) { state.iterationOptions = action.payload }, + setRunAttempt(state, action) { + state.runAttempt = action.payload + }, + setRunAttemptOptions(state, action) { + state.runAttemptOptions = action.payload + }, setSelectedMetricsOptions(state, action) { state.metricsOptions = { ...state.metricsOptions, @@ -214,8 +183,19 @@ const detailsStoreSlice = createSlice({ } } }, - showWarning(state, action) { - state.showWarning = action.payload + increaseDetailsLoadingCounter(state) { + state.loadingCounter = state.loadingCounter + 1 + }, + decreaseDetailsLoadingCounter(state) { + state.loadingCounter = state.loadingCounter - 1 + }, + clearMetricsOptions(state) { + state.metricsOptions = { + all: [], + lastSelected: [], + preselected: [], + selectedByEndpoint: {} + } } }, extraReducers: builder => { @@ -307,23 +287,17 @@ const detailsStoreSlice = createSlice({ export const { removeDetailsPods, - removeDetailsPopUpInfoContent, - removeInfoContent, removeModelFeatureVector, removePods, - resetChanges, - setChanges, - setChangesCounter, - setChangesData, setDetailsDates, - setDetailsPopUpInfoContent, - setEditMode, - setFiltersWasHandled, - setInfoContent, setIteration, setIterationOption, + setRunAttempt, + setRunAttemptOptions, setSelectedMetricsOptions, - showWarning + increaseDetailsLoadingCounter, + decreaseDetailsLoadingCounter, + clearMetricsOptions } = detailsStoreSlice.actions export default detailsStoreSlice.reducer diff --git a/src/reducers/featureStoreReducer.js b/src/reducers/featureStoreReducer.js index 98ac108f81..2caaa43176 100644 --- a/src/reducers/featureStoreReducer.js +++ b/src/reducers/featureStoreReducer.js @@ -33,7 +33,7 @@ import { largeResponseCatchHandler } from '../utils/largeResponseCatchHandler' import { parseFeatureSets } from '../utils/parseFeatureSets' import { parseFeatureVectors } from '../utils/parseFeatureVectors' import { parseFeatures } from '../utils/parseFeatures' -import { showErrorNotification } from '../utils/notifications.util' +import { showErrorNotification } from 'igz-controls/utils/notification.util' const initialState = { error: null, @@ -124,7 +124,8 @@ export const createNewFeatureSet = createAsyncThunk( : error.message showErrorNotification(thunkAPI.dispatch, error, '', message) - thunkAPI.rejectWithValue(error) + + return thunkAPI.rejectWithValue(error) }) } ) @@ -181,7 +182,8 @@ export const fetchFeatureSets = createAsyncThunk( thunkAPI.dispatch, config?.ui?.setRequestErrorMessage ) - thunkAPI.rejectWithValue(error.message) + + return thunkAPI.rejectWithValue(error.message) }) } ) @@ -236,7 +238,8 @@ export const fetchFeatureVectors = createAsyncThunk( thunkAPI.dispatch, config?.ui?.setRequestErrorMessage ) - thunkAPI.rejectWithValue(error) + + return thunkAPI.rejectWithValue(error) } }) } @@ -268,7 +271,8 @@ export const fetchFeatureSetsTags = createAsyncThunk( ({ project, config }, thunkAPI) => { return featureStoreApi.fetchFeatureSetsTags(project, config).catch(error => { largeResponseCatchHandler(error, 'Failed to fetch tags', thunkAPI.dispatch) - thunkAPI.rejectWithValue(error) + + return thunkAPI.rejectWithValue(error) }) } ) @@ -277,7 +281,8 @@ export const fetchFeatureVectorsTags = createAsyncThunk( ({ project, config }, thunkAPI) => { return featureStoreApi.fetchFeatureVectorsTags(project, config).catch(error => { largeResponseCatchHandler(error, 'Failed to fetch tags', thunkAPI.dispatch) - thunkAPI.rejectWithValue(error) + + return thunkAPI.rejectWithValue(error) }) } ) @@ -296,7 +301,8 @@ export const startFeatureSetIngest = createAsyncThunk( : error.message showErrorNotification(thunkAPI.dispatch, error, '', message) - thunkAPI.rejectWithValue(message) + + return thunkAPI.rejectWithValue(message) }) } ) @@ -499,7 +505,7 @@ const featureStoreSlice = createSlice({ state.features.loading = true }) builder.addCase(fetchFeatures.rejected, (state, action) => { - state.features.loading = true + state.features.loading = false state.error = action.payload }) builder.addCase(fetchFeatures.fulfilled, (state, action) => { diff --git a/src/reducers/functionReducer.js b/src/reducers/functionReducer.js index 55c7b89d39..11aca61f73 100644 --- a/src/reducers/functionReducer.js +++ b/src/reducers/functionReducer.js @@ -24,7 +24,7 @@ import functionsApi from '../api/functions-api' import { hideLoading, showLoading } from './redux.util' import mlrunNuclioApi from '../api/mlrun-nuclio-api' import yaml from 'js-yaml' -import { showErrorNotification } from '../utils/notifications.util' +import { showErrorNotification } from 'igz-controls/utils/notification.util' import { largeResponseCatchHandler } from '../utils/largeResponseCatchHandler' import { generateCategories, generateHubCategories } from '../utils/generateTemplatesCategories' @@ -169,7 +169,7 @@ export const fetchFunctions = createAsyncThunk( thunkAPI.dispatch, setRequestErrorMessageLocal ) - thunkAPI.rejectWithValue(error.message) + return thunkAPI.rejectWithValue(error) }) } ) diff --git a/src/reducers/jobReducer.js b/src/reducers/jobReducer.js index d86387ec5e..4d0a98bccb 100644 --- a/src/reducers/jobReducer.js +++ b/src/reducers/jobReducer.js @@ -19,7 +19,7 @@ such restriction. */ import { createAsyncThunk, createSlice } from '@reduxjs/toolkit' import jobsApi from '../api/jobs-api' -import { hideLoading, showLoading } from './redux.util' +import { defaultRejectedHandler, hideLoading, showLoading } from './redux.util' import { get } from 'lodash' import { DATES_FILTER, @@ -31,7 +31,7 @@ import { } from '../constants' import { largeResponseCatchHandler } from '../utils/largeResponseCatchHandler' import functionsApi from '../api/functions-api' -import { showErrorNotification } from '../utils/notifications.util' +import { showErrorNotification } from 'igz-controls/utils/notification.util' import { getNewJobErrorMsg } from '../components/JobWizard/JobWizard.util' const initialState = { @@ -42,7 +42,7 @@ const initialState = { jobRuns: [], jobs: [], logs: { - loading: false, + loadingCounter: 0, error: null }, loading: false, @@ -140,8 +140,8 @@ export const deleteAllJobRuns = createAsyncThunk('deleteAllJobRuns', ({ project, export const deleteJob = createAsyncThunk('deleteJob', ({ project, job }) => { return jobsApi.deleteJob(project, job.uid) }) -export const editJob = createAsyncThunk('editJob', ({ postData, project }) => { - return jobsApi.editJob(postData, project) +export const editJob = createAsyncThunk('editJob', ({ postData, project }, thunkAPI) => { + return jobsApi.editJob(postData, project).catch(thunkAPI.rejectWithValue) }) export const fetchAllJobRuns = createAsyncThunk( 'fetchAllJobRuns', @@ -194,8 +194,8 @@ export const fetchJobFunctions = createAsyncThunk('fetchJobFunctions', ({ projec return res.data?.funcs }) }) -export const fetchJobLogs = createAsyncThunk('fetchJobLogs', ({ id, project }) => { - return jobsApi.getJobLogs(id, project).then(result => { +export const fetchJobLogs = createAsyncThunk('fetchJobLogs', ({ id, project, attempt, signal }) => { + return jobsApi.getJobLogs(id, project, attempt, signal).then(result => { return result }) }) @@ -382,15 +382,15 @@ const jobsSlice = createSlice({ state.jobLoadingCounter-- }) builder.addCase(fetchJobLogs.pending, state => { - state.logs.loading = true + state.logs.loadingCounter++ state.logs.error = null }) builder.addCase(fetchJobLogs.fulfilled, state => { state.logs.error = null - state.logs.loading = false + state.logs.loadingCounter-- }) builder.addCase(fetchJobLogs.rejected, (state, action) => { - state.logs.loading = false + state.logs.loadingCounter-- state.logs.error = action.payload }) builder.addCase(fetchJobs.pending, showLoading) @@ -415,9 +415,9 @@ const jobsSlice = createSlice({ state.scheduled = [] state.loading = false }) - builder.addCase(removeScheduledJob.rejected, (state, action) => { - state.error = action.payload - }) + builder.addCase(removeScheduledJob.pending, showLoading) + builder.addCase(removeScheduledJob.fulfilled, hideLoading) + builder.addCase(removeScheduledJob.rejected, defaultRejectedHandler) builder.addCase(runNewJob.pending, showLoading) builder.addCase(runNewJob.fulfilled, state => { state.error = null diff --git a/src/reducers/monitoringApplicationsReducer.js b/src/reducers/monitoringApplicationsReducer.js index 820cf8e91e..0599ffa3c1 100644 --- a/src/reducers/monitoringApplicationsReducer.js +++ b/src/reducers/monitoringApplicationsReducer.js @@ -18,245 +18,64 @@ under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ import { createSlice, createAsyncThunk } from '@reduxjs/toolkit' +import { get } from 'lodash' import { defaultPendingHandler, defaultRejectedHandler } from './redux.util' import { splitApplicationsContent } from '../utils/applications.utils' import monitoringApplicationsApi from '../api/monitoringApplications-api' +import nuclioApi from '../api/nuclio' import { DATES_FILTER } from '../constants' -// TODO: delete initialState data in ML-10005 const initialState = { applicationsSummary: { - running_model_monitoring_functions: 16, - failed_model_monitoring_functions: 8, - real_time_model_endpoint_count: 75, - batch_model_endpoint_count: 44, loading: false, error: null }, - monitoringApplication: { - name: 'monitorAppV1', - application_class: 'MyAppV1', - started_at: '2025-05-01T12:00:00Z', - updated_time: '2025-05-07T10:00:00Z', - base_period: 10, - nuclio_function_uri: 'my-project/functions/my-project-monitorAppV1/', - stats: { - detections: 1245, - potential_detections: 98, - lag: 2, - committed_offset: 110, - shards: { - 1: { - committed: 50, - lag: 2 - }, - 2: { - committed: 60, - lag: 0 - } - }, - processed_model_endpoints: 8, - metrics: [ - { - type: 'result', - time: '2025-05-07T09:07:14+00:00', - name: 'some_result', - kind: 'data-drift', - status: 'Detection', - value: 0.95 - }, - { - type: 'metric', - time: '2025-05-07T09:07:14+00:00', - name: 'some_metric', - value: 0.4 - } - ] + endpointsWithDetections: { + data: { + values: [], + start: null, + end: null }, - status: 'ready' + loading: false, + error: null }, + monitoringApplication: {}, monitoringApplications: { - applications: [ - { - name: 'monitorAppV1', - application_class: 'MyAppV1', - started_at: '2025-05-01T12:00:00Z', - updated_time: '2025-05-07T10:00:00Z', - base_period: 10, - nuclio_function_uri: 'my-project/functions/my-project-monitorAppV1/', - stats: { - detections: 1245, - potential_detections: 98, - lag: 2, - committed_offset: 110, - shards: { - 1: { - committed: 50, - lag: 2 - }, - 2: { - committed: 60, - lag: 0 - } - }, - processed_model_endpoints: 8, - metrics: [ - { - type: 'result', - time: '2025-05-07T09:07:14+00:00', - name: 'some_result', - kind: 'data-drift', - status: 'Detection', - value: 0.95 - }, - { - type: 'metric', - time: '2025-05-07T09:07:14+00:00', - name: 'some_metric', - value: 0.4 - } - ] - }, - status: 'ready' - }, - { - name: 'monitorAppV2', - application_class: 'MyAppV2', - started_at: '2025-05-01T08:00:00Z', - updated_time: '2025-05-06T20:00:00Z', - base_period: 10, - nuclio_function_uri: 'default/functions/default-monitorAppV2/', - stats: { - detections: 567, - potential_detections: 34, - lag: 0, - committed_offset: 10598, - shards: { - 1: { - committed: 50, - lag: 2 - }, - 2: { - committed: 60, - lag: 0 - } - }, - processed_model_endpoints: 8, - metrics: [ - { - type: 'result', - time: '2025-05-07T09:07:14+00:00', - name: 'some_result', - kind: 0, - status: 2, - value: 0.95 - }, - { - type: 'metric', - time: '2025-05-07T09:07:14+00:00', - name: 'some_metric', - value: 0.4 - } - ] - }, - status: 'ready' - }, - { - name: 'monitorAppV3', - application_class: 'MyAppV3', - started_at: '2025-05-02T09:00:00Z', - updated_time: '2025-05-08T11:00:00Z', - base_period: 15, - nuclio_function_uri: 'default/functions/default-monitorAppV3/', - stats: { - detections: 850, - potential_detections: 60, - lag: 5, - committed_offset: 203498, - shards: { - 1: { - committed: 50, - lag: 2 - }, - 2: { - committed: 60, - lag: 0 - } - }, - processed_model_endpoints: 8, - metrics: [ - { - type: 'result', - time: '2025-05-07T09:07:14+00:00', - name: 'some_result', - kind: 0, - status: 2, - value: 0.95 - }, - { - type: 'metric', - time: '2025-05-07T09:07:14+00:00', - name: 'some_metric', - value: 0.4 - } - ] - }, - status: 'ready' - } - ], - operatingFunctions: [ - { - name: 'model-monitoring-controller', - application_class: 'modelMonitoringController', - started_at: '2025-05-01T12:00:00Z', - updated_time: '2025-05-07T10:00:00Z', - base_period: 10, - nuclio_function_uri: 'default/functions/default-modelMonitoringController/', - stats: { - detections: 1245, - potential_detections: 98, - lag: 12, - committed_offset: 398742 - }, - status: 'ready' - }, - { - name: 'model-monitoring-stream', - application_class: 'modelMonitoringStream', - started_at: '2025-05-01T08:00:00Z', - updated_time: '2025-05-06T20:00:00Z', - base_period: 10, - nuclio_function_uri: 'default/functions/default-modelMonitoringStream/', - stats: { - detections: 567, - potential_detections: 34, - lag: 0, - committed_offset: 10598 - }, - status: 'ready' - }, - { - name: 'model-monitoring-writer', - application_class: 'modelMonitoringWriter', - started_at: '2025-05-01T08:00:00Z', - updated_time: '2025-05-06T20:00:00Z', - base_period: 10, - nuclio_function_uri: 'default/functions/default-modelMonitoringWriter/', - stats: { - detections: 2567, - potential_detections: 134, - lag: 10, - committed_offset: 110598 - }, - status: 'ready' - } - ] + applications: [], + operatingFunctions: [] }, loading: false, error: null } +export const fetchMEPWithDetections = createAsyncThunk( + 'fetchMEPWithDetections', + ({ project, filters }) => { + const params = { + start: filters[DATES_FILTER].value[0].getTime() + } + + if (filters[DATES_FILTER].value[1]) { + params.end = filters[DATES_FILTER].value[1].getTime() + } + + const savedStartDate = filters[DATES_FILTER].value[0].getTime() + const savedEndDate = (filters[DATES_FILTER].value[1] || new Date()).getTime() + + return monitoringApplicationsApi.getMEPWithDetections(project, params).then(response => { + return { + values: response.data.values.map(([date, suspected, detected]) => [ + date, + suspected + detected + ]), + start: savedStartDate, + end: savedEndDate + } + }) + } +) + export const fetchMonitoringApplication = createAsyncThunk( 'fetchMonitoringApplication', ({ project, functionName, filters }) => { @@ -264,6 +83,10 @@ export const fetchMonitoringApplication = createAsyncThunk( start: filters[DATES_FILTER].value[0].getTime() } + if (filters[DATES_FILTER].value[1]) { + params.end = filters[DATES_FILTER].value[1].getTime() + } + return monitoringApplicationsApi .getMonitoringApplication(project, functionName, params) .then(response => response.data) @@ -272,14 +95,39 @@ export const fetchMonitoringApplication = createAsyncThunk( export const fetchMonitoringApplications = createAsyncThunk( 'fetchMonitoringApplications', - ({ project, filters }) => { + async ({ project, filters }) => { const params = { start: filters[DATES_FILTER].value[0].getTime() } - return monitoringApplicationsApi.getMonitoringApplications(project, params).then(response => { - return splitApplicationsContent(response.data) + if (filters[DATES_FILTER].value[1]) { + params.end = filters[DATES_FILTER].value[1].getTime() + } + + const [mlrunResult, nuclioResult] = await Promise.allSettled([ + monitoringApplicationsApi.getMonitoringApplications(project, params), + nuclioApi.getFunctions(project) + ]) + + if (mlrunResult.status !== 'fulfilled') { + throw new Error(mlrunResult.reason) + } + + const mlrunApiApps = get(mlrunResult, 'value.data') + const nuclioApiApps = get(nuclioResult, 'value.data') + + const splitApps = splitApplicationsContent(mlrunApiApps) + + const applications = splitApps.applications.map(mlrunApp => { + const match = nuclioApiApps[`${mlrunApp.project_name}-${mlrunApp.name}`] + + return { + ...mlrunApp, + status: match?.status?.state ?? mlrunApp.status + } }) + + return { ...splitApps, applications } } ) @@ -296,6 +144,9 @@ const monitoringApplicationsSlice = createSlice({ name: 'monitoringApplicationsStore', initialState, reducers: { + removeMEPWithDetections(state) { + state.endpointsWithDetections = initialState.endpointsWithDetections + }, removeMonitoringApplication(state) { state.monitoringApplication = initialState.monitoringApplication }, @@ -304,16 +155,30 @@ const monitoringApplicationsSlice = createSlice({ } }, extraReducers: builder => { + builder.addCase(fetchMEPWithDetections.pending, state => { + state.endpointsWithDetections.loading = true + }) + builder.addCase(fetchMEPWithDetections.fulfilled, (state, { payload }) => { + state.endpointsWithDetections.data = payload + state.endpointsWithDetections.loading = false + state.endpointsWithDetections.error = null + }) + builder.addCase(fetchMEPWithDetections.rejected, (state, action) => { + state.endpointsWithDetections.loading = false + state.endpointsWithDetections.error = action.error + }) builder.addCase(fetchMonitoringApplication.pending, defaultPendingHandler) builder.addCase(fetchMonitoringApplication.fulfilled, (state, { payload }) => { state.monitoringApplication = payload state.loading = false + state.error = null }) builder.addCase(fetchMonitoringApplication.rejected, defaultRejectedHandler) builder.addCase(fetchMonitoringApplications.pending, defaultPendingHandler) builder.addCase(fetchMonitoringApplications.fulfilled, (state, { payload }) => { state.monitoringApplications = payload state.loading = false + state.error = null }) builder.addCase(fetchMonitoringApplications.rejected, defaultRejectedHandler) builder.addCase(fetchMonitoringApplicationsSummary.pending, state => { @@ -322,6 +187,7 @@ const monitoringApplicationsSlice = createSlice({ builder.addCase(fetchMonitoringApplicationsSummary.fulfilled, (state, { payload }) => { state.applicationsSummary = payload state.applicationsSummary.loading = false + state.applicationsSummary.error = null }) builder.addCase(fetchMonitoringApplicationsSummary.rejected, (state, action) => { state.applicationsSummary.loading = false @@ -330,7 +196,10 @@ const monitoringApplicationsSlice = createSlice({ } }) -export const { removeMonitoringApplication, removeMonitoringApplications } = - monitoringApplicationsSlice.actions +export const { + removeMEPWithDetections, + removeMonitoringApplication, + removeMonitoringApplications +} = monitoringApplicationsSlice.actions export default monitoringApplicationsSlice.reducer diff --git a/src/reducers/projectReducer.js b/src/reducers/projectReducer.js index 0fd11ab98e..9104540b9a 100644 --- a/src/reducers/projectReducer.js +++ b/src/reducers/projectReducer.js @@ -28,9 +28,11 @@ import { } from 'igz-controls/constants' import { DEFAULT_ABORT_MSG, PROJECT_ONLINE_STATUS, REQUEST_CANCELED } from '../constants' import { parseProjects } from '../utils/parseProjects' -import { showErrorNotification } from '../utils/notifications.util' +import { showErrorNotification } from 'igz-controls/utils/notification.util' import { parseSummaryData } from '../utils/parseSummaryData' import { mlrunUnhealthyErrors } from '../components/ProjectsPage/projects.util' +import { aggregateApplicationStatuses, splitApplicationsContent } from '../utils/applications.utils' +import { fetchNuclioFunctions } from './nuclioReducer' const initialState = { deletingProjects: {}, @@ -50,6 +52,7 @@ const initialState = { isUnhealthy: false, retrying: false }, + accessibleProjectsMap: {}, project: { data: null, error: null, @@ -244,13 +247,26 @@ export const fetchProjectSecrets = createAsyncThunk( return projectsApi.getProjectSecrets(project).catch(error => thunkAPI.rejectWithValue(error)) } ) -export const fetchProjectSummary = createAsyncThunk( - 'fetchProjectSummary', - ({ project, signal }, thunkAPI) => { - return projectsApi - .getProjectSummary(project, signal) - .then(({ data }) => { - return parseSummaryData(data) +export const fetchProjectSummaryAndNuclioFuncs = createAsyncThunk( + 'fetchProjectSummaryAndNuclioFuncs', + ({ project, projectSummarySignal, functionsSignal }, thunkAPI) => { + return Promise.all([ + projectsApi.getProjectSummary(project, projectSummarySignal), + thunkAPI.dispatch(fetchNuclioFunctions({ project, signal: functionsSignal })).unwrap() + ]) + .then(([projectSummary, nuclioFunctions]) => { + const parsedProjectSummary = parseSummaryData(projectSummary.data) + const { ready: runningAppsNumber, error: failedAppsNumber } = aggregateApplicationStatuses( + splitApplicationsContent(nuclioFunctions.data).applications + ) + + return { + ...parsedProjectSummary, + running_model_monitoring_functions: + runningAppsNumber ?? parsedProjectSummary.running_model_monitoring_functions, + failed_model_monitoring_functions: + failedAppsNumber ?? parsedProjectSummary.failed_model_monitoring_functions + } }) .catch(error => { if (![REQUEST_CANCELED, DEFAULT_ABORT_MSG].includes(error.message)) { @@ -261,7 +277,7 @@ export const fetchProjectSummary = createAsyncThunk( ) export const fetchProjects = createAsyncThunk( 'fetchProjects', - ({ params, setRequestErrorMessage = () => {} }, thunkAPI) => { + ({ params, setRequestErrorMessage = () => {}, showNotification = true }, thunkAPI) => { setRequestErrorMessage('') return projectsApi @@ -270,14 +286,17 @@ export const fetchProjects = createAsyncThunk( return parseProjects(response.data.projects) }) .catch(error => { - showErrorNotification( - thunkAPI.dispatch, - error, - 'Failed to fetch projects', - null, - null, - setRequestErrorMessage - ) + if (showNotification) { + showErrorNotification( + thunkAPI.dispatch, + error, + 'Failed to fetch projects', + null, + null, + setRequestErrorMessage + ) + } + return thunkAPI.rejectWithValue(error) }) } @@ -374,6 +393,12 @@ const projectStoreSlice = createSlice({ }, setProjectTotalAlerts(state, action) { state.projectTotalAlerts = { ...action.payload } + }, + setAccessibleProjectsMap(state, action) { + state.accessibleProjectsMap = { + ...state.accessibleProjectsMap, + ...action.payload + } } }, extraReducers: builder => { @@ -487,7 +512,7 @@ const projectStoreSlice = createSlice({ }) builder.addCase(fetchProjectSecrets.fulfilled, (state, action) => { state.project.secrets = { - data: action.payload, + data: action.payload.data, error: null, loading: false } @@ -499,17 +524,17 @@ const projectStoreSlice = createSlice({ loading: false } }) - builder.addCase(fetchProjectSummary.pending, state => { + builder.addCase(fetchProjectSummaryAndNuclioFuncs.pending, state => { state.projectSummary.loading = true }) - builder.addCase(fetchProjectSummary.fulfilled, (state, action) => { + builder.addCase(fetchProjectSummaryAndNuclioFuncs.fulfilled, (state, action) => { state.projectSummary = { data: action.payload, error: null, loading: false } }) - builder.addCase(fetchProjectSummary.rejected, (state, action) => { + builder.addCase(fetchProjectSummaryAndNuclioFuncs.rejected, (state, action) => { state.projectSummary = { data: [], error: action.payload.message, @@ -576,7 +601,8 @@ export const { setMlrunIsUnhealthy, setMlrunUnhealthyRetrying, setJobsMonitoringData, - setProjectTotalAlerts + setProjectTotalAlerts, + setAccessibleProjectsMap } = projectStoreSlice.actions export default projectStoreSlice.reducer diff --git a/src/reducers/workflowReducer.js b/src/reducers/workflowReducer.js index 3d8bb8c9b8..8046b80cc0 100644 --- a/src/reducers/workflowReducer.js +++ b/src/reducers/workflowReducer.js @@ -45,7 +45,7 @@ export const fetchWorkflow = createAsyncThunk('fetchWorkflow', ({ project, workf }) export const fetchWorkflows = createAsyncThunk( 'fetchWorkflows', - async ({ project, filter, config, withPagination }, { rejectWithValue }) => { + async ({ project, filter, config, withPagination }, { dispatch, rejectWithValue }) => { const page = project === '*' ? JOBS_MONITORING_WORKFLOWS_TAB : MONITOR_WORKFLOWS_TAB let result = [] let nextPageToken = '' @@ -56,7 +56,7 @@ export const fetchWorkflows = createAsyncThunk( largeResponseCatchHandler( error, 'Failed to fetch workflows', - null, + dispatch, config?.ui?.setRequestErrorMessage ) diff --git a/src/scss/main.scss b/src/scss/main.scss index 0487c07d94..fb64c367a8 100644 --- a/src/scss/main.scss +++ b/src/scss/main.scss @@ -40,306 +40,6 @@ body { } } -/* =========== CONTENT MENU ============= */ - -.content-menu { - display: inline-flex; - align-items: center; - width: 100%; - min-height: 40px; - - &__tabs-wrapper { - overflow-x: hidden; - } - - &__tabs { - display: flex; - flex-direction: row; - align-items: center; - list-style-type: none; - transition: transform 0.2s ease-in-out; - - @include mixins.resetSpaces; - } - - &__tab { - align-items: center; - margin: 0 15px 0 0; - padding: 5px; - color: colors.$topaz; - font-weight: 400; - line-height: 1; - white-space: nowrap; - text-align: center; - text-transform: capitalize; - cursor: pointer; - - &:first-child { - padding-left: 0; - } - - &-sm { - font-size: 16px; - - @media screen and (min-width: 1300px) { - font-size: 18px; - } - } - - &-md { - font-size: 18px; - - @media screen and (min-width: 1300px) { - font-size: 20px; - } - } - - &-lg { - font-size: 20px; - - @media screen and (min-width: 1300px) { - font-size: 22px; - } - } - - &::after { - display: block; - width: 100%; - padding-bottom: 5px; - border-width: 2px; - border-bottom: 2px solid colors.$cornflowerBlue; - transform: scale(0); - opacity: 0; - transition: all 0.3s ease-in-out; - content: ''; - } - - &:hover:not([class*='_active']) { - &::after { - transform: scale(1); - opacity: 0.6; - } - } - - & > * { - position: relative; - display: inline-flex; - align-items: center; - - &.content-menu__tab-tip { - gap: 5px; - } - - &.content-menu__tab-icon { - gap: 5px; - - & > * { - svg { - width: 17px; - height: 17px; - - path { - fill: colors.$topaz; - } - } - } - } - } - - &.content-menu__tab_active { - svg { - path { - fill: colors.$cornflowerBlue; - } - } - } - - &_active { - color: colors.$primary; - font-weight: 700; - pointer-events: none; - - .content-menu__tab-tip { - svg { - pointer-events: auto; - } - } - - &::after { - transform: scale(1); - opacity: 1; - } - - a { - cursor: default; - } - - .content-menu__tab-icon { - svg { - path { - fill: colors.$cornflowerBlue; - } - } - } - } - } - - &_disabled { - pointer-events: none; - - a { - cursor: not-allowed; - } - } - - &__preview { - color: colors.$spunPearl; - font-size: 10px; - } - - .tabs-slider { - &__arrow { - display: flex; - width: 30px; - min-width: fit-content; - max-width: 24px; - border-radius: 8px; - - &_left { - padding-top: 3px; - transform: rotate(180deg); - } - - &_right { - padding-bottom: 3px; - } - - &_hidden { - display: none; - } - - &_disabled { - pointer-events: none; - - & path { - fill: colors.$spunPearl; - } - } - - &:hover:not(.details-menu__arrow_disabled) { - background-color: colors.$mulledWineThree; - cursor: pointer; - } - - svg { - align-self: center; - } - } - } -} - -/* =========== CONTENT ============= */ - -.content { - position: relative; - flex-direction: column; - min-width: 800px; - padding: 15px 24px 10px; - background-color: colors.$white; - - @include mixins.jobsFlex; - - @media screen and (min-width: 1300px) { - padding: 15px 64px 15px; - } - - &__header { - display: flex; - flex-flow: row nowrap; - align-items: center; - justify-content: space-between; - min-height: 70px; - padding: 14px 24px; - background-color: colors.$white; - box-shadow: shadows.$headerShadow; - - .btn { - &_register { - text-transform: capitalize; - } - } - } - - .table-container { - position: relative; - display: flex; - flex: 1; - flex-direction: column; - background-color: colors.$white; - - .no_data { - margin: auto; - color: colors.$mulledWine; - } - } - - &-wrapper { - display: flex; - flex: 1 1; - flex-direction: column; - min-width: 100%; - } - - &__action-bar-wrapper { - display: flex; - flex-flow: row wrap; - align-items: center; - - &_hidden { - display: none; - } - - .content-menu { - flex: 0; - margin-right: 20px; - margin-bottom: 15px; - - &__item { - white-space: nowrap; - } - } - - .action-bar { - display: flex; - flex: 1; - align-items: flex-start; - justify-content: flex-end; - width: 100%; - margin-bottom: 15px; - - &_hidden { - display: none; - } - - &__filters { - &-item { - &:not(:last-child) { - margin: 0 15px 0 0; - } - } - } - } - } - - &__history-back-link-wrapper { - padding-bottom: 5px; - - .history-back-link__title { - max-width: 100%; - } - } -} - /* =========== MAIN ============= */ main { @@ -357,9 +57,7 @@ main { &.unpinned { .create-container__header, .create-container__data, - .content__header, - .project__header, - .settings__header { + .content__header { padding-left: 40px; transition: padding 0.3s ease-in-out; } @@ -389,7 +87,7 @@ main { .page-actions { display: flex; justify-content: flex-end; - margin: 0 0 20px 0; + margin: 0 0 20px; .search-container { flex: unset; @@ -414,292 +112,6 @@ main { } } -/* =========== TABLE ============= */ - -.table { - position: relative; - width: 100%; - text-align: left; - border-spacing: 0; - - .table { - &-row { - display: flex; - flex-direction: row; - min-width: 100%; - min-height: 50px; - background-color: inherit; - - &:not(.parent-row_expanded) > * { - position: relative; - display: inline-flex; - flex: 1; - align-items: center; - border-bottom: borders.$tableRowBorder; - - @include mixins.tableDet(8px, 5px, 8px, 10px); - - &:first-child { - padding-left: 30px; - } - - &.table-cell { - &-name { - position: sticky; - left: 0; - z-index: 1; - min-width: 250px; - padding-right: 10px; - } - - &-icon { - position: sticky; - right: 0; - justify-content: center; - max-width: 85px; - padding: 0; - - @include mixins.tableColumnFlex(0, 50px); - - & > :first-child { - padding: 0; - } - - &__run-icon { - margin-bottom: -2px; - transform: rotate(-90deg) scale(1.2); - } - } - } - } - - &.parent-row { - &:not(.parent-row_expanded) { - &:not(.parent-row_without-actions) { - .table-cell-icon { - .actions-menu { - &__container_extended { - &::before { - background: - linear-gradient( - 90deg, - rgba(255, 255, 255, 0) 0%, - rgba(245, 247, 255, 1) 100% - ); - } - } - } - } - - &:hover { - .table-cell-icon { - .actions-menu { - &__container { - display: flex; - - &_extended { - background-color: colors.$ghostWhite; - - &::before { - background: - linear-gradient( - 90deg, - rgba(255, 255, 255, 0) 0%, - rgba(245, 247, 255, 1) 100% - ); - } - } - - .btn { - min-width: 24px; - padding: 0; - border: none; - - &:hover { - background-color: transparent; - } - } - } - } - } - } - } - } - - .expand-arrow { - position: absolute; - left: 5px; - cursor: pointer; - } - - .best-iteration { - position: absolute; - top: auto; - bottom: auto; - left: 5px; - margin-top: 3px; - } - - &_expanded { - flex-direction: column; - border: 0; - - .table-row { - &:hover { - .table-cell-icon { - .actions-menu { - &__container { - display: flex; - } - } - } - } - } - - .row_grouped-by { - position: sticky; - top: #{variables.$headerRowHeight}px; - z-index: 3; - padding: 0; - background-color: colors.$white; - - .expand-arrow { - transform: rotate(90deg); - } - } - } - } - - .checkbox { - position: absolute; - left: 8px; - margin: 0; - } - } - - &-header { - position: sticky; - top: 0; - z-index: 3; - min-width: 100%; - - &-row { - min-height: #{variables.$headerRowHeight}px; - } - - &__cell { - min-width: 75px; - - @include mixins.tableHeader; - - &:first-child { - border-radius: 4px 0 0 0; - } - - &:last-child { - border-radius: 0 4px 0 0; - } - } - } - - &-body { - position: relative; - z-index: 2; - - &__cell { - .status { - display: flex; - flex: 0 1 12px; - align-items: center; - justify-content: center; - min-width: 12px; - margin-left: 5px; - - & > * { - margin: 0; - } - } - } - - .table-row { - background-color: colors.$white; - - &:hover, - &_active { - background-color: colors.$ghostWhite; - } - - & > * { - background-color: inherit; - } - } - } - } - - &-main { - display: flex; - flex: 1; - flex-flow: column nowrap; - overflow-y: auto; - will-change: scroll-position; - } - - &.table-with-details { - .table-cell-name { - min-width: 240px; - max-width: 240px; - } - } - - &-fixed { - table-layout: fixed; - } -} - -/* =========== SORT ============= */ - -.sortable-header { - &-cell { - position: relative; - border: 0; - border-radius: 0; - cursor: pointer; - - .sort-icon { - position: absolute; - top: auto; - right: 2px; - bottom: auto; - display: none; - } - - &_active { - background-color: colors.$alabaster; - - .sort-icon { - display: block; - } - } - - &:hover { - .sort-icon { - display: block; - } - } - - label { - cursor: pointer; - } - } - - &-label { - position: relative; - display: flex; - align-items: center; - padding-right: 25px; - } -} - /* =========== STATE ============= */ [class^='state-active'], @@ -772,6 +184,10 @@ main { @include mixins.statusState(colors.$topaz, false); } +[class^='state-pendingRetry'] { + @include mixins.statusState(colors.$fuchsiaPink, false); +} + .state-created-job, .state-created-function, .state-creating-function, @@ -895,16 +311,21 @@ main { } .graph-pane { + position: relative; display: flex; - flex-direction: column; - width: 25%; - min-width: 350px; - overflow: hidden; + width: 30%; + min-width: 400px; + color: colors.$primary; background: colors.$white; border: borders.$secondaryBorder; box-shadow: 0 0 30px rgba(colors.$black, 0.15); - &.scrollable { + &-scroll-container { + position: absolute; + top: 0; + right: 0; + width: 100%; + height: 100%; overflow-y: auto; } @@ -912,9 +333,24 @@ main { display: flex; align-items: center; justify-content: space-between; - padding: 25px; + padding: 10px 25px; + border-bottom: borders.$secondaryBorder; font-weight: bold; font-size: 20px; + position: sticky; + top: 0; + z-index: 4; + background-color: colors.$white; + + &-icon { + margin-right: 8px; + display: flex; + align-items: center; + } + + &-label { + margin-right: auto; + } } } } @@ -1134,65 +570,15 @@ div[id^='chartjs-tooltip'] { } } -/* =========== GENERAL ============= */ - -.d-flex { - display: flex; -} - -.visibility-hidden { - visibility: hidden; -} +/* =========== ICONS ============= */ -.data-ellipsis { - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; -} - -.cursor-pointer { - cursor: pointer; -} - -.capitalize { - text-transform: capitalize; -} - -.wrap { - white-space: pre-wrap; -} - -iframe { - width: 100%; - height: 100%; -} - -a { - color: inherit; - text-decoration: none; -} - -*, -::after, -::before { - box-sizing: border-box; -} - -::-webkit-scrollbar { - width: 8px; - height: 8px; -} - -::-webkit-scrollbar-track { - background-color: rgba(colors.$black, 0.1); - border-radius: 10px; -} - -::-webkit-scrollbar-thumb { - background-color: rgba(colors.$black, 0.25); - border-radius: 10px; +.table-severity-warning-icon { + svg { + width: 32px; + height: 32px; - &:hover { - background-color: rgba(colors.$black, 0.4); + path { + fill: colors.$supernova; + } } } diff --git a/src/setupProxy.js b/src/setupProxy.js index 571c9c827d..80056e64d8 100644 --- a/src/setupProxy.js +++ b/src/setupProxy.js @@ -28,7 +28,7 @@ module.exports = function (app) { headers: { Connection: 'keep-alive' }, - onProxyReq: function (proxyReq, req, res) { + onProxyReq: function (proxyReq) { proxyReq.setHeader('x-v3io-session-key', import.meta.env.VITE_MLRUN_V3IO_ACCESS_KEY) proxyReq.setHeader('x-remote-user', 'admin') } diff --git a/src/store/toolkitStore.js b/src/store/toolkitStore.js index 8290caada5..901b2b37ee 100644 --- a/src/store/toolkitStore.js +++ b/src/store/toolkitStore.js @@ -29,18 +29,21 @@ import filtersStore from '../reducers/filtersReducer' import functionsStore from '../reducers/functionReducer' import jobsStore from '../reducers/jobReducer' import monitoringApplicationsStore from '../reducers/monitoringApplicationsReducer' -import notificationStore from '../reducers/notificationReducer' import nuclioStore from '../reducers/nuclioReducer' import projectStore from '../reducers/projectReducer' import tableStore from '../reducers/tableReducer' import tasksStore from '../reducers/tasksReducer' import workflowsStore from '../reducers/workflowReducer' +import commonDetailsStore from 'igz-controls/reducers/commonDetailsReducer' +import notificationStore from 'igz-controls/reducers/notificationReducer' + const toolkitStore = configureStore({ reducer: { alertsStore, appStore, artifactsStore, + commonDetailsStore, detailsStore, downloadStore, featureStore, diff --git a/src/stories/Link.stories.js b/src/stories/Link.stories.jsx similarity index 100% rename from src/stories/Link.stories.js rename to src/stories/Link.stories.jsx diff --git a/src/types.js b/src/types.js index 7e301d0ae3..8ad5a2881c 100644 --- a/src/types.js +++ b/src/types.js @@ -21,16 +21,19 @@ import PropTypes from 'prop-types' import { BE_PAGE, BE_PAGE_SIZE, - DENSITY_CHUNKY, - DENSITY_DENSE, - DENSITY_MEDIUM, - DENSITY_NORMAL, FE_PAGE, FE_PAGE_SIZE, + GREY_NODE, + INPUT_NODE, + OUTPUT_NODE, + OVAL_NODE_SHAPE, PANEL_CREATE_MODE, PANEL_EDIT_MODE, PANEL_FUNCTION_CREATE_MODE, - PANEL_RERUN_MODE + PANEL_RERUN_MODE, + PRIMARY_NODE, + ROUNDED_RECTANGLE_NODE_SHAPE, + SECONDARY_NODE } from './constants' import { BUTTON_VARIANTS } from 'igz-controls/types' @@ -44,50 +47,6 @@ export const COMBOBOX_MATCHES = PropTypes.arrayOf( }) ) -export const DENSITY_OPTIONS = PropTypes.oneOf([ - DENSITY_DENSE, - DENSITY_NORMAL, - DENSITY_MEDIUM, - DENSITY_CHUNKY -]) - -export const CHIP = PropTypes.shape({ - delimiter: PropTypes.element, - id: PropTypes.string, - value: PropTypes.string.isRequired -}) - -export const CHIP_INPUT_LIST = PropTypes.arrayOf( - PropTypes.shape({ - disabled: PropTypes.bool, - icon: PropTypes.element, - id: PropTypes.string.isRequired, - label: PropTypes.string.isRequired, - subLabel: PropTypes.string, - ui: PropTypes.object - }) -) - -export const CHIP_OPTIONS = PropTypes.shape({ - background: PropTypes.oneOf([ - 'none', - 'orange', - 'green', - 'purple', - 'grey', - 'sorbus', - 'java', - 'amethyst' - ]), - boldValue: PropTypes.bool, - borderColor: PropTypes.oneOf(['transparent', 'orange', 'green', 'purple', 'grey']), - density: DENSITY_OPTIONS, - font: PropTypes.oneOf(['primary', 'white', 'green', 'purple', 'orange']), - borderRadius: PropTypes.oneOf(['primary', 'secondary']) -}) - -export const CHIPS = PropTypes.arrayOf(CHIP) - export const FUNCTION_PANEL_MODE = PropTypes.oneOf([PANEL_EDIT_MODE, PANEL_CREATE_MODE]) export const SELECT_OPTION = PropTypes.shape({ @@ -118,19 +77,6 @@ export const CONFIRM_DIALOG_BUTTON = PropTypes.shape({ variant: PropTypes.string.isRequired }) -const ACTIONS_MENU_ITEM = PropTypes.shape({ - label: PropTypes.string.isRequired, - icon: PropTypes.object, - onClick: PropTypes.func.isRequired, - disabled: PropTypes.bool, - className: PropTypes.string -}) - -export const ACTIONS_MENU = PropTypes.oneOfType([ - PropTypes.arrayOf(PropTypes.arrayOf(ACTIONS_MENU_ITEM.isRequired)), - PropTypes.func -]) - export const MAIN_SPLIT_BUTTON = PropTypes.shape({ className: PropTypes.string, icon: PropTypes.element, @@ -158,15 +104,6 @@ export const CONTENT_MENU_TABS = PropTypes.arrayOf( }) ) -export const SLIDER_TABS = PropTypes.arrayOf( - PropTypes.shape({ - id: PropTypes.string.isRequired, - label: PropTypes.string.isRequired, - tip: PropTypes.string, - hidden: PropTypes.bool - }) -) - export const SCHEDULE_DATA = PropTypes.shape({ cron: PropTypes.string, defaultCron: PropTypes.string, @@ -216,12 +153,6 @@ export const JOB_WIZARD_MODE = PropTypes.oneOf([ PANEL_RERUN_MODE ]) -export const VIRTUALIZATION_CONFIG = PropTypes.shape({ - startIndex: PropTypes.number.isRequired, - endIndex: PropTypes.number.isRequired, - tableBodyPaddingTop: PropTypes.number.isRequired -}) - export const SLIDER_STYLE_1 = 'style1' export const SLIDER_STYLE_2 = 'style2' @@ -281,12 +212,12 @@ export const FILTERS_CONFIG = PropTypes.objectOf( }) ) -export const STATUS_LIST = PropTypes.arrayOf( +export const OPTIONS_LIST = PropTypes.arrayOf( PropTypes.shape({ id: PropTypes.string.isRequired, label: PropTypes.string.isRequired, - status: PropTypes.string.isRequired, - disabled: PropTypes.bool + disabled: PropTypes.bool, + status: PropTypes.string, }) ) @@ -312,3 +243,23 @@ export const MEMBER = PropTypes.shape({ initialRole: PropTypes.string, modification: PropTypes.string }) + +export const REACT_FLOW_NODE_DATA = PropTypes.shape({ + subType: PropTypes.oneOf([INPUT_NODE, OUTPUT_NODE, PRIMARY_NODE, SECONDARY_NODE, GREY_NODE]) + .isRequired, + label: PropTypes.string.isRequired, + tip: PropTypes.string, + subLabel: PropTypes.string, + isSelectable: PropTypes.bool, + withOpacity: PropTypes.bool, + shape: PropTypes.oneOf([OVAL_NODE_SHAPE, ROUNDED_RECTANGLE_NODE_SHAPE, null]), + sourceHandle: PropTypes.shape({ + tooltip: PropTypes.string, + className: PropTypes.string + }), + targetHandle: PropTypes.shape({ + tooltip: PropTypes.string, + className: PropTypes.string + }), + customData: PropTypes.object +}) diff --git a/src/utils/applications.utils.js b/src/utils/applications.utils.js index 9df80994a1..1216600cc8 100644 --- a/src/utils/applications.utils.js +++ b/src/utils/applications.utils.js @@ -17,25 +17,58 @@ illegal under applicable law, and the grant of the foregoing license under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ +import { isArray, clone } from 'lodash' + +import { ERROR_STATE, FUNCTION_READY_STATE, UNHEALTHY_STATE } from '../constants' + const OPERATING_FUNCTIONS_NAMES_LIST = [ - 'model-monitoring-controller', - 'model-monitoring-stream', - 'model-monitoring-writer' + 'model-monitoring-controller', + 'model-monitoring-stream', + 'model-monitoring-writer' +] +const NUCLIO_FUNCTIONS_MLRUN_TYPES = [ + 'mlrun__model-monitoring-application', + 'mlrun__model-monitoring-infra' ] export const splitApplicationsContent = (functions = []) => { - const monitoringApplicationsData = { - operatingFunctions: [], - applications: [] - } + const monitoringApplicationsData = { + operatingFunctions: [], + applications: [] + } + let workingFunctions = clone(functions) - functions.forEach(func => { - if (OPERATING_FUNCTIONS_NAMES_LIST.includes(func.name)) { - monitoringApplicationsData.operatingFunctions.push(func) - } else { - monitoringApplicationsData.applications.push(func) - } + if (!isArray(functions)) { + workingFunctions = Object.values(functions).filter(app => { + return NUCLIO_FUNCTIONS_MLRUN_TYPES.includes(app.metadata.labels['mlrun__type']) }) + } + + workingFunctions.forEach(func => { + const funcName = func.name + ? func.name + : func.metadata.name.replace(`${func.metadata.labels['nuclio.io/project-name']}-`, '') + + if (OPERATING_FUNCTIONS_NAMES_LIST.includes(funcName)) { + monitoringApplicationsData.operatingFunctions.push(func) + } else { + monitoringApplicationsData.applications.push(func) + } + }) + + return monitoringApplicationsData +} + +export const aggregateApplicationStatuses = monitoringApplications => { + return monitoringApplications.reduce( + (acc, application) => { + const status = application.status.state ? application.status.state : application.status - return monitoringApplicationsData + return { + ready: acc.ready + (status === FUNCTION_READY_STATE ? 1 : 0), + error: acc.error + ([ERROR_STATE, UNHEALTHY_STATE].includes(status) ? 1 : 0) + } + }, + { ready: 0, error: 0 } + ) } diff --git a/src/utils/artifacts.util.js b/src/utils/artifacts.util.js index 23a6e34b53..249d2a8dd3 100644 --- a/src/utils/artifacts.util.js +++ b/src/utils/artifacts.util.js @@ -32,9 +32,13 @@ import { LLM_PROMPTS_PAGE, MODEL_TYPE, MODELS_PAGE, - VIEW_SEARCH_PARAMETER + TAG_FILTER_ALL_ITEMS, + TAG_FILTER_LATEST, + ALL_VERSIONS_PATH, + LLM_PROMPT_TYPE, + LLM_PROMPT_TITLE } from '../constants' -import { TAG_FILTER_ALL_ITEMS, TAG_FILTER_LATEST, ALL_VERSIONS_PATH } from '../constants' +import { VIEW_SEARCH_PARAMETER } from 'igz-controls/constants' import { deleteTag, editTag, @@ -49,9 +53,13 @@ import { getArtifactIdentifier } from './getUniqueIdentifier' import { parseArtifacts } from './parseArtifacts' import { parseIdentifier } from './parseUri' import { setFilters, setModalFiltersValues } from '../reducers/filtersReducer' -import { showErrorNotification } from './notifications.util' -import { getFilteredSearchParams } from './filter.util' +import { showErrorNotification } from 'igz-controls/utils/notification.util' +import { getFilteredSearchParams } from 'igz-controls/utils/filter.util' import { generateObjectNotInTheListMessage } from './generateMessage.util' +import { openPopUp } from 'igz-controls/utils/common.util' +import { ConfirmDialog } from 'igz-controls/components' +import { PRIMARY_BUTTON, TERTIARY_BUTTON } from 'igz-controls/constants' +import { getArtifactMessagesByKind } from './createArtifact.util' export const applyTagChanges = (changes, artifactItem, projectName, dispatch, setNotification) => { let updateTagMsg = 'Tag was updated' @@ -115,6 +123,93 @@ export const applyTagChanges = (changes, artifactItem, projectName, dispatch, se } } +export const processActionAfterTagUniquesValidation = ({ + tag = '', + artifact, + projectName, + dispatch, + actionCallback, + showLoader = () => {}, + hideLoader = () => {}, + getCustomErrorMsg = () => 'Failed to update a tag', + onErrorCallback, + throwError = false +}) => { + showLoader() + + if (tag === '') { + return actionCallback().finally(hideLoader) + } + + const messagesByKind = getArtifactMessagesByKind(artifact.kind) + + return artifactApi + .getExpandedArtifact(projectName, artifact.db_key ?? artifact.spec.db_key ?? artifact.key , tag) + .then(response => { + if (response?.data) { + if (!isEmpty(response.data.artifacts)) { + return new Promise((resolve, _reject) => { + const reject = (...args) => { + hideLoader() + + return _reject(...args) + } + + // hide and show loader again to avoid UI loader above confirmation dialog + hideLoader() + openPopUp(ConfirmDialog, { + confirmButton: { + label: 'Overwrite', + variant: PRIMARY_BUTTON, + handler: () => { + showLoader() + actionCallback().then(resolve).catch(reject).finally(hideLoader) + } + }, + cancelButton: { + label: 'Cancel', + variant: TERTIARY_BUTTON, + handler: () => reject() + }, + closePopUp: () => reject(), + header: messagesByKind.overwriteConfirmTitle, + message: messagesByKind.getOverwriteConfirmMessage( + response.data.artifacts[0].kind === LLM_PROMPT_TYPE + ? LLM_PROMPT_TITLE + : response.data.artifacts[0].kind || ARTIFACT_TYPE + ), + className: 'override-artifact-dialog' + }) + }) + } else { + return actionCallback().finally(hideLoader) + } + } + }) + .catch(error => { + if (error) { + showErrorNotification(dispatch, error, '', getCustomErrorMsg(error), () => + processActionAfterTagUniquesValidation({ + tag, + artifact, + projectName, + dispatch, + actionCallback, + getCustomErrorMsg, + onErrorCallback, + throwError + }) + ) + + onErrorCallback?.() + } + + hideLoader() + + if (throwError) throw error + }) +} + export const isArtifactTagUnique = (projectName, category, artifact) => async value => { const artifactCategory = { MODELS_TAB: MODEL_TYPE, @@ -225,6 +320,7 @@ export const checkForSelectedArtifact = debounce( artifactName, artifacts, dispatch, + ignoreLastCheckedArtifact = false, isAllVersions, navigate, paginatedArtifacts, @@ -245,7 +341,7 @@ export const checkForSelectedArtifact = debounce( if ( artifacts && searchBePage === configBePage && - lastCheckedArtifactIdRef.current !== paramsId + (lastCheckedArtifactIdRef.current !== paramsId || ignoreLastCheckedArtifact) ) { lastCheckedArtifactIdRef.current = paramsId diff --git a/src/utils/copyToClipboard.js b/src/utils/copyToClipboard.js index 6fc648aab1..5ce46b16d1 100644 --- a/src/utils/copyToClipboard.js +++ b/src/utils/copyToClipboard.js @@ -17,8 +17,8 @@ illegal under applicable law, and the grant of the foregoing license under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ -import { setNotification } from '../reducers/notificationReducer' -import { showErrorNotification } from './notifications.util' +import { setNotification } from 'igz-controls/reducers/notificationReducer' +import { showErrorNotification } from 'igz-controls/utils/notification.util' export const copyToClipboard = (textToCopy, dispatch) => { if (!navigator.clipboard?.writeText) { diff --git a/src/utils/createAlertsContent.jsx b/src/utils/createAlertsContent.jsx index db834034b0..6535f25c67 100644 --- a/src/utils/createAlertsContent.jsx +++ b/src/utils/createAlertsContent.jsx @@ -18,11 +18,11 @@ under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ import { upperFirst } from 'lodash' -import { formatDatetime } from './datetime' +import { formatDatetime } from 'igz-controls/utils/datetime.util' import Application from 'igz-controls/images/entity-type-application.svg?react' import Endpoint from 'igz-controls/images/entity-type-endpoint.svg?react' -import Error from 'igz-controls/images/severity-warning.svg?react' +import Error from 'igz-controls/images/notification-badge.svg?react' import Critical from 'igz-controls/images/severity-critical.svg?react' import Email from 'igz-controls/images/email-icon.svg?react' import Git from 'igz-controls/images/git-icon.svg?react' @@ -47,7 +47,9 @@ import { SEVERITY_CRITICAL, SEVERITY_HIGH, SEVERITY_LOW, - SEVERITY_MEDIUM + SEVERITY_MEDIUM, + FAIL_STATE, + FAILED_STATE } from '../constants' const getEntityTypeData = entityType => { @@ -177,7 +179,7 @@ const getNotificationData = notifications => return { icon: (
    {alertsNotifications[notification.kind]} @@ -189,7 +191,7 @@ const getNotificationData = notifications =>
    ), tooltip: upperFirst( - `${notification.kind}: ${notification.summary.succeeded} success, ${notification.summary.failed} failed` + `${notification.kind}: ${notification.summary.succeeded} success, ${notification.summary.failed} ${FAILED_STATE}` ), kind: notification.kind, succeeded: notification.summary.succeeded, @@ -272,7 +274,7 @@ export const createAlertRowData = ({ ...alert }, isCrossProjects, showExpandButt { id: `alertName.${alert.id}`, headerId: 'alertName', - headerLabel: 'Alert Name', + headerLabel: 'Alert name', value: name, className: 'table-cell-name', getLink: () => (!showExpandButton ? getLink(alert) : ''), @@ -291,7 +293,7 @@ export const createAlertRowData = ({ ...alert }, isCrossProjects, showExpandButt { id: `eventType.${alert.id}`, headerId: 'eventType', - headerLabel: 'Event Type', + headerLabel: 'Event type', value: alert.event_kind?.split('-')?.join(' '), className: 'table-cell-1' }, @@ -305,7 +307,7 @@ export const createAlertRowData = ({ ...alert }, isCrossProjects, showExpandButt { id: `entityType.${alert.id}`, headerId: 'entityType', - headerLabel: 'Entity Type', + headerLabel: 'Entity type', value: getEntityTypeData(alert.entity_kind).value, className: 'table-cell-small', tooltip: getEntityTypeData(alert.entity_kind).tooltip, diff --git a/src/utils/createApplicationContent.jsx b/src/utils/createApplicationContent.jsx index ce145446f0..1291299b7b 100644 --- a/src/utils/createApplicationContent.jsx +++ b/src/utils/createApplicationContent.jsx @@ -19,12 +19,17 @@ such restriction. */ import { capitalize } from 'lodash' -import { formatDatetime } from './datetime' +import { formatDatetime } from 'igz-controls/utils/datetime.util' import { generateNuclioLink } from './parseUri' +import { saveAndTransformSearchParams } from 'igz-controls/utils/filter.util' +import { MONITORING_APP_PAGE } from '../constants' -export const createApplicationContent = application => { +export const createApplicationContent = (application, projectName) => { const identifierUnique = 'identifierUnique.' + application.name + application.application_class - const nuclioFunctionName = application.nuclio_function_uri.split('/')[2] + + // If the Nuclio function name is generated by Mlrun, it follows the structure bellow + // and is limited to 63 characters + const nuclioFunctionName = `${projectName}-${application.name.toLowerCase()}`.slice(0, 63) return { data: { @@ -40,16 +45,19 @@ export const createApplicationContent = application => { id: `key.${identifierUnique}`, headerId: 'name', headerLabel: 'Name', - value: capitalize(application.name), + value: application.name, className: 'table-cell-name', - getLink: () => application.name + getLink: () => `/projects/${projectName}/${MONITORING_APP_PAGE}/${application.name}${saveAndTransformSearchParams( + window.location.search, + true + )}` }, { id: `lag.${identifierUnique}`, headerId: 'lag', headerLabel: 'Lag', tip: "Number of messages currently waiting in the app's queue", - value: application.stats.lag, + value: application.stats.stream_stats?.lag ?? 0, className: 'table-cell-1' }, { @@ -57,22 +65,22 @@ export const createApplicationContent = application => { headerId: 'commitedOffset', tip: 'Total number of messages handled by the app', headerLabel: 'Commited offset', - value: application.stats.committed_offset, + value: application.stats.stream_stats?.committed ?? 0, className: 'table-cell-2' }, { id: `detections.${identifierUnique}`, headerId: 'detections', headerLabel: 'Detections', - value: application.stats.detections, + value: application.stats.detected, className: 'table-cell-1' }, { id: `possibleDetections.${identifierUnique}`, headerId: 'possibleDetections', headerLabel: 'Possible detections', - value: application.stats.potential_detections, - className: 'table-cell-1' + value: application.stats.potential_detection, + className: 'table-cell-2' }, { id: `class.${identifierUnique}`, @@ -81,13 +89,7 @@ export const createApplicationContent = application => { value: application.application_class, className: 'table-cell-2' }, - { - id: `startedAt.${identifierUnique}`, - headerId: 'startedAt', - headerLabel: 'Started at', - value: formatDatetime(application.started_at, 'N/A'), - className: 'table-cell-2' - }, + { id: `updated.${identifierUnique}`, headerId: 'updated', @@ -99,9 +101,11 @@ export const createApplicationContent = application => { id: `nuclioFunction.${identifierUnique}`, headerId: 'nuclioFunction', headerLabel: 'Nuclio function', - value: nuclioFunctionName, + value: application.name, className: 'table-cell-2', - getLink: () => generateNuclioLink(`/projects/${application.nuclio_function_uri}`), + getLink: () => + generateNuclioLink(`/projects/${projectName}/functions/${nuclioFunctionName}`), + linkIsExternal: true, showStatus: true } ] diff --git a/src/utils/createArtifact.util.js b/src/utils/createArtifact.util.js index 2871924b8b..4daf2c4bdb 100644 --- a/src/utils/createArtifact.util.js +++ b/src/utils/createArtifact.util.js @@ -23,24 +23,35 @@ const artifactSubTitle = const getOverwriteConfirmMessage = (existingKind = '') => `That combination of name and tag is already in use in an existing ${existingKind}. If you proceed, the existing ${existingKind} will be overwritten` -export const createArtifactMessages = { - artifact: { - title: - 'Register an artifact in MLRun so it can be used, for example, by functions, jobs, and pipelines.', - subTitle: artifactSubTitle, - overwriteConfirmTitle: 'Overwrite artifact?', - getOverwriteConfirmMessage - }, - dataset: { - title: - 'Register a dataset as an artifact in MLRun so it can be used, for example, by functions, jobs, and pipelines.', - subTitle: artifactSubTitle, - overwriteConfirmTitle: 'Overwrite dataset?', - getOverwriteConfirmMessage +export const getArtifactMessagesByKind = (kind = '') => { + const messagesByKind = { + artifact: { + title: + 'Register an artifact in MLRun so it can be used, for example, by functions, jobs, and pipelines.', + subTitle: artifactSubTitle, + overwriteConfirmTitle: 'Overwrite artifact?', + getOverwriteConfirmMessage + }, + dataset: { + title: + 'Register a dataset as an artifact in MLRun so it can be used, for example, by functions, jobs, and pipelines.', + subTitle: artifactSubTitle, + overwriteConfirmTitle: 'Overwrite dataset?', + getOverwriteConfirmMessage + }, + model: { + overwriteConfirmTitle: 'Overwrite model?', + getOverwriteConfirmMessage + }, + 'llm-prompt': { + overwriteConfirmTitle: 'Overwrite LLM prompt?', + getOverwriteConfirmMessage + }, + document: { + overwriteConfirmTitle: 'Overwrite document?', + getOverwriteConfirmMessage + } } -} -export const createModelMessages = { - overwriteConfirmTitle: 'Overwrite model?', - getOverwriteConfirmMessage + return messagesByKind[kind.toLowerCase()] ?? messagesByKind['artifact'] } diff --git a/src/utils/createArtifactPreviewContent.js b/src/utils/createArtifactPreviewContent.js index 67a476d8de..404973f5d6 100644 --- a/src/utils/createArtifactPreviewContent.js +++ b/src/utils/createArtifactPreviewContent.js @@ -19,6 +19,8 @@ such restriction. */ import { has, isString } from 'lodash' +import { UNKNOWN_STATE } from '../constants' + const splitStringToArray = str => { return str.split(/,(?! )/g) } @@ -85,7 +87,7 @@ export const createArtifactPreviewContent = ( content: URL.createObjectURL(res.data) } } else { - artifact.type = 'unknown' + artifact.type = UNKNOWN_STATE if (path && artifactName) { artifact.data = { diff --git a/src/utils/createArtifactsContent.jsx b/src/utils/createArtifactsContent.jsx index 96c76bd266..f1d561a531 100644 --- a/src/utils/createArtifactsContent.jsx +++ b/src/utils/createArtifactsContent.jsx @@ -32,17 +32,18 @@ import { ALL_VERSIONS_PATH } from '../constants' import { parseKeyValues } from './object' -import { formatDatetime } from './datetime' import prettyBytes from 'pretty-bytes' import { parseUri } from './parseUri' import { generateLinkToDetailsPanel } from './link-helper.util' import { openPopUp } from 'igz-controls/utils/common.util' +import { formatDatetime } from 'igz-controls/utils/datetime.util' import { validateArguments } from './validateArguments' -// import { roundFloats } from './roundFloats' +// import { roundFloats } from 'igz-controls/utils/common.util' import SeverityOk from 'igz-controls/images/severity-ok.svg?react' -import SeverityWarning from 'igz-controls/images/severity-warning.svg?react' +import SeverityWarning from 'igz-controls/images/severity-low.svg?react' import SeverityError from 'igz-controls/images/severity-error.svg?react' +import TableModelCell from '../elements/TableModelCell/TableModelCell' export const createArtifactsContent = (artifacts, page, pageTab, project, isAllVersions) => { return (artifacts.filter(artifact => !artifact.link_iteration) ?? []).map(artifact => { @@ -138,7 +139,9 @@ export const createModelsRowData = (artifact, project, isAllVersions, metricsCou className: 'table-cell-name', getLink: tab => getArtifactsDetailsLink(artifact, 'models/models', tab, project, isAllVersions), - showTag: true + showTag: true, + showSelectedUid: true, + showUpdatedDate: true }, { id: `labels.${artifact.ui.identifierUnique}`, @@ -193,7 +196,7 @@ export const createModelsRowData = (artifact, project, isAllVersions, metricsCou Framework &
    - Algorithm + algorithm
    ), value: @@ -269,7 +272,9 @@ export const createFilesRowData = (artifact, project, isAllVersions) => { value: isAllVersions ? artifact.uid : artifact.db_key, className: 'table-cell-name', getLink: tab => getArtifactsDetailsLink(artifact, 'files', tab, project, isAllVersions), - showTag: true + showTag: true, + showSelectedUid: true, + showUpdatedDate: true }, { id: `version.${artifact.ui.identifierUnique}`, @@ -347,7 +352,9 @@ export const createDocumentsRowData = (artifact, project, isAllVersions) => { value: isAllVersions ? artifact.uid : artifact.db_key, className: 'table-cell-name', getLink: tab => getArtifactsDetailsLink(artifact, 'documents', tab, project, isAllVersions), - showTag: true + showTag: true, + showSelectedUid: true, + showUpdatedDate: true }, { id: `updated.${artifact.ui.identifierUnique}`, @@ -391,7 +398,7 @@ export const createDocumentsRowData = (artifact, project, isAllVersions) => { } } -const getDriftStatusData = driftStatus => { +export const getDriftStatusData = driftStatus => { switch (String(driftStatus)) { case '0': case 'NO_DRIFT': @@ -408,7 +415,7 @@ const getDriftStatusData = driftStatus => { case 'POSSIBLE_DRIFT': return { value: ( - + ), @@ -492,7 +499,7 @@ export const createModelEndpointsRowData = (artifact, project) => { { id: `functionTag.${artifact.ui.identifierUnique}`, headerId: 'functionTag', - headerLabel: 'Function Tag', + headerLabel: 'Function tag', value: artifact.spec?.function_tag, className: 'table-cell-small' }, @@ -557,7 +564,9 @@ export const createDatasetsRowData = (artifact, project, isAllVersions) => { value: isAllVersions ? artifact.uid : artifact.db_key, className: 'table-cell-name', getLink: tab => getArtifactsDetailsLink(artifact, 'datasets', tab, project, isAllVersions), - showTag: true + showTag: true, + showSelectedUid: true, + showUpdatedDate: true }, { id: `labels.${artifact.ui.identifierUnique}`, @@ -629,7 +638,24 @@ export const createLLMPromptsRowData = (artifact, project, isAllVersions) => { className: 'table-cell-name', getLink: tab => getArtifactsDetailsLink(artifact, 'llm-prompts', tab, project, isAllVersions), - showTag: true + showTag: true, + showSelectedUid: true, + showUpdatedDate: true + }, + { + id: `model.${artifact.ui.identifierUnique}`, + headerId: 'modelName', + headerLabel: 'Model name', + value: artifact.parent_uri || '', + template: ( + + ), + className: 'table-cell-1', + type: 'modelName' }, { id: `labels.${artifact.ui.identifierUnique}`, diff --git a/src/utils/createFeatureStoreContent.jsx b/src/utils/createFeatureStoreContent.jsx index 9be2785e89..da7c595801 100644 --- a/src/utils/createFeatureStoreContent.jsx +++ b/src/utils/createFeatureStoreContent.jsx @@ -26,16 +26,14 @@ import FeatureSetPopUp from '../elements/DetailsPopUp/FeatureSetPopUp/FeatureSet import { FEATURE_STORE_PAGE, FEATURE_SETS_TAB, - FEATURE_VECTORS_TAB, - BUTTON_COPY_URI_CELL_TYPE + FEATURE_VECTORS_TAB } from '../constants' -import { parseKeyValues } from './object' -import { formatDatetime } from './datetime' -import { generateUri } from './resources' -import { truncateUid } from '../utils' +import { formatDatetime } from 'igz-controls/utils/datetime.util' import { generateLinkToDetailsPanel } from './link-helper.util' -import { validateArguments } from './validateArguments' import { openPopUp } from 'igz-controls/utils/common.util' +import { parseKeyValues } from './object' +import { truncateUid } from 'igz-controls/utils/string.util' +import { validateArguments } from './validateArguments' import Nosql from 'igz-controls/images/nosql.svg?react' import Stream from 'igz-controls/images/stream.svg?react' @@ -126,14 +124,6 @@ export const createFeatureSetsRowData = (featureSet, project, pageTab, showExpan headerLabel: 'Updated', value: featureSet.updated ? formatDatetime(featureSet.updated, 'N/A') : 'N/A', className: 'table-cell-2' - }, - { - id: `buttonCopy.${featureSet.ui.identifierUnique}`, - headerId: 'copy', - value: '', - className: 'table-cell-icon', - type: BUTTON_COPY_URI_CELL_TYPE, - actionHandler: item => generateUri(item, null, pageTab) } ] } @@ -148,7 +138,7 @@ export const createFeaturesRowData = (feature, isTablePanelOpen, showExpandButto { id: `key.${feature.ui.identifierUnique}`, headerId: 'featurename', - headerLabel: 'Feature Name', + headerLabel: 'Feature name', type: feature.ui.type, value: feature.name, className: 'table-cell-name', @@ -344,14 +334,6 @@ export const createFeatureVectorsRowData = (featureVector, pageTab, project, sho showTag: true, showStatus: true }, - { - id: `buttonCopy.${featureVector.ui.identifierUnique}`, - headerId: 'copy', - value: '', - className: 'table-cell-icon', - type: BUTTON_COPY_URI_CELL_TYPE, - actionHandler: item => generateUri(item, null, pageTab) - }, { id: `uid.${featureVector.ui.identifierUnique}`, headerId: 'featurevectoruid', diff --git a/src/utils/createFunctionsRowData.js b/src/utils/createFunctionsRowData.js index 46e5a3837f..ae7d95ac29 100644 --- a/src/utils/createFunctionsRowData.js +++ b/src/utils/createFunctionsRowData.js @@ -17,9 +17,10 @@ illegal under applicable law, and the grant of the foregoing license under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ -import { formatDatetime } from './datetime' +import { formatDatetime } from 'igz-controls/utils/datetime.util' import { getFunctionImage } from '../components/FunctionsPage/functions.util' import { ALL_VERSIONS_PATH } from '../constants' +import { typesOfJob } from './jobs.util' const createFunctionsRowData = (func, projectName, isAllVersions, showExpandButton, oldVersion) => { return { @@ -49,6 +50,8 @@ const createFunctionsRowData = (func, projectName, isAllVersions, showExpandButt showStatus: true }, showTag: true, + showSelectedUid: true, + showUpdatedDate: true, showStatus: true, showExpandButton }, @@ -58,7 +61,8 @@ const createFunctionsRowData = (func, projectName, isAllVersions, showExpandButt headerLabel: 'Kind', value: func.type, className: 'table-cell-small', - type: 'type' + type: 'type', + types: typesOfJob }, { id: `hash.${func.ui.identifierUnique}`, @@ -82,7 +86,7 @@ const createFunctionsRowData = (func, projectName, isAllVersions, showExpandButt { id: `command.${func.ui.identifierUnique}`, headerId: 'command', - headerLabel: 'Code Entry Point', + headerLabel: 'Code entry point', value: func.command, className: 'table-cell-2' }, diff --git a/src/utils/createJobsContent.js b/src/utils/createJobsContent.js index 492fe80ad5..d2444f8b0d 100644 --- a/src/utils/createJobsContent.js +++ b/src/utils/createJobsContent.js @@ -31,7 +31,8 @@ import { MONITOR_JOBS_TAB, MONITOR_WORKFLOWS_TAB, NAME_FILTER, - PROJECT_FILTER + PROJECT_FILTER, + RUNNING_STATE } from '../constants' import { openPopUp } from 'igz-controls/utils/common.util' import { @@ -39,13 +40,13 @@ import { getWorkflowMonitoringDetailsLink } from '../components/Workflow/workflow.util' import { measureTime } from './measureTime' -import { formatDatetime } from './datetime' import { generateLinkToDetailsPanel } from './link-helper.util' import { getJobIdentifier, getWorkflowJobIdentifier } from './getUniqueIdentifier' import { parseKeyValues } from './object' import { validateArguments } from './validateArguments' -import { getJobKindFromLabels } from './jobs.util' -import { saveAndTransformSearchParams } from './filter.util' +import { getJobKindFromLabels, typesOfJob } from './jobs.util' +import { saveAndTransformSearchParams } from 'igz-controls/utils/filter.util' +import { formatDatetime } from 'igz-controls/utils/datetime.util' export const createJobsMonitorTabContent = (jobs, jobName, isStagingMode) => { return jobs.map(job => { @@ -94,7 +95,8 @@ export const createJobsMonitorTabContent = (jobs, jobName, isStagingMode) => { type: type === JOB_KIND_WORKFLOW && !isStagingMode ? 'hidden' : 'link', getLink, showStatus: true, - showUidRow: true + showUid: true, + showDate: true }, { headerId: 'type', @@ -102,7 +104,8 @@ export const createJobsMonitorTabContent = (jobs, jobName, isStagingMode) => { id: `type.${identifierUnique}`, value: type, className: 'table-cell-1', - type: 'type' + type: 'type', + types: typesOfJob }, { headerId: 'job.uid', @@ -117,7 +120,7 @@ export const createJobsMonitorTabContent = (jobs, jobName, isStagingMode) => { id: `duration.${identifierUnique}`, value: measureTime( job.startTime || new Date(job.created_at), - (job.state?.value !== 'running' && job.updated) || + (job.state?.value !== RUNNING_STATE && job.updated) || (job.state?.value !== ERROR_STATE && new Date(job.finished_at)) ), className: 'table-cell-1', @@ -160,6 +163,14 @@ export const createJobsMonitorTabContent = (jobs, jobName, isStagingMode) => { value: job.updated || new Date(job.finished_at), className: 'table-cell-1', type: 'hidden' + }, + { + headerId: 'attempts', + headerLabel: 'Attempts', + id: `attempts.${identifierUnique}`, + value: `${job.retryCountWithInitialAttempt} out of ${job.maxRetriesWithInitialAttempt}`, + className: 'table-cell-1', + tip: 'Number of attempts to run Kubernetes jobs' } ] } @@ -201,7 +212,8 @@ export const createJobsScheduleTabContent = jobs => { id: `type.${identifierUnique}`, value: job.type, className: 'table-cell-small', - type: 'type' + type: 'type', + types: typesOfJob }, { headerId: 'nextrun', @@ -320,7 +332,7 @@ export const createJobsWorkflowsTabContent = (jobs, projectName, isStagingMode, id: `duration.${identifierUnique}`, value: measureTime( job.startTime || new Date(job.created_at), - (job.state?.value !== 'running' && job.updated) || + (job.state?.value !== RUNNING_STATE && job.updated) || (job.state?.value !== ERROR_STATE && new Date(job.finished_at)) ), className: 'table-cell-1', @@ -386,7 +398,8 @@ export const createJobsWorkflowContent = ( ) }, showStatus: true, - showUidRow: true + showUid: true, + showDate: true }, { headerId: 'kind', @@ -395,6 +408,7 @@ export const createJobsWorkflowContent = ( value: job.run_type, className: 'table-cell-1', type: 'type', + types: typesOfJob, hidden: isSelectedItem }, { @@ -451,7 +465,7 @@ export const createJobsMonitoringContent = (jobs, jobName, isStagingMode) => { const savedAndTransformedSearchParams = saveAndTransformSearchParams( window.location.search, true, - [BE_PAGE, FE_PAGE, NAME_FILTER] + [BE_PAGE, FE_PAGE, NAME_FILTER, PROJECT_FILTER] ) return `/projects/*/${JOBS_MONITORING_PAGE}/${JOBS_MONITORING_JOBS_TAB}/${job.name}${savedAndTransformedSearchParams}${savedAndTransformedSearchParams ? '&' : '?'}${`${PROJECT_FILTER}=${job.project}`}` @@ -477,7 +491,8 @@ export const createJobsMonitoringContent = (jobs, jobName, isStagingMode) => { type: type === JOB_KIND_WORKFLOW && !isStagingMode ? 'hidden' : 'link', getLink, showStatus: true, - showUidRow: true + showUid: true, + showDate: true }, { headerId: 'projectName', @@ -492,7 +507,8 @@ export const createJobsMonitoringContent = (jobs, jobName, isStagingMode) => { id: `type.${identifierUnique}`, value: type, className: 'table-cell-1', - type: 'type' + type: 'type', + types: typesOfJob }, { headerId: 'job.uid', @@ -514,7 +530,7 @@ export const createJobsMonitoringContent = (jobs, jobName, isStagingMode) => { id: `duration.${identifierUnique}`, value: measureTime( job.startTime || new Date(job.created_at), - (job.state?.value !== 'running' && job.updated) || + (job.state?.value !== RUNNING_STATE && job.updated) || (job.state?.value !== ERROR_STATE && new Date(job.finished_at)) ), className: 'table-cell-1', @@ -549,6 +565,14 @@ export const createJobsMonitoringContent = (jobs, jobName, isStagingMode) => { value: job.updated || new Date(job.finished_at), className: 'table-cell-1', type: 'hidden' + }, + { + headerId: 'attempts', + headerLabel: 'Attempts', + id: `attempts.${identifierUnique}`, + value: `${job.retryCountWithInitialAttempt} out of ${job.maxRetriesWithInitialAttempt}`, + className: 'table-cell-1', + tip: 'Number of attempts to run Kubernetes jobs' } ] } @@ -597,7 +621,8 @@ export const createScheduleJobsMonitoringContent = jobs => { id: `type.${identifierUnique}`, value: job.type, className: 'table-cell-small', - type: 'type' + type: 'type', + types: typesOfJob }, { headerId: 'nextrun', @@ -723,7 +748,7 @@ export const createWorkflowsMonitoringContent = (jobs, isStagingMode, isSelected id: `duration.${identifierUnique}`, value: measureTime( job.startTime || new Date(job.created_at), - (job.state?.value !== 'running' && job.updated) || + (job.state?.value !== RUNNING_STATE && job.updated) || (job.state?.value !== ERROR_STATE && new Date(job.finished_at)) ), className: 'table-cell-1', diff --git a/src/utils/createRealTimePipelinesContent.js b/src/utils/createRealTimePipelinesContent.js index 72d60c460f..dd161cafba 100644 --- a/src/utils/createRealTimePipelinesContent.js +++ b/src/utils/createRealTimePipelinesContent.js @@ -19,9 +19,10 @@ such restriction. */ import FunctionPopUp from '../elements/DetailsPopUp/FunctionPopUp/FunctionPopUp' -import { formatDatetime } from './datetime' +import { formatDatetime } from 'igz-controls/utils/datetime.util' import { openPopUp } from 'igz-controls/utils/common.util' import { MODELS_PAGE, REAL_TIME_PIPELINES_TAB } from '../constants' +import { typesOfJob } from './jobs.util' const createRealTimePipelinesContent = (pipelines, projectName) => pipelines.map(pipeline => { @@ -55,7 +56,8 @@ const createRealTimePipelinesContent = (pipelines, projectName) => headerLabel: 'Type', value: pipeline.graph?.kind === 'router' ? 'Router' : 'Flow', className: 'table-cell-small', - type: 'type' + type: 'type', + types: typesOfJob }, { id: `function.${pipeline.ui.identifierUnique}`, diff --git a/src/utils/datetime.js b/src/utils/datetime.js deleted file mode 100755 index e24a345d7f..0000000000 --- a/src/utils/datetime.js +++ /dev/null @@ -1,93 +0,0 @@ -/* -Copyright 2019 Iguazio Systems Ltd. - -Licensed under the Apache License, Version 2.0 (the "License") with -an addition restriction as set forth herein. You may not use this -file except in compliance with the License. You may obtain a copy of -the License at http://www.apache.org/licenses/LICENSE-2.0. - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -implied. See the License for the specific language governing -permissions and limitations under the License. - -In addition, you may not use the software for any purposes that are -illegal under applicable law, and the grant of the foregoing license -under the Apache 2.0 license is conditioned upon your compliance with -such restriction. -*/ -import moment from 'moment' - -export const formatDatetime = (datetime, invalidDateMessage) => { - if (!datetime) { - return invalidDateMessage - } - - const date = new Date(datetime) - - return typeof date !== 'object' || !(date instanceof Date) || isNaN(date) - ? invalidDateMessage - : new Intl.DateTimeFormat('en-US', { - year: 'numeric', - month: 'short', - day: 'numeric', - hour: '2-digit', - minute: '2-digit', - second: '2-digit' - }).format(date) -} - -export const getFormatTime = time => { - const [hour, minute] = time.split(':') - if (!minute) { - return { - hour: '0', - minute: '0' - } - } - return { - hour: hour.replace(/_/g, '0'), - minute: minute.replace(/_/g, '0') - } -} - -export const getTimeElapsedByDate = creationDate => { - moment.updateLocale('en', { - relativeTime: { - future: 'in %s', - past: '%s ago', - s: 'a few seconds', - ss: '%d seconds', - m: 'a minute', - mm: '%d minutes', - h: 'an hour', - hh: '%d hours', - d: 'a day', - dd: '%d days', - w: 'a week', - ww: '%d weeks', - M: 'a month', - MM: '%d months', - y: 'a year', - yy: '%d years' - } - }) - - const time = moment.utc(creationDate) - - return time.fromNow() -} - -export const getDateAndTimeByFormat = (date, dateFormat) => { - return moment(date).format(dateFormat) -} - -export const sortListByDate = (list = [], field, isAscending = true) => { - return [...list].sort((prevElem, nextElem) => { - const prev = Date.parse(prevElem[field]) - const next = Date.parse(nextElem[field]) - - return isAscending ? prev - next : next - prev - }) -} diff --git a/src/utils/filter.util.js b/src/utils/filter.util.js deleted file mode 100644 index b61623c7df..0000000000 --- a/src/utils/filter.util.js +++ /dev/null @@ -1,56 +0,0 @@ -/* -Copyright 2019 Iguazio Systems Ltd. - -Licensed under the Apache License, Version 2.0 (the "License") with -an addition restriction as set forth herein. You may not use this -file except in compliance with the License. You may obtain a copy of -the License at http://www.apache.org/licenses/LICENSE-2.0. - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -implied. See the License for the specific language governing -permissions and limitations under the License. - -In addition, you may not use the software for any purposes that are -illegal under applicable law, and the grant of the foregoing license -under the Apache 2.0 license is conditioned upon your compliance with -such restriction. -*/ - -const SAVED_PARAMS = 'savedParams' - -export const getSavedSearchParams = searchParams => { - return atob(new URLSearchParams(searchParams)?.get(SAVED_PARAMS) ?? '') ?? '' -} - -export const saveAndTransformSearchParams = ( - searchParams, - includeSearchParams = false, - excludeParamsNames = [] -) => { - let newSearchParams = '?' - - if (includeSearchParams) { - const filteredNewSearchParams = getFilteredSearchParams(searchParams, excludeParamsNames) - newSearchParams = filteredNewSearchParams ? `${filteredNewSearchParams}&` : newSearchParams - } - - return searchParams ? `${newSearchParams}${SAVED_PARAMS}=${btoa(searchParams)}` : '' -} - -export const transformSearchParams = params => { - return params ? `${SAVED_PARAMS}=${btoa(params)}` : '' -} - -export const getFilteredSearchParams = (searchParams, excludeParamsNames = []) => { - const params = new URLSearchParams(searchParams) - - excludeParamsNames.forEach(paramName => params.delete(paramName)) - - const newSearchParams = params.toString() - - if (!newSearchParams) return '' - - return `?${newSearchParams}` -} diff --git a/src/utils/generateAlertsStats.js b/src/utils/generateAlertsStats.js index c3553871f0..274184d353 100644 --- a/src/utils/generateAlertsStats.js +++ b/src/utils/generateAlertsStats.js @@ -35,19 +35,19 @@ export const generateAlertsStats = (data, navigate, projectName) => { return { total: { - counter: data.total, + counter: data.total ?? 'N/A', link: () => navigateToAlertsPage({}) }, job: { - counter: data.job, + counter: data.jobs ?? 'N/A', link: () => navigateToAlertsPage({ [ENTITY_TYPE]: JOB }) }, endpoints: { - counter: data.endpoint, + counter: data.endpoint ?? 'N/A', link: () => navigateToAlertsPage({ [ENTITY_TYPE]: MODEL_ENDPOINT_RESULT }) }, application: { - counter: data.application, + counter: data.application ?? 'N/A', link: () => navigateToAlertsPage({ [ENTITY_TYPE]: MODEL_MONITORING_APPLICATION }) } } diff --git a/src/utils/generateMonitoringData.js b/src/utils/generateMonitoringData.js index ff22e8cd73..0b41247558 100644 --- a/src/utils/generateMonitoringData.js +++ b/src/utils/generateMonitoringData.js @@ -17,111 +17,278 @@ illegal under applicable law, and the grant of the foregoing license under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ +import { generateTypeFilter } from '../components/FilterMenu/filterMenu.settings' + import { + APPLICATION, + ARTIFACTS_PAGE, DATES_FILTER, + ERROR_STATE, + FAILED_STATE, FILTER_ALL_ITEMS, JOBS_MONITORING_JOBS_TAB, JOBS_MONITORING_PAGE, + JOBS_MONITORING_SCHEDULED_TAB, JOBS_MONITORING_WORKFLOWS_TAB, - JOB_KIND_JOB, JOB_KIND_WORKFLOW, + MODELS_PAGE, + MONITORING_APP_PAGE, + MONITOR_WORKFLOWS_TAB, STATUS_FILTER, TYPE_FILTER, - ERROR_STATE, - FAILED_STATE + PENDING_STATE, + RUNNING_STATE, + COMPLETED_STATE, + ABORTED_STATE, + ABORTING_STATE, + PENDING_RETRY_STATE, + TERMINATING_STATE } from '../constants' -import { ANY_TIME_DATE_OPTION } from './datePicker.util' +import { + ANY_TIME_DATE_OPTION, + PAST_24_HOUR_DATE_OPTION, + NEXT_24_HOUR_DATE_OPTION +} from './datePicker.util' +import classNames from 'classnames' -const IN_PROCESS = 'In Process' +const IN_PROCESS = 'In process' const FAILED = 'Failed' const SUCCEEDED = 'Succeeded' +const RUNNING = 'Running' + +export const generateMonitoringStats = (data, navigate, tab, projectName) => { + const linkClassNameDetails = (projectName, noLine) => + classNames(!noLine && 'stats__line', projectName && 'stats__link') + + const linkClassNameHeader = projectName => classNames(projectName && 'stats__link') + + const navigateToTab = (projectName, tab) => { + projectName && navigate(`/projects/${projectName}/${tab}`) + } -export const generateMonitoringStats = (data, navigate, tab) => { const navigateToJobsMonitoringPage = (filters = {}) => { - navigate(`/projects/*/${JOBS_MONITORING_PAGE}/${tab}?${new URLSearchParams(filters)}`) + projectName + ? navigate(`/projects/${projectName}/jobs/${tab}?${new URLSearchParams(filters)}`) + : navigate(`/projects/*/${JOBS_MONITORING_PAGE}/${tab}?${new URLSearchParams(filters)}`) } return tab === JOBS_MONITORING_JOBS_TAB ? { total: { - counter: data.total || 0, - link: () => navigateToJobsMonitoringPage({ [STATUS_FILTER]: [FILTER_ALL_ITEMS] }) + counter: data.total ?? 'N/A', + link: () => + navigateToJobsMonitoringPage({ + [STATUS_FILTER]: [FILTER_ALL_ITEMS], + [DATES_FILTER]: PAST_24_HOUR_DATE_OPTION + }) }, counters: [ { - counter: data.running || 0, + counter: data.running ?? 'N/A', + className: classNames('stats__link', 'stats__line'), link: () => navigateToJobsMonitoringPage({ - [STATUS_FILTER]: ['running', 'pending', 'aborting'], + [STATUS_FILTER]: [ + RUNNING_STATE, + PENDING_STATE, + PENDING_RETRY_STATE, + ABORTING_STATE + ], [DATES_FILTER]: ANY_TIME_DATE_OPTION }), - statusClass: 'running', - tooltip: 'Aborting, Pending, Running', + statusClass: RUNNING_STATE, + tooltip: 'Aborting, Pending, Pending retry, Running', label: IN_PROCESS }, { - counter: data.failed || 0, - link: () => navigateToJobsMonitoringPage({ [STATUS_FILTER]: [ERROR_STATE, 'aborted'] }), - statusClass: 'failed', + counter: data.failed ?? 'N/A', + className: classNames('stats__link', 'stats__line'), + link: () => + navigateToJobsMonitoringPage({ + [STATUS_FILTER]: [ERROR_STATE, ABORTED_STATE], + [DATES_FILTER]: PAST_24_HOUR_DATE_OPTION + }), + statusClass: FAILED_STATE, tooltip: 'Aborted, Error', - label: FAILED + label: FAILED, + counterClassName: classNames({ + stats__failed: data.failed > 0 + }) }, { - counter: data.completed || 0, - link: () => navigateToJobsMonitoringPage({ [STATUS_FILTER]: ['completed'] }), - statusClass: 'completed', + counter: data.completed ?? 'N/A', + className: classNames('stats__link', 'stats__line'), + link: () => + navigateToJobsMonitoringPage({ + [STATUS_FILTER]: [COMPLETED_STATE], + [DATES_FILTER]: PAST_24_HOUR_DATE_OPTION + }), + statusClass: COMPLETED_STATE, tooltip: 'Completed', label: SUCCEEDED } ] } - : tab === JOBS_MONITORING_WORKFLOWS_TAB + : [JOBS_MONITORING_WORKFLOWS_TAB, MONITOR_WORKFLOWS_TAB].includes(tab) ? { total: { - counter: data.total || 0, - link: () => navigateToJobsMonitoringPage({ [STATUS_FILTER]: [FILTER_ALL_ITEMS] }) + counter: data.total ?? 'N/A', + link: () => + navigateToJobsMonitoringPage({ + [STATUS_FILTER]: [FILTER_ALL_ITEMS], + [DATES_FILTER]: PAST_24_HOUR_DATE_OPTION + }) }, counters: [ { - counter: data.running || 0, + counter: data.running ?? 'N/A', link: () => navigateToJobsMonitoringPage({ - [STATUS_FILTER]: ['running'], + [STATUS_FILTER]: [RUNNING_STATE, TERMINATING_STATE], [DATES_FILTER]: ANY_TIME_DATE_OPTION }), - statusClass: 'running', - tooltip: 'Running', + className: classNames('stats__link', 'stats__line'), + statusClass: RUNNING_STATE, + tooltip: 'Running, Terminating', label: IN_PROCESS }, { - counter: data.failed || 0, + counter: data.failed ?? 'N/A', + className: classNames('stats__link', 'stats__line'), link: () => - navigateToJobsMonitoringPage({ [STATUS_FILTER]: [ERROR_STATE, FAILED_STATE] }), - statusClass: 'failed', + navigateToJobsMonitoringPage({ + [STATUS_FILTER]: [ERROR_STATE, FAILED_STATE], + [DATES_FILTER]: PAST_24_HOUR_DATE_OPTION + }), + statusClass: FAILED_STATE, tooltip: 'Error, Failed', - label: FAILED + label: FAILED, + counterClassName: classNames({ + stats__failed: data.failed > 0 + }) }, { - counter: data.completed || 0, - link: () => navigateToJobsMonitoringPage({ [STATUS_FILTER]: ['completed'] }), - statusClass: 'completed', + counter: data.completed ?? 'N/A', + className: classNames('stats__link', 'stats__line'), + link: () => + navigateToJobsMonitoringPage({ + [STATUS_FILTER]: [COMPLETED_STATE], + [DATES_FILTER]: PAST_24_HOUR_DATE_OPTION + }), + statusClass: COMPLETED_STATE, tooltip: 'Completed', label: SUCCEEDED } ] } - : { - total: { - counter: data.total || 0, - link: () => navigateToJobsMonitoringPage({ [TYPE_FILTER]: FILTER_ALL_ITEMS }, {}) - }, - jobs: { - counter: data.jobs || 0, - link: () => navigateToJobsMonitoringPage({ [TYPE_FILTER]: JOB_KIND_JOB }, {}) - }, - workflows: { - counter: data.workflows || 0, - link: () => navigateToJobsMonitoringPage({ [TYPE_FILTER]: JOB_KIND_WORKFLOW }, {}) + : tab === ARTIFACTS_PAGE + ? { + total: { + counter: data.total ?? 'N/A' + }, + datasets: { + counter: data.datasets ?? 'N/A', + link: () => navigateToTab(projectName, 'datasets'), + className: linkClassNameDetails(projectName) + }, + documents: { + counter: data.documents ?? 'N/A', + link: () => navigateToTab(projectName, 'documents'), + className: linkClassNameDetails(projectName) + }, + llm_prompt: { + counter: data.llm_prompts ?? 'N/A', + link: () => navigateToTab(projectName, 'llm-prompts'), + className: linkClassNameDetails(projectName) + }, + files: { + counter: data.files ?? 'N/A', + link: () => navigateToTab(projectName, 'files'), + className: linkClassNameDetails(projectName) + }, + list: [ + { key: 'datasets', label: 'Datasets' }, + { key: 'documents', label: 'Documents' }, + { key: 'llm_prompt', label: 'LLM prompt artifacts' }, + { key: 'files', label: 'Other artifacts' } + ] } - } + : tab === MODELS_PAGE + ? { + models: { + counter: data ?? 'N/A', + link: () => navigateToTab(projectName, 'models'), + className: linkClassNameHeader(projectName) + } + } + : tab === APPLICATION + ? { + total: { + counter: data.total ?? 'N/A', + link: () => navigateToTab(projectName, MONITORING_APP_PAGE), + className: `stats__counter_total ${linkClassNameHeader(projectName)}` + }, + counters: [ + { + counter: data.running ?? 'N/A', + className: classNames(projectName && 'stats__link'), + link: () => navigateToTab(projectName, MONITORING_APP_PAGE), + statusClass: RUNNING_STATE, + label: RUNNING, + popUpClassName: classNames({ 'card-popup_text_link': projectName }), + tooltip: RUNNING + }, + { + counter: data.failed ?? 'N/A', + className: classNames(projectName && 'stats__link', { + stats__failed: data.failed > 0 + }), + link: () => navigateToTab(projectName, MONITORING_APP_PAGE), + statusClass: FAILED_STATE, + label: FAILED, + popUpClassName: classNames({ 'card-popup_text_link': projectName }), + tooltip: 'Error, Unhealthy' + } + ] + } + : { + total: { + counter: data.total ?? 'N/A', + link: () => + navigateToJobsMonitoringPage({ + [TYPE_FILTER]: FILTER_ALL_ITEMS, + [DATES_FILTER]: NEXT_24_HOUR_DATE_OPTION + }) + }, + jobs: { + counter: data.jobs ?? 'N/A', + link: () => + navigateToJobsMonitoringPage({ + [TYPE_FILTER]: generateTypeFilter(JOBS_MONITORING_SCHEDULED_TAB) + .filter( + type => + type.id !== JOB_KIND_WORKFLOW && + type.id !== FILTER_ALL_ITEMS && + !type.hidden + ) + .map(item => item.id) + .join(','), + [DATES_FILTER]: NEXT_24_HOUR_DATE_OPTION + }) + }, + workflows: { + counter: data.workflows ?? 'N/A', + link: () => + navigateToJobsMonitoringPage({ + [TYPE_FILTER]: JOB_KIND_WORKFLOW, + [DATES_FILTER]: NEXT_24_HOUR_DATE_OPTION + }) + } + } +} + +export const countTotalValue = (values = []) => { + if (values.every(element => typeof element !== 'number')) return 'N/A' + + return values.reduce((acc, element) => acc + (typeof element === 'number' ? element : 0), 0) } diff --git a/src/utils/generatePods.jsx b/src/utils/generatePods.jsx index 250a0274f6..91bd7b0b4c 100644 --- a/src/utils/generatePods.jsx +++ b/src/utils/generatePods.jsx @@ -19,17 +19,19 @@ such restriction. */ import React from 'react' +import { PENDING_STATE } from '../constants' + export const generatePods = (project, uid, pods) => { const podsList = pods?.[project]?.[uid]?.pod_resources ?? [] const podsTooltip = podsList.map((value, index) => (

    {value?.name} - {value?.status?.phase?.toLowerCase?.() === 'pending' + {value?.status?.phase?.toLowerCase?.() === PENDING_STATE ? ' (pending...)' : (value?.status?.phase?.toLowerCase ?? '')}

    )) - const podsPending = podsList.filter(pod => pod?.status?.phase?.toLowerCase?.() === 'pending') + const podsPending = podsList.filter(pod => pod?.status?.phase?.toLowerCase?.() === PENDING_STATE) return { podsList, diff --git a/src/utils/getArtifactPreview.jsx b/src/utils/getArtifactPreview.jsx index d30fe9c26d..6cdce1792c 100644 --- a/src/utils/getArtifactPreview.jsx +++ b/src/utils/getArtifactPreview.jsx @@ -17,13 +17,18 @@ illegal under applicable law, and the grant of the foregoing license under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ -import { TextTooltipTemplate, Tooltip } from 'igz-controls/components' -import CopyToClipboard from '../common/CopyToClipboard/CopyToClipboard' +import { TextTooltipTemplate, Tooltip, CopyToClipboard } from 'igz-controls/components' import Download from '../common/Download/Download' import api from '../api/artifacts-api' import { createArtifactPreviewContent } from './createArtifactPreviewContent' -import { ARTIFACT_MAX_CHUNK_SIZE, DEFAULT_ABORT_MSG, REQUEST_CANCELED } from '../constants' +import { + ARTIFACT_MAX_CHUNK_SIZE, + DEFAULT_ABORT_MSG, + ERROR_STATE, + REQUEST_CANCELED, + UNKNOWN_STATE +} from '../constants' const fileSizes = { '100KB': 102400, @@ -165,7 +170,7 @@ export const fetchArtifactPreviewFromPath = async ( : 'preview, use the download option instead' }` }, - type: 'unknown' + type: UNKNOWN_STATE } ]) } else { @@ -196,7 +201,7 @@ export const fetchArtifactPreviewFromPath = async ( body: err.response ? JSON.stringify(err.response, null, 2) : '' }, content: [], - type: 'error' + type: ERROR_STATE } ]) } diff --git a/src/utils/getChartConfig.jsx b/src/utils/getChartConfig.jsx index f161efab82..b0c5f10ac6 100644 --- a/src/utils/getChartConfig.jsx +++ b/src/utils/getChartConfig.jsx @@ -106,7 +106,23 @@ const setMetricChartText = (context, tooltipModel, tooltipEl, chartType) => { } } -const generateCustomTooltip = (context, applicationChartType) => { +const setMEPWithDetectionChartText = (context, tooltipModel, tooltipEl) => { + if (tooltipModel.body) { + let innerHtml = '
    ' + const fullDate = + context.tooltip.dataPoints[0].dataset?.dates?.[context.tooltip.dataPoints[0].dataIndex] + + innerHtml += `
    Date: ${fullDate}
    ` + innerHtml += `
    Value: ${context.tooltip.dataPoints[0].raw}
    ` + + innerHtml += '
    ' + + const divRoot = tooltipEl.querySelector('div') + divRoot.innerHTML = innerHtml + } +} + +const generateCustomTooltip = (context, applicationChartType, setText = setMetricChartText) => { // ChartJs type const chartType = context.tooltip.dataPoints[0].dataset.chartType @@ -134,12 +150,7 @@ const generateCustomTooltip = (context, applicationChartType) => { return } - // Set Text - if (applicationChartType === CHART_TYPE_HISTOGRAM) { - setHistogramChartText(context, tooltipModel, tooltipEl) - } else { - setMetricChartText(context, tooltipModel, tooltipEl, chartType) - } + setText(context, tooltipModel, tooltipEl, chartType) // Display, position, and set styles for font const position = context.chart.canvas.getBoundingClientRect() @@ -238,6 +249,10 @@ export const getMetricChartConfig = type => { const barOptions = { ...defaultOptions, barThickness: 20, + borderRadius: { + topLeft: 4, + topRight: 4 + }, scales: { ...defaultOptions.scales, x: { @@ -297,7 +312,8 @@ export const getHistogramChartConfig = () => { }, tooltip: { enabled: false, - external: context => generateCustomTooltip(context, CHART_TYPE_HISTOGRAM), + external: context => + generateCustomTooltip(context, CHART_TYPE_HISTOGRAM, setHistogramChartText), mode: 'index', intersect: false, callbacks: { @@ -312,3 +328,40 @@ export const getHistogramChartConfig = () => { } } } + +export const getMEPsWithDetectionChartConfig = () => { + const barConfig = getMetricChartConfig(CHART_TYPE_BAR) + + return { + ...barConfig, + options: { + ...barConfig.options, + scales: { + ...barConfig.options.scales, + x: { + ...barConfig.options.scales.x, + title: { + display: false + } + }, + y: { + ...barConfig.options.scales.y, + title: { + ...barConfig.options.scales.y.title, + text: 'Model endpoints' + } + } + }, + plugins: { + ...barConfig.options.plugins, + tooltip: { + enabled: false, + intersect: false, + mode: 'index', + external: context => + generateCustomTooltip(context, null, setMEPWithDetectionChartText), + } + } + } + } +} diff --git a/src/utils/getChipLabelAndValue.js b/src/utils/getChipLabelAndValue.js deleted file mode 100644 index a290ad164d..0000000000 --- a/src/utils/getChipLabelAndValue.js +++ /dev/null @@ -1,30 +0,0 @@ -/* -Copyright 2019 Iguazio Systems Ltd. - -Licensed under the Apache License, Version 2.0 (the "License") with -an addition restriction as set forth herein. You may not use this -file except in compliance with the License. You may obtain a copy of -the License at http://www.apache.org/licenses/LICENSE-2.0. - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -implied. See the License for the specific language governing -permissions and limitations under the License. - -In addition, you may not use the software for any purposes that are -illegal under applicable law, and the grant of the foregoing license -under the Apache 2.0 license is conditioned upon your compliance with -such restriction. -*/ -import { roundFloats } from './roundFloats' - -export const getChipLabelAndValue = chip => { - const indexOfDelimiter = chip.value.indexOf(':') - const value = chip.value.slice(indexOfDelimiter + 1) - - return { - chipLabel: indexOfDelimiter > 0 ? chip.value.slice(0, indexOfDelimiter) : chip.value, - chipValue: indexOfDelimiter > 0 ? (Number.isInteger(value) ? roundFloats(value) : value) : '' - } -} diff --git a/src/utils/getChipOptions.js b/src/utils/getChipOptions.js deleted file mode 100644 index c9d9698946..0000000000 --- a/src/utils/getChipOptions.js +++ /dev/null @@ -1,68 +0,0 @@ -/* -Copyright 2019 Iguazio Systems Ltd. - -Licensed under the Apache License, Version 2.0 (the "License") with -an addition restriction as set forth herein. You may not use this -file except in compliance with the License. You may obtain a copy of -the License at http://www.apache.org/licenses/LICENSE-2.0. - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -implied. See the License for the specific language governing -permissions and limitations under the License. - -In addition, you may not use the software for any purposes that are -illegal under applicable law, and the grant of the foregoing license -under the Apache 2.0 license is conditioned upon your compliance with -such restriction. -*/ -const chipOptions = [ - { - type: 'labels', - boldValue: false, - background: 'purple', - borderColor: 'transparent', - density: 'dense', - font: 'purple', - borderRadius: 'primary' - }, - { - type: 'metrics', - boldValue: false, - background: 'grey', - borderColor: 'transparent', - borderRadius: 'primary', - density: 'dense', - font: 'primary' - }, - { - type: 'parameters', - boldValue: false, - background: 'orange', - borderColor: 'transparent', - borderRadius: 'primary', - density: 'dense', - font: 'orange' - }, - { - type: 'results', - boldValue: false, - background: 'grey', - borderColor: 'transparent', - borderRadius: 'primary', - density: 'dense', - font: 'primary' - }, - { - type: 'relations', - boldValue: false, - background: 'orange', - borderColor: 'transparent', - borderRadius: 'primary', - density: 'dense', - font: 'orange' - } -] - -export const getChipOptions = variant => chipOptions.find(item => item.type === variant) diff --git a/src/utils/getFunctionLogs.js b/src/utils/getFunctionLogs.js index a96a5ca804..f0db21af84 100644 --- a/src/utils/getFunctionLogs.js +++ b/src/utils/getFunctionLogs.js @@ -23,7 +23,7 @@ import { } from '../components/FunctionsPage/functions.util' import { TAG_LATEST } from '../constants' import { fetchFunctionLogs, fetchFunctionNuclioLogs } from '../reducers/functionReducer' -import { showErrorNotification } from './notifications.util' +import { showErrorNotification } from 'igz-controls/utils/notification.util' const isFunctionTransient = response => { return TRANSIENT_FUNCTION_STATUSES.includes(response.headers?.['x-mlrun-function-status']) diff --git a/src/utils/getJobLogs.util.js b/src/utils/getJobLogs.util.js index 82c1f65be0..44c44d85dc 100644 --- a/src/utils/getJobLogs.util.js +++ b/src/utils/getJobLogs.util.js @@ -17,12 +17,13 @@ illegal under applicable law, and the grant of the foregoing license under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ +import { REQUEST_CANCELED } from '..//constants' import { fetchJobLogs } from '../reducers/jobReducer' -export const getJobLogs = (id, project, streamLogsRef, setDetailsLogs, dispatch) => { +export const getJobLogs = (id, project, streamLogsRef, setDetailsLogs, dispatch, attempt, signal) => { setDetailsLogs('') - dispatch(fetchJobLogs({ id, project })) + dispatch(fetchJobLogs({ id, project, attempt, signal })) .unwrap() .then(res => { const reader = res.body?.getReader() @@ -42,5 +43,9 @@ export const getJobLogs = (id, project, streamLogsRef, setDetailsLogs, dispatch) streamLogsRef.current = read read() } + }).catch((error) => { + if (error.message === REQUEST_CANCELED) { + setDetailsLogs('') + } }) } diff --git a/src/utils/getNoDataMessage.js b/src/utils/getNoDataMessage.js index d93131c4c1..123c431f73 100644 --- a/src/utils/getNoDataMessage.js +++ b/src/utils/getNoDataMessage.js @@ -64,7 +64,10 @@ import { TAG_FILTER_ALL_ITEMS, TYPE_FILTER, PROJECTS_FILTER_ALL_ITEMS, - LLM_PROMPTS_PAGE + LLM_PROMPTS_PAGE, + MODEL_NAME_FILTER, + MODEL_TAG_FILTER, + ME_MODE_FILTER } from '../constants' const messageNamesList = { @@ -160,13 +163,13 @@ const getSelectedDateValue = (filterType, filters) => { true, true, '/', - filters[DATES_FILTER].value[0] ?? new Date(), - filters[DATES_FILTER].value[1] ?? new Date() + filters[DATES_FILTER]?.value?.[0] ?? new Date(), + filters[DATES_FILTER]?.value?.[1] ?? new Date() ) return (filterType === DATE_RANGE_TIME_FILTER && - !isEqual(filters[DATES_FILTER].value, DATE_FILTER_ANY_TIME)) || - (filterType === DATES_FILTER && !isEqual(filters[DATES_FILTER].value, DATE_FILTER_ANY_TIME)) + !isEqual(filters[DATES_FILTER]?.value, DATE_FILTER_ANY_TIME)) || + (filterType === DATES_FILTER && !isEqual(filters[DATES_FILTER]?.value, DATE_FILTER_ANY_TIME)) ? date : ANY_TIME } @@ -181,7 +184,9 @@ const generateNoEntriesFoundMessage = (visibleFilterTypes, filtersConfig, filter : filters[filterType] const isLastElement = index === visibleFilterTypes.length - 1 - return message + `${label} ${value}${isLastElement ? '"' : ', '}` + return ( + message + `${label.endsWith(':') ? label : `${label}:`} ${value}${isLastElement ? '"' : ', '}` + ) }, 'No data matches the filter: "') } @@ -201,6 +206,8 @@ const getVisibleFilterTypes = (filtersConfig, filters, filtersStore) => { type === ENDPOINT_RESULT || type === JOB_NAME || type === LABELS_FILTER || + type === MODEL_NAME_FILTER || + type === MODEL_TAG_FILTER || type === NAME_FILTER) && filters[type]?.length > 0 const isStatusVisible = @@ -221,6 +228,7 @@ const getVisibleFilterTypes = (filtersConfig, filters, filtersStore) => { (type === DATES_FILTER && !isEqual(filters[DATES_FILTER]?.value, DATE_FILTER_ANY_TIME)) const isShowUntaggedVisible = type === SHOW_UNTAGGED_FILTER && !filters[SHOW_UNTAGGED_FILTER] const isGroupByVisible = type === GROUP_BY_FILTER && filtersStore.groupBy !== GROUP_BY_NONE + const isMEModeVisible = type === ME_MODE_FILTER && filters[ME_MODE_FILTER] !== FILTER_ALL_ITEMS return ( isDateVisible || @@ -234,7 +242,8 @@ const getVisibleFilterTypes = (filtersConfig, filters, filtersStore) => { isShowUntaggedVisible || isStatusVisible || isTagVisible || - isTypeVisible + isTypeVisible || + isMEModeVisible ) }) } diff --git a/src/utils/cutChips.js b/src/utils/getSecretNameValidator.js similarity index 52% rename from src/utils/cutChips.js rename to src/utils/getSecretNameValidator.js index 78eaf66386..31dc943b50 100644 --- a/src/utils/cutChips.js +++ b/src/utils/getSecretNameValidator.js @@ -17,22 +17,26 @@ illegal under applicable law, and the grant of the foregoing license under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ -export const cutChips = (chips = [], maxLength, delimiter) => { - if (chips.length > maxLength) { - let hiddenChipsNumber = `+ ${chips.length - maxLength}` - const hiddenChips = chips.slice(maxLength).map(value => ({ value, delimiter })) - const visibleChips = chips.slice(0, maxLength).map(value => ({ value, delimiter })) - visibleChips.push({ - value: hiddenChipsNumber, - delimiter - }) - - return { - visibleChips, - hiddenChips - } - } +export const getSecretNameValidator = (projectName, initialSecretName) => { return { - visibleChips: chips.map(value => ({ value, delimiter })) + name: 'secretProhibitedNames', + label: 'Secret does not reference an MLRun secret defined in another project', + pattern: secretName => { + // if prohibited secret was set before (we get it from BE) we accept it as valid + if (secretName && secretName === initialSecretName) return true + + if (secretName.startsWith('mlrun-auth-secrets.')) return false + + const correctPatternBeginning = 'mlrun-project-secrets-' // mlrun-project-secrets-{project-name} + + if (secretName.startsWith(correctPatternBeginning)) { + const secretProjectName = secretName.slice(correctPatternBeginning.length) + + return secretProjectName === projectName + } + + return true + } } } + diff --git a/src/utils/getState.js b/src/utils/getState.js index 778c480802..742d2f2ab8 100644 --- a/src/utils/getState.js +++ b/src/utils/getState.js @@ -75,6 +75,7 @@ const commonStateLabels = withFailedState => { [FAILED_STATE]: withFailedState ? 'Failed' : 'Error', omitted: 'Omitted', pending: 'Pending', + pendingRetry: 'Pending retry', ready: 'Ready', running: 'Running', skipped: 'Skipped', diff --git a/src/utils/getUniqueIdentifier.js b/src/utils/getUniqueIdentifier.js index 9da4fa4bde..13d609d065 100644 --- a/src/utils/getUniqueIdentifier.js +++ b/src/utils/getUniqueIdentifier.js @@ -17,6 +17,7 @@ illegal under applicable law, and the grant of the foregoing license under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ +import { get } from 'lodash' import { ADD_TO_FEATURE_VECTOR_TAB, ALERTS_PAGE, @@ -41,7 +42,7 @@ export const getArtifactIdentifier = (artifact, unique) => { if (artifact?.metadata?.tag) identifier += `.${artifact?.metadata?.tag}` } - return identifier + return identifier && `id.${identifier}` } export const getFunctionIdentifier = (func, unique) => { @@ -52,13 +53,13 @@ export const getFunctionIdentifier = (func, unique) => { if (func?.tag) identifier += `.${func.tag}` } - return identifier + return identifier && `id.${identifier}` } export const getAlertIdentifier = (alert, unique) => { let identifier = `${alert?.name || ''}` if (unique && alert?.id) identifier += `.${alert.id}` - return identifier + return identifier && `id.${identifier}` } export const getJobIdentifier = (job, unique) => { @@ -66,7 +67,7 @@ export const getJobIdentifier = (job, unique) => { if (unique && job?.uid) identifier += `.${job.uid}` - return identifier + return identifier && `id.${identifier}` } export const getWorkflowJobIdentifier = (job, unique) => { @@ -85,7 +86,7 @@ export const getWorkflowJobIdentifier = (job, unique) => { if (jobId) identifier += `.${jobId}` - return identifier + return identifier && `id.${identifier}` } export const getFeatureIdentifier = (feature, unique) => { @@ -95,7 +96,7 @@ export const getFeatureIdentifier = (feature, unique) => { if (feature.metadata?.name) identifier += `.${feature.metadata.name}` if (feature.ui?.type) identifier += `.${feature.ui.type}` - return identifier + return identifier && `id.${identifier}` } export const getFeatureSetIdentifier = (featureSet, unique) => { @@ -104,7 +105,7 @@ export const getFeatureSetIdentifier = (featureSet, unique) => { if (unique && featureSet?.tag) identifier += `.${featureSet.tag}` if (unique && featureSet?.uid) identifier += `.${featureSet.uid}` - return identifier + return identifier && `id.${identifier}` } export const getFeatureVectorIdentifier = (featureVector, unique) => { @@ -113,15 +114,27 @@ export const getFeatureVectorIdentifier = (featureVector, unique) => { if (unique && featureVector?.tag) identifier += `.${featureVector.tag}` if (unique && featureVector?.uid) identifier += `.${featureVector.uid}` - return identifier + return identifier && `id.${identifier}` } -export const getV3ioStreamIdentifier = v3ioStream => { - return `${v3ioStream?.consumerGroup || ''}` +export const getV3ioStreamIdentifier = (v3ioStream, consumerGroupIsObject) => { + const identifier = get( + v3ioStream, + consumerGroupIsObject ? 'consumerGroup.identifierUnique' : 'consumerGroup', + '' + ) + + return consumerGroupIsObject ? identifier : `id.${identifier}` } -export const getV3ioStreamShardLagIdentifier = v3ioStream => { - return `${v3ioStream?.shardLagId || ''}` +export const getV3ioStreamShardLagIdentifier = (v3ioStream, shardLagIdIsObject) => { + const identifier = get( + v3ioStream, + shardLagIdIsObject ? 'shardLagId.identifierUnique' : 'shardLagId', + '' + ) + + return shardLagIdIsObject ? identifier : `id.${identifier}` } export const getIdentifierMethod = tab => { diff --git a/src/utils/handleDeleteArtifact.js b/src/utils/handleDeleteArtifact.js index 3821b513ca..b8c6d2eed4 100644 --- a/src/utils/handleDeleteArtifact.js +++ b/src/utils/handleDeleteArtifact.js @@ -20,8 +20,8 @@ such restriction. import { capitalize } from 'lodash' import { deleteArtifact } from '../reducers/artifactsReducer' import { deleteArtifacts } from '../reducers/artifactsReducer' -import { setNotification } from '../reducers/notificationReducer' -import { showErrorNotification } from './notifications.util' +import { setNotification } from 'igz-controls/reducers/notificationReducer' +import { showErrorNotification } from 'igz-controls/utils/notification.util' export const handleDeleteArtifact = ( dispatch, diff --git a/src/utils/helper.js b/src/utils/helper.js index 945727eeb5..f60042ef53 100644 --- a/src/utils/helper.js +++ b/src/utils/helper.js @@ -18,7 +18,6 @@ under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ -import { VIEW_SEARCH_PARAMETER } from '../constants' import localStorageService from './localStorageService' export const isDemoMode = search => { @@ -29,10 +28,6 @@ export const getUrlMode = search => { return new URLSearchParams(search).get('mode')?.toLowerCase() } -export const getViewMode = search => { - return new URLSearchParams(search).get(VIEW_SEARCH_PARAMETER)?.toLowerCase() -} - export const isPanelOpened = search => { return new URLSearchParams(search).get('openPanel')?.toLowerCase() === 'true' } diff --git a/src/utils/index.js b/src/utils/index.js index a6a16504ba..f86a297497 100755 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -17,7 +17,5 @@ illegal under applicable law, and the grant of the foregoing license under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ -export * from './datetime' export * from './object' export * from './parseUri' -export * from './string' diff --git a/src/utils/jobs.util.js b/src/utils/jobs.util.jsx similarity index 71% rename from src/utils/jobs.util.js rename to src/utils/jobs.util.jsx index 4a2b36eac0..b25088dda8 100644 --- a/src/utils/jobs.util.js +++ b/src/utils/jobs.util.jsx @@ -17,6 +17,7 @@ illegal under applicable law, and the grant of the foregoing license under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ +import React from 'react' import { cloneDeep, debounce, omit } from 'lodash' import { @@ -25,12 +26,24 @@ import { FE_PAGE, FILTER_ALL_ITEMS, JOBS_MONITORING_JOBS_TAB, + FUNCTION_TYPE_APPLICATION, JOBS_MONITORING_SCHEDULED_TAB, + JOB_KIND_DASK, + JOB_KIND_DATABRICKS, + JOB_KIND_HANDLER, + JOB_KIND_JOB, + JOB_KIND_LOCAL, + JOB_KIND_MPIJOB, + JOB_KIND_NUCLIO, + JOB_KIND_REMOTE, + JOB_KIND_SERVING, + JOB_KIND_SPARK, + JOB_KIND_WORKFLOW, LABELS_FILTER, MONITOR_JOBS_TAB, NAME_FILTER, - PROJECT_FILTER, PROJECTS_FILTER_ALL_ITEMS, + PROJECT_FILTER, STATUS_FILTER, TYPE_FILTER } from '../constants' @@ -48,11 +61,39 @@ import { jobsStatuses, workflowsStatuses } from '../components/FilterMenu/filterMenu.settings' -import { getCloseDetailsLink } from './link-helper.util' -import { parseJob } from './parseJob' import { fetchJob } from '../reducers/jobReducer' -import { showErrorNotification } from './notifications.util' import { generateObjectNotInTheListMessage } from './generateMessage.util' +import { getCloseDetailsLink } from './link-helper.util' +import { parseJob } from './parseJob' +import { showErrorNotification } from 'igz-controls/utils/notification.util' + +import Code from 'igz-controls/images/code.svg?react' +import Application from 'igz-controls/images/application-icon.svg?react' +import DatabricksIcon from 'igz-controls/images/databricks-icon.svg?react' +import Jupyter from 'igz-controls/images/jupyter.svg?react' +import Package from 'igz-controls/images/package.svg?react' +import Horovod from 'igz-controls/images/horovod.svg?react' +import Nuclio from 'igz-controls/images/nuclio.svg?react' +import Remote from 'igz-controls/images/ic_remote.svg?react' +import Serving from 'igz-controls/images/serving-icon.svg?react' +import Spark from 'igz-controls/images/spark.svg?react' +import Workflow from 'igz-controls/images/workflow-icon.svg?react' + +export const typesOfJob = { + '': { label: 'Local', icon: }, + [FUNCTION_TYPE_APPLICATION]: { label: 'Application', icon: }, + [JOB_KIND_DASK]: { label: 'Dask', icon: null }, + [JOB_KIND_DATABRICKS]: { label: 'Databricks', icon: }, + [JOB_KIND_HANDLER]: { label: 'Handler', icon: }, + [JOB_KIND_JOB]: { label: 'Job', icon: }, + [JOB_KIND_LOCAL]: { label: 'Local', icon: }, + [JOB_KIND_MPIJOB]: { label: 'Horovod', icon: }, + [JOB_KIND_NUCLIO]: { label: 'Nuclio', icon: }, + [JOB_KIND_REMOTE]: { label: 'Remote', icon: }, + [JOB_KIND_SERVING]: { label: 'Serving', icon: }, + [JOB_KIND_SPARK]: { label: 'Spark', icon: }, + [JOB_KIND_WORKFLOW]: { label: 'Workflow', icon: } +} export const checkForSelectedJob = debounce( ( @@ -91,7 +132,13 @@ export const checkForSelectedJob = debounce( .then(job => { const parsedJob = parseJob(job) if (!parsedJob) { - navigate(getCloseDetailsLink(jobName || (projectName ? MONITOR_JOBS_TAB : JOBS_MONITORING_JOBS_TAB), true), { replace: true }) + navigate( + getCloseDetailsLink( + jobName || (projectName ? MONITOR_JOBS_TAB : JOBS_MONITORING_JOBS_TAB), + true + ), + { replace: true } + ) } else if (parsedJob) { const findJobIndex = jobsList => jobsList.findIndex(job => { @@ -112,7 +159,7 @@ export const checkForSelectedJob = debounce( return prevSearchParams }) } else { - parsedJob.ui.infoMessage = generateObjectNotInTheListMessage('job\'s run') + parsedJob.ui.infoMessage = generateObjectNotInTheListMessage("job's run") } } @@ -120,7 +167,13 @@ export const checkForSelectedJob = debounce( } }) .catch(error => { - navigate(getCloseDetailsLink(jobName || (projectName ? MONITOR_JOBS_TAB : JOBS_MONITORING_JOBS_TAB), true), { replace: true }) + navigate( + getCloseDetailsLink( + jobName || (projectName ? MONITOR_JOBS_TAB : JOBS_MONITORING_JOBS_TAB), + true + ), + { replace: true } + ) showErrorNotification( dispatch, error, @@ -142,7 +195,11 @@ export const getJobKindFromLabels = (labels = []) => { export const getJobsFiltersConfig = (jobName, crossProjects) => { const filters = { - [NAME_FILTER]: { label: 'Name:', hidden: Boolean(jobName), initialValue: '' }, + [NAME_FILTER]: { + label: 'Name:', + initialValue: '', + hidden: Boolean(jobName) + }, [DATES_FILTER]: { label: 'Start time:', initialValue: getDatePickerFilterValue( @@ -154,7 +211,8 @@ export const getJobsFiltersConfig = (jobName, crossProjects) => { label: 'Project:', initialValue: PROJECTS_FILTER_ALL_ITEMS, isModal: true, - hidden: Boolean(jobName) + hidden: Boolean(jobName), + applyHidden: true }, [STATUS_FILTER]: { label: 'Status:', initialValue: [FILTER_ALL_ITEMS], isModal: true }, [TYPE_FILTER]: { label: 'Type:', initialValue: FILTER_ALL_ITEMS, isModal: true }, @@ -203,7 +261,7 @@ export const getScheduledFiltersConfig = crossProjects => { ) }, [PROJECT_FILTER]: { label: 'Project:', initialValue: PROJECTS_FILTER_ALL_ITEMS, isModal: true }, - [TYPE_FILTER]: { label: 'Type:', initialValue: FILTER_ALL_ITEMS, isModal: true }, + [TYPE_FILTER]: { label: 'Type:', initialValue: [FILTER_ALL_ITEMS], isModal: true }, [LABELS_FILTER]: { label: 'Labels:', initialValue: '', isModal: true } } @@ -243,9 +301,14 @@ export const parseWorkflowsQueryParamsCallback = (paramName, paramValue) => { } export const parseScheduledQueryParamsCallback = (paramName, paramValue) => { - if (paramName === TYPE_FILTER) { - return generateTypeFilter(JOBS_MONITORING_SCHEDULED_TAB).find(type => type.id === paramValue) - ?.id + if (paramName === TYPE_FILTER && paramValue) { + const validTypes = new Set( + generateTypeFilter(JOBS_MONITORING_SCHEDULED_TAB).map(type => type.id) + ) + + const filteredStatuses = paramValue.split(',').filter(paramType => validTypes.has(paramType)) + + return filteredStatuses.length ? filteredStatuses : null } return paramValue diff --git a/src/utils/largeResponseCatchHandler.js b/src/utils/largeResponseCatchHandler.js index eca10eb5e4..86a314d8cd 100644 --- a/src/utils/largeResponseCatchHandler.js +++ b/src/utils/largeResponseCatchHandler.js @@ -18,7 +18,7 @@ under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ import { DEFAULT_ABORT_MSG, LARGE_REQUEST_CANCELED, REQUEST_CANCELED } from '../constants' -import { showErrorNotification } from './notifications.util' +import { showErrorNotification } from 'igz-controls/utils/notification.util' export const largeResponseCatchHandler = ( error, diff --git a/src/utils/link-helper.util.js b/src/utils/link-helper.util.js index d978918a5f..79064f395a 100644 --- a/src/utils/link-helper.util.js +++ b/src/utils/link-helper.util.js @@ -17,9 +17,11 @@ illegal under applicable law, and the grant of the foregoing license under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ -import { DETAILS_OVERVIEW_TAB, VIEW_SEARCH_PARAMETER } from '../constants' -import { getFilteredSearchParams } from './filter.util' -import { showErrorNotification } from './notifications.util' +import { DETAILS_OVERVIEW_TAB } from '../constants' +import { VIEW_SEARCH_PARAMETER } from 'igz-controls/constants' +import { generateUrlFromRouterPath } from 'igz-controls/utils/common.util' +import { getFilteredSearchParams } from 'igz-controls/utils/filter.util' +import { showErrorNotification } from 'igz-controls/utils/notification.util' export const isPageTabValid = (pageTab, tabs, navigate, location) => { if (!tabs.includes(pageTab)) { @@ -35,31 +37,25 @@ export const isProjectValid = (navigate, projects, currentProjectName, dispatch) !projects.some(project => project?.metadata?.name === currentProjectName) ) { navigate('/projects', { replace: true }) - showErrorNotification( - dispatch, - {}, - '', - 'This project does not exist' - ) + showErrorNotification(dispatch, {}, '', 'This project does not exist') } } -export const generateUrlFromRouterPath = link => { - return new URL(link, window.location.origin).toString() -} - -export const getCloseDetailsLink = (paramName, ignoreOrigin) => { +export const getCloseDetailsLink = (paramName, ignoreOrigin, objectName) => { let pathname = window.location.pathname if (ignoreOrigin && pathname.startsWith(import.meta.env.VITE_PUBLIC_URL)) { pathname = pathname.slice(import.meta.env.VITE_PUBLIC_URL.length) } - const link = + let linkParts = pathname .split('/') .splice(0, pathname.split('/').lastIndexOf(paramName) + 1) - .join('/') + getFilteredSearchParams(window.location.search, [VIEW_SEARCH_PARAMETER]) + + if (objectName && paramName === objectName && linkParts[linkParts.length - 1] === objectName) linkParts.pop() + + const link = linkParts.join('/') + getFilteredSearchParams(window.location.search, [VIEW_SEARCH_PARAMETER]) return ignoreOrigin ? link : generateUrlFromRouterPath(link) } diff --git a/src/utils/notifications.util.js b/src/utils/notifications.util.js deleted file mode 100644 index 8ea06709c5..0000000000 --- a/src/utils/notifications.util.js +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright 2019 Iguazio Systems Ltd. - -Licensed under the Apache License, Version 2.0 (the "License") with -an addition restriction as set forth herein. You may not use this -file except in compliance with the License. You may obtain a copy of -the License at http://www.apache.org/licenses/LICENSE-2.0. - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -implied. See the License for the specific language governing -permissions and limitations under the License. - -In addition, you may not use the software for any purposes that are -illegal under applicable law, and the grant of the foregoing license -under the Apache 2.0 license is conditioned upon your compliance with -such restriction. -*/ - -import { setNotification } from '../reducers/notificationReducer' -import { getErrorMsg } from 'igz-controls/utils/common.util' -import { FORBIDDEN_ERROR_STATUS_CODE } from 'igz-controls/constants' - -export const showErrorNotification = ( - dispatch, - error, - defaultErrorMsg, - customErrorMsg, - retryCallback, - showNotificationCallback -) => { - const notificationData = { - status: error?.response?.status || 400, - id: Math.random(), - message: customErrorMsg || getErrorMsg(error, defaultErrorMsg), - error - } - - if (retryCallback && error?.response?.status !== FORBIDDEN_ERROR_STATUS_CODE) { - notificationData.retry = retryCallback - } - - showNotificationCallback?.(defaultErrorMsg) - dispatch(setNotification(notificationData)) -} diff --git a/src/utils/object.js b/src/utils/object.js index f2054233c5..86d3f78b53 100755 --- a/src/utils/object.js +++ b/src/utils/object.js @@ -18,7 +18,7 @@ under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ import { isNil } from 'lodash' -import { roundFloats } from './roundFloats' +import { roundFloats } from 'igz-controls/utils/common.util' // {key: "value", key2: "value2"} --> ["key: value", "key2: value2"] export const parseKeyValues = (object = {}) => diff --git a/src/utils/parseAlert.js b/src/utils/parseAlert.js index 458d186b8e..9e6063c064 100644 --- a/src/utils/parseAlert.js +++ b/src/utils/parseAlert.js @@ -17,14 +17,16 @@ illegal under applicable law, and the grant of the foregoing license under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ +import { getAlertIdentifier } from './getUniqueIdentifier' + export const parseAlerts = alerts => { return alerts.map(alert => { return { ...alert, ui: { ...alert, - identifier: alert.id, - identifierUnique: `${alert.name}.${alert.id}` + identifier: getAlertIdentifier(alert), + identifierUnique: getAlertIdentifier(alert, true) } } }) diff --git a/src/utils/parseJob.js b/src/utils/parseJob.js index 2803b79726..a83d9bbdfc 100644 --- a/src/utils/parseJob.js +++ b/src/utils/parseJob.js @@ -97,6 +97,10 @@ export const parseJob = (job, tab, customState, customError) => { nodeSelectorChips: parseKeyValues(job.spec?.node_selector || {}), project: job.metadata.project, reason: job.status?.reason ?? '', + retryCount: job.status?.retry_count, + maxRetries: job.spec?.retry?.count, + retryCountWithInitialAttempt: (job.status.retry_count ?? 0) + 1, + maxRetriesWithInitialAttempt: (job.spec?.retry?.count ?? 0) + 1, results: job.status?.results || {}, resultsChips: parseKeyValues(job.status?.results || {}), startTime: new Date(job.status?.start_time), diff --git a/src/utils/poll.util.js b/src/utils/poll.util.js index 7b55e7cb74..58bebc9d37 100644 --- a/src/utils/poll.util.js +++ b/src/utils/poll.util.js @@ -19,9 +19,11 @@ such restriction. */ import { constant, chain, isNil, overSome, isNaN, isFinite } from 'lodash' -export const BG_TASK_RUNNING = 'running' -export const BG_TASK_FAILED = 'failed' -export const BG_TASK_SUCCEEDED = 'succeeded' +import { FAILED_STATE, RUNNING_STATE, SUCCEEDED_STATE } from '../constants' + +export const BG_TASK_RUNNING = RUNNING_STATE +export const BG_TASK_FAILED = FAILED_STATE +export const BG_TASK_SUCCEEDED = SUCCEEDED_STATE /** * Polls by calling `pollMethod` and then invoking `isDone` method with `pollMethod`'s result. Stops polling diff --git a/src/utils/roundFloats.js b/src/utils/roundFloats.js deleted file mode 100644 index 717b60557d..0000000000 --- a/src/utils/roundFloats.js +++ /dev/null @@ -1,31 +0,0 @@ -/* -Copyright 2019 Iguazio Systems Ltd. - -Licensed under the Apache License, Version 2.0 (the "License") with -an addition restriction as set forth herein. You may not use this -file except in compliance with the License. You may obtain a copy of -the License at http://www.apache.org/licenses/LICENSE-2.0. - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -implied. See the License for the specific language governing -permissions and limitations under the License. - -In addition, you may not use the software for any purposes that are -illegal under applicable law, and the grant of the foregoing license -under the Apache 2.0 license is conditioned upon your compliance with -such restriction. -*/ -export const roundFloats = (value, precision) => { - if ( - ((typeof value === 'string' && value.trim() !== '') || typeof value === 'number') && - !isNaN(value) - ) { - const parsedNum = parseFloat(value) - - return parsedNum % 1 === 0 ? parsedNum : +parsedNum.toFixed(precision ?? 2) - } - - return value -} diff --git a/src/utils/tableRows.util.js b/src/utils/tableRows.util.js index 545a678456..531640f6f7 100644 --- a/src/utils/tableRows.util.js +++ b/src/utils/tableRows.util.js @@ -18,7 +18,7 @@ under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ -import { sortListByDate } from './datetime' +import { sortListByDate } from 'igz-controls/utils/datetime.util' export const PARENT_ROW_EXPANDED_CLASS = 'parent-row_expanded' diff --git a/src/reducers/notificationReducer.js b/src/utils/wrapComponentForNavbarNavigationTracking.jsx similarity index 56% rename from src/reducers/notificationReducer.js rename to src/utils/wrapComponentForNavbarNavigationTracking.jsx index ee850f1f93..c76ef67c48 100644 --- a/src/reducers/notificationReducer.js +++ b/src/utils/wrapComponentForNavbarNavigationTracking.jsx @@ -17,30 +17,28 @@ illegal under applicable law, and the grant of the foregoing license under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ -import { createSlice } from '@reduxjs/toolkit' - -const initialState = { - notification: [] -} - -const notificationSlice = createSlice({ - name: 'notification', - initialState, - reducers: { - setNotification(state, { payload }) { - if (payload.error) { - /* eslint-disable-next-line no-console */ - console.error(payload.error) +import { useEffect, useRef, useState } from 'react' +import { useLocation } from 'react-router-dom' + +const wrapComponentForNavbarNavigationTracking = WrappedComponent => { + const Wrap = props => { + const location = useLocation() + const savedKeyRef = useRef(0) + const [key, setKey] = useState(0) + + useEffect(() => { + if (location.state?.navbarNavigate) { + savedKeyRef.current += 1 + setKey(savedKeyRef.current) + } else { + setKey(savedKeyRef.current) } + }, [location.state?.navbarNavigate]) - state.notification.push(payload) - }, - removeNotification(state, { payload }) { - state.notification = state.notification.filter(item => item.id !== payload) - } + return } -}) -export const { setNotification, removeNotification } = notificationSlice.actions + return Wrap +} -export default notificationSlice.reducer +export default wrapComponentForNavbarNavigationTracking diff --git a/tests/features/MLFunction.feature b/tests/features/MLFunction.feature index 0f11d0f3cc..8d9edb32e0 100644 --- a/tests/features/MLFunction.feature +++ b/tests/features/MLFunction.feature @@ -109,7 +109,7 @@ Feature: ML Functions Then verify "Date_Picker_Filter_Dropdown" dropdown element on "ML_Functions" wizard should contains "Dropdown_Options"."Date_Picker_Filter_Options" When select "Any time" option in "Date_Picker_Filter_Dropdown" filter dropdown on "ML_Functions" wizard And wait load page - When click on cell with row index 2 in "name" column in "Functions_Table" table on "ML_Functions" wizard + When click on cell with row index 3 in "name" column in "Functions_Table" table on "ML_Functions" wizard And wait load page Then verify "Header" element visibility on "ML_Function_Info_Pane" wizard Then verify "Updated" element visibility on "ML_Function_Info_Pane" wizard @@ -119,7 +119,7 @@ Feature: ML Functions Then verify "Overview" tab is active in "Info_Pane_Tab_Selector" on "ML_Function_Info_Pane" wizard Then verify "Overview_Headers" on "ML_Function_Info_Pane" wizard should contains "ML_Function_Info_Pane"."Overview_Headers" Then click on "Cross_Close_Button" element on "ML_Function_Info_Pane" wizard - When click on cell with row index 1 in "name" column in "Functions_Table" table on "ML_Functions" wizard + When click on cell with row index 2 in "name" column in "Functions_Table" table on "ML_Functions" wizard And wait load page Then verify "Header" element visibility on "ML_Function_Info_Pane" wizard Then verify "Updated" element visibility on "ML_Function_Info_Pane" wizard @@ -449,7 +449,7 @@ Feature: ML Functions | Secret | | | | yes | Then verify "Volume_Paths_Table_Volume_Name_Input" element in "Resources_Accordion" on "New_Function" wizard should display hover warning "Input_Hint"."Input_Field_Require" Then verify "Volume_Paths_Table_Path_Input" element in "Resources_Accordion" on "New_Function" wizard should display hover warning "Input_Hint"."Input_Field_Require" - Then verify "Volume_Paths_Table_Config_Map_Input" element in "Resources_Accordion" on "New_Function" wizard should display hover warning "Input_Hint"."Input_Field_Require" + Then verify "Volume_Paths_Table_Secret_Name_Input" in "Resources_Accordion" on "New_Function" wizard should display options "Input_Hint"."Secret_Name_Rule_Options" Then verify "Volume_Paths_Table_Path_Input" element in "Resources_Accordion" on "New_Function" wizard should display hint "Input_Hint"."Mount_Path_Hint" When click on "Delete_New_Row_Button" element in "Resources_Accordion" on "New_Function" wizard When add new volume rows to "Volume_Paths_Table" table in "Resources_Accordion" on "New_Function" wizard using nontable inputs @@ -537,7 +537,7 @@ Feature: ML Functions | Function_Environment_Variables_Name_Input | Function_Environment_Variables_Type_Dropdown | Function_Environment_Variables_Secret_Name_Input | Function_Environment_Variables_Secret_Key_Input | Add_Row_Button | | | Secret | | @#$ | yes | Then verify "Function_Environment_Variables_Name_Input" element in "Environment_Variables_Accordion" on "New_Function" wizard should display hover warning "Input_Hint"."Input_Field_Require" - Then verify "Function_Environment_Variables_Secret_Name_Input" element in "Environment_Variables_Accordion" on "New_Function" wizard should display hover warning "Input_Hint"."Input_Field_Require" + Then verify "Function_Environment_Variables_Secret_Name_Input" in "Environment_Variables_Accordion" on "New_Function" wizard should display options "Input_Hint"."Secret_Name_Rule_Options" Then verify "Function_Environment_Variables_Secret_Name_Input" element in "Environment_Variables_Accordion" on "New_Function" wizard should display hint "Input_Hint"."SECRET_INPUT_HINT" Then verify "Function_Environment_Variables_Secret_Key_Input" element in "Environment_Variables_Accordion" on "New_Function" wizard should display hover warning "Input_Hint"."Input_Field_Invalid" Then verify "Function_Environment_Variables_Secret_Key_Input" element in "Environment_Variables_Accordion" on "New_Function" wizard should display hint "Input_Hint"."VALUE_INPUT_HINT" @@ -1110,9 +1110,9 @@ Feature: ML Functions Then verify "Cross_Cancel_Button" element visibility on "View_YAML" wizard Then verify "YAML_Modal_Container" element visibility on "View_YAML" wizard Then click on "Cross_Cancel_Button" element on "View_YAML" wizard - Then click on cell with row index 8 in "expand_btn" column in "Functions_Table" table on "ML_Functions" wizard + Then click on cell with row index 9 in "expand_btn" column in "Functions_Table" table on "ML_Functions" wizard And wait load page - Then select "View YAML" option in action menu on "ML_Functions" wizard in "Functions_Table" table at row with "Nov 23, 2021, 11:31:51 AM" value in "name" column + Then select "View YAML" option in action menu on "ML_Functions" wizard in "Functions_Table" table at row with "Nov 23, 2021, 10:31:51 AM" value in "name" column Then verify if "View_YAML" popup dialog appears Then verify "Cross_Cancel_Button" element visibility on "View_YAML" wizard Then verify "YAML_Modal_Container" element visibility on "View_YAML" wizard @@ -1369,14 +1369,14 @@ Feature: ML Functions And wait load page When click on cell with row index 2 in "name" column in "Functions_Table" table on "ML_Functions" wizard And wait load page - Then verify redirection from "projects/default/functions/model-monitoring-stream/latest/INVALID" to "projects/default/functions/model-monitoring-stream/latest/overview" + Then verify redirection from "projects/default/functions/model-monitoring-stream/latest/INVALID?dates=anyTime" to "projects/default/functions/model-monitoring-stream/latest/overview?dates=anyTime" Then select "Code" tab in "Info_Pane_Tab_Selector" on "ML_Function_Info_Pane" wizard And wait load page - Then verify redirection from "projects/default/functions/model-monitoring-stream/latest/INVALID" to "projects/default/functions/model-monitoring-stream/latest/overview" + Then verify redirection from "projects/default/functions/model-monitoring-stream/latest/CodeINVALID?dates=anyTime" to "projects/default/functions/model-monitoring-stream/latest/overview?dates=anyTime" Then select "Build Log" tab in "Info_Pane_Tab_Selector" on "ML_Function_Info_Pane" wizard And wait load page - Then verify redirection from "projects/default/functions/model-monitoring-stream/latest/INVALID" to "projects/default/functions/model-monitoring-stream/latest/overview" - Then verify redirection from "projects/default/INVALID/model-monitoring-stream/latest/overview" to "projects" + Then verify redirection from "projects/default/functions/model-monitoring-stream/latest/BuildLogINVALID?dates=anyTime" to "projects/default/functions/model-monitoring-stream/latest/overview?dates=anyTime" + Then verify redirection from "projects/default/INVALID/model-monitoring-stream/latest/overview?dates=anyTime" to "projects" @MLF @smoke @@ -1445,6 +1445,8 @@ Feature: ML Functions Then verify "New_Function_Build_Commands_Text_Area" not input element in "Code_Accordion" on "New_Function" wizard is enabled Then click on "Save_Button" element on "New_Function" wizard And wait load page + When turn on staging mode with query params "true" + And wait load page Then check "demo-function-02" value in "name" column in "Functions_Table" table on "ML_Functions" wizard Then verify "Table_FilterBy_Button" element visibility on "ML_Functions" wizard Then click on "Table_FilterBy_Button" element on "ML_Functions" wizard @@ -1456,6 +1458,7 @@ Feature: ML Functions And wait load page Then check "demo-function-02" value in "name" column in "Functions_Table" table on "ML_Functions" wizard When click on cell with value "demo-function-02" in "name" column in "Functions_Table" table on "ML_Functions" wizard + And wait load page Then check "demo-function-02" value in "name" column in "Overview_Table" table on "ML_Function_Info_Pane" wizard Then "Header" element on "ML_Function_Info_Pane" should contains "demo-function-02" value diff --git a/tests/features/alerts.feature b/tests/features/alerts.feature index ef2e0508f9..31dc72b71b 100644 --- a/tests/features/alerts.feature +++ b/tests/features/alerts.feature @@ -53,11 +53,10 @@ Feature: Alerts Page @MLAlert @smoke - # TODO: Add data to the mock to check the following elements (existing alerts with endpoint type) Scenario: MLAlert002 - Check filtering by Endpoint entity type on Alerts page Given open url And wait load page - And click on row root with value "auto-generated-data" in "name" column in "Projects_Table" table on "Projects" wizard + And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard And wait load page And select "tab" with "Alerts" value in breadcrumbs menu And wait load page @@ -72,7 +71,6 @@ Feature: Alerts Page When select "Endpoint" option in "Entity_Type_Filter_Dropdown" filter dropdown on "FilterBy_Popup" wizard Then click on "Apply_Button" element on "FilterBy_Popup" wizard And wait load page - # Add data to the mock to check the following elements Then verify "Alerts_Table" element visibility on "Alerts" wizard Then value in "entityType" column with "tooltip" in "Alerts_Table" on "Alerts" wizard should contains "Endpoint" Then verify "Table_FilterBy_Button" element on "Alerts" wizard should display hover tooltip "Common_Tooltips"."FilterBy_Button_1" @@ -154,14 +152,13 @@ Feature: Alerts Page @MLAlert @smoke - # TODO: Add data to the mock to check the following elements (existing alerts with application type) Scenario: MLAlert004 - Check filtering by Application entity type on Alerts page Given open url And wait load page - And click on row root with value "cat-vs-dog-classification" in "name" column in "Projects_Table" table on "Projects" wizard + And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard And wait load page Then verify breadcrumbs "tab" label should be equal "Project monitoring" value - Then verify breadcrumbs "project" label should be equal "cat-vs-dog-classification" value + Then verify breadcrumbs "project" label should be equal "default" value And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard Then click on "Alerts_Button" element on "commonPagesHeader" wizard And wait load page @@ -172,7 +169,6 @@ Feature: Alerts Page Then verify "Date_Picker_Filter_Dropdown" dropdown on "Alerts" wizard selected option value "Past 24 hours" When select "Any time" option in "Date_Picker_Filter_Dropdown" filter dropdown on "Alerts" wizard And wait load page - # Add data to the mock to check the following elements Then verify "Alerts_Table" element visibility on "Alerts" wizard Then click on "Table_FilterBy_Button" element on "Alerts" wizard When select "Application" option in "Entity_Type_Filter_Dropdown" filter dropdown on "FilterBy_Popup" wizard @@ -267,11 +263,10 @@ Feature: Alerts Page @MLAlert @smoke - # TODO: Add data to the mock to check the following elements (existing job data for details popup) Scenario: MLAlert006 - Check components in Job detail pop-up on Job alert detail pane on Alerts page Given open url And wait load page - And click on row root with value "auto-generated-data" in "name" column in "Projects_Table" table on "Projects" wizard + And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard And wait load page And select "tab" with "Alerts" value in breadcrumbs menu And wait load page @@ -285,28 +280,32 @@ Feature: Alerts Page When select "Job" option in "Entity_Type_Filter_Dropdown" filter dropdown on "FilterBy_Popup" wizard Then click on "Apply_Button" element on "FilterBy_Popup" wizard And wait load page - Then type value "alertd0beb8b0b8" to "Search_By_Name_Filter_Input" field on "Alerts" wizard + Then value in "entityType" column with "tooltip" in "Alerts_Table" on "Alerts" wizard should contains "Job" + Then click on "Table_FilterBy_Button" element on "Alerts" wizard + When select "All" option in "Entity_Type_Filter_Dropdown" filter dropdown on "FilterBy_Popup" wizard + Then click on "Apply_Button" element on "FilterBy_Popup" wizard + And wait load page + Then type value "obryv-default" to "Search_By_Name_Filter_Input" field on "Alerts" wizard Then click on "Refresh_Button" element on "Alerts" wizard And wait load page - Then value in "alertName" column with "text" in "Alerts_Table" on "Alerts" wizard should contains "alertd0beb8b0b8" + Then value in "alertName" column with "text" in "Alerts_Table" on "Alerts" wizard should contains "alert-name-obryv-default" And wait load page Then verify "Alerts_Table" element visibility on "Alerts" wizard Then value in "entityType" column with "tooltip" in "Alerts_Table" on "Alerts" wizard should contains "Job" When click on cell with row index 1 in "alertName" column in "Alerts_Table" table on "Alerts" wizard And wait load page Then verify "Header" element visibility on "Alerts_Jobs_Info_Pane" wizard - Then "Header" element on "Alerts_Jobs_Info_Pane" should contains "alertd0beb8b0b8" value + Then "Header" element on "Alerts_Jobs_Info_Pane" should contains "alert-name-obryv-default" value Then verify "Overview_General_Headers" element visibility on "Alerts_Jobs_Info_Pane" wizard Then verify "Overview_General_Headers" on "Alerts_Jobs_Info_Pane" wizard should contains "Alerts_Jobs_Info_Pane"."Overview_General_Headers_PerProject" Then verify "Job_Detail_PopUp_Link" element visibility on "Alerts_Jobs_Info_Pane" wizard Then click on "Job_Detail_PopUp_Link" element on "Alerts_Jobs_Info_Pane" wizard - # Add data to the mock to check the following elements Then verify if "Modal_Transition_Popup" popup dialog appears Then verify "Title" element visibility on "Modal_Transition_Popup" wizard - Then "Title" element on "Modal_Transition_Popup" should contains "erann-test" value + Then "Title" element on "Modal_Transition_Popup" should contains "test-func-oyn-handler" value Then verify "Data_Status" element visibility on "Modal_Transition_Popup" wizard Then verify "State_Icon" element visibility on "Modal_Transition_Popup" wizard - Then verify "State_Icon" element on "Modal_Transition_Popup" wizard should display hover tooltip "Jobs_Monitor_Tab_Info_Pane"."Error_State" + Then verify "State_Icon" element on "Modal_Transition_Popup" wizard should display hover tooltip "Jobs_Monitor_Tab_Info_Pane"."Error_State_With_Message" Then verify "Refresh_Button" element visibility on "Modal_Transition_Popup" wizard Then verify "Refresh_Button" element on "Modal_Transition_Popup" wizard should display hover tooltip "Common_Tooltips"."Refresh_Button" Then click on "Refresh_Button" element on "Modal_Transition_Popup" wizard @@ -349,21 +348,21 @@ Feature: Alerts Page Then verify "Logs" tab is active in "Tab_Selector" on "Modal_Transition_Popup" wizard Then verify "Logs_Text_container" element visibility on "Modal_Transition_Popup" wizard Then verify "Logs_Refresh_Button" element visibility on "Modal_Transition_Popup" wizard - And verify "No_Data_Message" element visibility on "commonPagesHeader" wizard - Then "No_Data_Message" component on "commonPagesHeader" should contains "No_Data_Message"."No_Data" + Then click on "Logs_Refresh_Button" element on "Modal_Transition_Popup" wizard + And wait load page + Then verify "Logs_Text_container" element visibility on "Modal_Transition_Popup" wizard And select "Pods" tab in "Tab_Selector" on "Modal_Transition_Popup" wizard And wait load page Then verify "Pods" tab is active in "Tab_Selector" on "Modal_Transition_Popup" wizard And verify "No_Data_Message" element visibility on "commonPagesHeader" wizard - Then "No_Data_Message" component on "commonPagesHeader" should contains "No_Data_Message"."No_Pods_data" + Then "No_Data_Message" component on "commonPagesHeader" should contains "No_Data_Message"."No_Pods_data_Completion" @MLAlert @smoke - # TODO: Add data to the mock to check the following elements (existing alerts with endpoint type) Scenario: MLAlert007 - Check components on Endpoints alert detail pane on Alerts page Given open url And wait load page - And click on row root with value "cat-vs-dog-classification" in "name" column in "Projects_Table" table on "Projects" wizard + And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard And wait load page And select "tab" with "Alerts" value in breadcrumbs menu And wait load page @@ -374,7 +373,6 @@ Feature: Alerts Page Then verify "Date_Picker_Filter_Dropdown" dropdown on "Alerts" wizard selected option value "Past 24 hours" When select "Any time" option in "Date_Picker_Filter_Dropdown" filter dropdown on "Alerts" wizard And wait load page - # Add data to the mock to check the following elements Then verify "Alerts_Table" element visibility on "Alerts" wizard Then click on "Table_FilterBy_Button" element on "Alerts" wizard When select "Endpoint" option in "Entity_Type_Filter_Dropdown" filter dropdown on "FilterBy_Popup" wizard @@ -385,7 +383,7 @@ Feature: Alerts Page When click on cell with row index 1 in "alertName" column in "Alerts_Table" table on "Alerts" wizard And wait load page Then verify "Header" element visibility on "Alerts_Endpoint_Info_Pane" wizard - Then "Header" element on "Alerts_Endpoint_Info_Pane" should contains "data-drift" value + Then "Header" element on "Alerts_Endpoint_Info_Pane" should contains "alert-name-uqbxb-proj-default" value Then verify "Cross_Close_Button" element visibility on "Alerts_Endpoint_Info_Pane" wizard Then click on "Cross_Close_Button" element on "Alerts_Endpoint_Info_Pane" wizard Then verify "Header" element not exists on "Alerts_Endpoint_Info_Pane" wizard @@ -393,14 +391,14 @@ Feature: Alerts Page And wait load page Then verify "Header" element visibility on "Alerts_Endpoint_Info_Pane" wizard Then verify "Overview_General_Headers" element visibility on "Alerts_Endpoint_Info_Pane" wizard - Then verify "Overview_General_Headers" on "Alerts_Endpoint_Info_Pane" wizard should contains "Alerts_Endpoint_Info_Pane"."Overview_General_Headers" + Then verify "Overview_General_Headers" on "Alerts_Endpoint_Info_Pane" wizard should contains "Alerts_Endpoint_Info_Pane"."Overview_General_Headers_Per_Project" Then verify "Overview_Trigger_Criteria" element visibility on "Alerts_Endpoint_Info_Pane" wizard Then verify "Overview_Trigger_Criteria" on "Alerts_Endpoint_Info_Pane" wizard should contains "Alerts_Jobs_Info_Pane"."Overview_Trigger_Criteria_Headers" Then verify "Notifications_Header" element visibility on "Alerts_Endpoint_Info_Pane" wizard Then verify "Notifications_Item" element visibility on "Alerts_Endpoint_Info_Pane" wizard Then verify "Date_Picker_Filter_Dropdown" element visibility on "Alerts_Endpoint_Info_Pane" wizard Then verify "Date_Picker_Filter_Dropdown" dropdown on "Alerts_Endpoint_Info_Pane" wizard selected option value "Past 24 hours" - Then verify "Date_Picker_Filter_Dropdown" dropdown element on "Alerts_Endpoint_Info_Pane" wizard should contains "Dropdown_Options"."Date_Picker_Filter_Options" + Then verify "Date_Picker_Filter_Dropdown" dropdown element on "Alerts_Endpoint_Info_Pane" wizard should contains "Dropdown_Options"."Date_Picker_Filter_Options_Endpoint" Then verify "Metrics_App_Name" element visibility on "Alerts_Endpoint_Info_Pane" wizard Then verify "Metrics_Stats_Card" element visibility on "Alerts_Endpoint_Info_Pane" wizard Then click on "Cross_Close_Button" element on "Alerts_Endpoint_Info_Pane" wizard @@ -411,11 +409,10 @@ Feature: Alerts Page @MLAlert @smoke - # TODO: Add data to the mock to check the following elements (existing alerts with application type) Scenario: MLAlert008 - Check components on Application alert detail pane on Alerts page Given open url And wait load page - And click on row root with value "cat-vs-dog-classification" in "name" column in "Projects_Table" table on "Projects" wizard + And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard And wait load page And select "tab" with "Alerts" value in breadcrumbs menu And wait load page @@ -426,7 +423,6 @@ Feature: Alerts Page Then verify "Date_Picker_Filter_Dropdown" dropdown on "Alerts" wizard selected option value "Past 24 hours" When select "Any time" option in "Date_Picker_Filter_Dropdown" filter dropdown on "Alerts" wizard And wait load page - # Add data to the mock to check the following elements Then verify "Alerts_Table" element visibility on "Alerts" wizard Then click on "Table_FilterBy_Button" element on "Alerts" wizard When select "Application" option in "Entity_Type_Filter_Dropdown" filter dropdown on "FilterBy_Popup" wizard @@ -445,7 +441,7 @@ Feature: Alerts Page And wait load page Then verify "Header" element visibility on "Alerts_Application_Info_Pane" wizard Then verify "Overview_General_Headers" element visibility on "Alerts_Application_Info_Pane" wizard - Then verify "Overview_General_Headers" on "Alerts_Application_Info_Pane" wizard should contains "Alerts_Application_Info_Pane"."Overview_General_Headers" + Then verify "Overview_General_Headers" on "Alerts_Application_Info_Pane" wizard should contains "Alerts_Application_Info_Pane"."Overview_General_Headers_Per_Project" Then verify "Overview_Trigger_Criteria" element visibility on "Alerts_Application_Info_Pane" wizard Then verify "Overview_Trigger_Criteria" on "Alerts_Application_Info_Pane" wizard should contains "Alerts_Jobs_Info_Pane"."Overview_Trigger_Criteria_Headers" Then verify "Notifications_Header" element visibility on "Alerts_Application_Info_Pane" wizard diff --git a/tests/features/alertsMonitoring.feature b/tests/features/alertsMonitoring.feature index 7ea7488fdc..10e1f89a38 100644 --- a/tests/features/alertsMonitoring.feature +++ b/tests/features/alertsMonitoring.feature @@ -256,7 +256,6 @@ Feature: Alerts Monitoring Page @MLAM @smoke - # TODO: Add data to the mock to check the following elements (existing job data for details popup) Scenario: MLAM006 - Check components in Job detail pop-up on Job alert detail pane Given open url And wait load page @@ -282,14 +281,29 @@ Feature: Alerts Monitoring Page Then verify "Overview_General_Headers" element visibility on "Alerts_Jobs_Info_Pane" wizard Then verify "Overview_General_Headers" on "Alerts_Jobs_Info_Pane" wizard should contains "Alerts_Jobs_Info_Pane"."Overview_General_Headers" Then verify "Job_Detail_PopUp_Link" element visibility on "Alerts_Jobs_Info_Pane" wizard + When select "Any time" option in "Date_Picker_Filter_Dropdown" filter dropdown on "Alerts_Monitoring" wizard + And wait load page + Then type value "obryv-default" to "Search_By_Name_Filter_Input" field on "Alerts_Monitoring" wizard + Then click on "Refresh_Button" element on "Alerts_Monitoring" wizard + And wait load page + Then value in "alertName" column with "text" in "Alerts_Table" on "Alerts_Monitoring" wizard should contains "alert-name-obryv-default" + And wait load page + Then verify "Alerts_Table" element visibility on "Alerts_Monitoring" wizard + Then value in "entityType" column with "tooltip" in "Alerts_Table" on "Alerts_Monitoring" wizard should contains "Job" + When click on cell with row index 1 in "alertName" column in "Alerts_Table" table on "Alerts_Monitoring" wizard + And wait load page + Then verify "Header" element visibility on "Alerts_Jobs_Info_Pane" wizard + Then "Header" element on "Alerts_Jobs_Info_Pane" should contains "alert-name-obryv-default" value + Then verify "Overview_General_Headers" element visibility on "Alerts_Jobs_Info_Pane" wizard + Then verify "Overview_General_Headers" on "Alerts_Jobs_Info_Pane" wizard should contains "Alerts_Jobs_Info_Pane"."Overview_General_Headers" + Then verify "Job_Detail_PopUp_Link" element visibility on "Alerts_Jobs_Info_Pane" wizard Then click on "Job_Detail_PopUp_Link" element on "Alerts_Jobs_Info_Pane" wizard - # Add data to the mock to check the following elements Then verify if "Modal_Transition_Popup" popup dialog appears Then verify "Title" element visibility on "Modal_Transition_Popup" wizard - Then "Title" element on "Modal_Transition_Popup" should contains "erann-test" value + Then "Title" element on "Modal_Transition_Popup" should contains "test-func-oyn-handler" value Then verify "Data_Status" element visibility on "Modal_Transition_Popup" wizard Then verify "State_Icon" element visibility on "Modal_Transition_Popup" wizard - Then verify "State_Icon" element on "Modal_Transition_Popup" wizard should display hover tooltip "Jobs_Monitor_Tab_Info_Pane"."Error_State" + Then verify "State_Icon" element on "Modal_Transition_Popup" wizard should display hover tooltip "Jobs_Monitor_Tab_Info_Pane"."Error_State_With_Message" Then verify "Refresh_Button" element visibility on "Modal_Transition_Popup" wizard Then verify "Refresh_Button" element on "Modal_Transition_Popup" wizard should display hover tooltip "Common_Tooltips"."Refresh_Button" Then click on "Refresh_Button" element on "Modal_Transition_Popup" wizard @@ -332,17 +346,17 @@ Feature: Alerts Monitoring Page Then verify "Logs" tab is active in "Tab_Selector" on "Modal_Transition_Popup" wizard Then verify "Logs_Text_container" element visibility on "Modal_Transition_Popup" wizard Then verify "Logs_Refresh_Button" element visibility on "Modal_Transition_Popup" wizard - And verify "No_Data_Message" element visibility on "commonPagesHeader" wizard - Then "No_Data_Message" component on "commonPagesHeader" should contains "No_Data_Message"."No_Data" + Then click on "Logs_Refresh_Button" element on "Modal_Transition_Popup" wizard + And wait load page + Then verify "Logs_Text_container" element visibility on "Modal_Transition_Popup" wizard And select "Pods" tab in "Tab_Selector" on "Modal_Transition_Popup" wizard And wait load page Then verify "Pods" tab is active in "Tab_Selector" on "Modal_Transition_Popup" wizard And verify "No_Data_Message" element visibility on "commonPagesHeader" wizard - Then "No_Data_Message" component on "commonPagesHeader" should contains "No_Data_Message"."No_Pods_data" + Then "No_Data_Message" component on "commonPagesHeader" should contains "No_Data_Message"."No_Pods_data_Completion" @MLAM @smoke - # TODO: Add data to the mock to check the following elements Scenario: MLAM007 - Check components on Endpoints alert detail pane Given open url And wait load page @@ -379,20 +393,34 @@ Feature: Alerts Monitoring Page Then verify "Overview_Trigger_Criteria" on "Alerts_Endpoint_Info_Pane" wizard should contains "Alerts_Jobs_Info_Pane"."Overview_Trigger_Criteria_Headers" Then verify "Notifications_Header" element visibility on "Alerts_Endpoint_Info_Pane" wizard Then verify "Notifications_Item" element visibility on "Alerts_Endpoint_Info_Pane" wizard - Then verify "Date_Picker_Filter_Dropdown" element visibility on "Alerts_Endpoint_Info_Pane" wizard - Then verify "Date_Picker_Filter_Dropdown" dropdown on "Alerts_Endpoint_Info_Pane" wizard selected option value "Past 24 hours" - Then verify "Date_Picker_Filter_Dropdown" dropdown element on "Alerts_Endpoint_Info_Pane" wizard should contains "Dropdown_Options"."Date_Picker_Filter_Options_Endpoint" - Then click on "Header" element on "Alerts_Endpoint_Info_Pane" wizard - And wait load page - # Add data to the mock to check the following elements - # Then verify "Metrics_App_Name" element visibility on "Alerts_Endpoint_Info_Pane" wizard - # Then verify "Metrics_Stats_Card" element visibility on "Alerts_Endpoint_Info_Pane" wizard Then verify "Metrics_Stats_Card_Empty" element visibility on "Alerts_Endpoint_Info_Pane" wizard + Then "Metrics_Stats_Card_Empty" element on "Alerts_Endpoint_Info_Pane" should contains "Metrics data not found" value Then click on "Cross_Close_Button" element on "Alerts_Endpoint_Info_Pane" wizard Then verify "Header" element not exists on "Alerts_Endpoint_Info_Pane" wizard When click on cell with row index 1 in "alertName" column in "Alerts_Table" table on "Alerts_Monitoring" wizard And wait load page Then verify "Header" element visibility on "Alerts_Endpoint_Info_Pane" wizard + When select "Any time" option in "Date_Picker_Filter_Dropdown" filter dropdown on "Alerts_Monitoring" wizard + And wait load page + When click on cell with value "alert-name-uqbxb-proj-default" in "alertName" column in "Alerts_Table" table on "Alerts_Monitoring" wizard + And wait load page + Then verify "Header" element visibility on "Alerts_Endpoint_Info_Pane" wizard + Then verify "Overview_General_Headers" element visibility on "Alerts_Endpoint_Info_Pane" wizard + Then verify "Overview_General_Headers" on "Alerts_Endpoint_Info_Pane" wizard should contains "Alerts_Endpoint_Info_Pane"."Overview_General_Headers" + Then verify "Overview_Trigger_Criteria" element visibility on "Alerts_Endpoint_Info_Pane" wizard + Then verify "Overview_Trigger_Criteria" on "Alerts_Endpoint_Info_Pane" wizard should contains "Alerts_Jobs_Info_Pane"."Overview_Trigger_Criteria_Headers" + Then verify "Notifications_Header" element visibility on "Alerts_Endpoint_Info_Pane" wizard + Then verify "Notifications_Item" element visibility on "Alerts_Endpoint_Info_Pane" wizard + Then verify "Date_Picker_Filter_Dropdown" element visibility on "Alerts_Endpoint_Info_Pane" wizard + Then verify "Date_Picker_Filter_Dropdown" dropdown on "Alerts_Endpoint_Info_Pane" wizard selected option value "Past 24 hours" + Then verify "Date_Picker_Filter_Dropdown" dropdown element on "Alerts_Endpoint_Info_Pane" wizard should contains "Dropdown_Options"."Date_Picker_Filter_Options_Endpoint" + Then click on "Header" element on "Alerts_Endpoint_Info_Pane" wizard + And wait load page + Then verify "Metrics_App_Name" element visibility on "Alerts_Endpoint_Info_Pane" wizard + Then verify "Metrics_Stats_Card" element visibility on "Alerts_Endpoint_Info_Pane" wizard + Then verify "Metrics_Stats_Card_Metric_Name" element visibility on "Alerts_Endpoint_Info_Pane" wizard + Then verify "Metrics_Stats_Card_Metric_BodyBar" element visibility on "Alerts_Endpoint_Info_Pane" wizard + Then verify "Metrics_Stats_Card_Metric_BodyLine" element visibility on "Alerts_Endpoint_Info_Pane" wizard @MLAM @smoke diff --git a/tests/features/artifacts.feature b/tests/features/artifacts.feature index 941178179d..7ab1e75205 100644 --- a/tests/features/artifacts.feature +++ b/tests/features/artifacts.feature @@ -300,76 +300,6 @@ Feature: Artifacts Page Then click on "Tabel_View_Button" element on "Files_Info_Pane" wizard Then verify "Cross_Close_Button" element visibility on "Files_Info_Pane" wizard - @MLA - @passive - @smoke - Scenario: MLA013 - Check Details panel still active on page refresh - # * set tear-down property "project" created with "automation-test" value - # * set tear-down property "file" created in "automation-test" project with "test-file" value - * create "automation-test" MLRun Project with code 201 - * create "test-file" File with "test" tag in "automation-test" project with code 200 - Given open url - And wait load page - And click on row root with value "automation-test" in "name" column in "Projects_Table" table on "Projects" wizard - And wait load page - And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard - And click on cell with value "Artifacts" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard - And wait load page - Then verify "Table_FilterBy_Button" element on "Files" wizard should display hover tooltip "Common_Tooltips"."FilterBy_Button" - Then click on "Table_FilterBy_Button" element on "Files" wizard - Then select "test" option in "Table_Tree_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard - Then click on "Apply_Button" element on "FilterBy_Popup" wizard - And wait load page - When click on cell with value "test-file" in "name" column in "Files_Table" table on "Files" wizard - And wait load page - Then check "test" value in "tag" column in "Overview_Table" table on "Files_Info_Pane" wizard - Then click on "Edit_btn_table_view" element on "Files_Info_Pane" wizard - And wait load page - When type value "v1" to "Version_tag_Input" field on "Files_Info_Pane" wizard - Then click on "Apply_Button" element on "Files_Info_Pane" wizard - Then click on "Apply_Changes_Button" element on "Files_Info_Pane" wizard - And wait load page - Then verify "Info_Pane_Tab_Selector" element visibility on "Files_Info_Pane" wizard - Then verify "Not_In_Filtered_List_Message" element visibility on "Files_Info_Pane" wizard - Then "Not_In_Filtered_List_Message" component on "Files_Info_Pane" should be equal "Files_Info_Pane"."Info_Banner_Message" - Then verify "Info_Pane_Tab_Selector" element visibility on "Files_Info_Pane" wizard - Then verify "Info_Pane_Tab_Selector" on "Files_Info_Pane" wizard should contains "Files_Info_Pane"."Tab_List" - Then verify "Overview" tab is active in "Info_Pane_Tab_Selector" on "Files_Info_Pane" wizard - Then verify "Header" element visibility on "Files_Info_Pane" wizard - Then "Header" element on "Files_Info_Pane" should contains "test-file" value - Then refresh a page - And wait load page - Then verify "Info_Pane_Tab_Selector" element visibility on "Files_Info_Pane" wizard - Then verify "Not_In_Filtered_List_Message" element visibility on "Files_Info_Pane" wizard - Then "Not_In_Filtered_List_Message" component on "Files_Info_Pane" should be equal "Files_Info_Pane"."Info_Banner_Message" - Then verify "Info_Pane_Tab_Selector" element visibility on "Files_Info_Pane" wizard - Then verify "Info_Pane_Tab_Selector" on "Files_Info_Pane" wizard should contains "Files_Info_Pane"."Tab_List" - Then verify "Overview" tab is active in "Info_Pane_Tab_Selector" on "Files_Info_Pane" wizard - Then verify "Header" element visibility on "Files_Info_Pane" wizard - Then "Header" element on "Files_Info_Pane" should contains "test-file" value - Then verify "Table_Refresh_Button" element visibility on "Files" wizard - Then verify "Table_Refresh_Button" element on "Files" wizard should display hover tooltip "Common_Tooltips"."Refresh_Button" - Then click on "Table_Refresh_Button" element on "Files" wizard - And wait load page - Then verify "Info_Pane_Tab_Selector" element visibility on "Files_Info_Pane" wizard - Then verify "Not_In_Filtered_List_Message" element visibility on "Files_Info_Pane" wizard - Then "Not_In_Filtered_List_Message" component on "Files_Info_Pane" should be equal "Files_Info_Pane"."Info_Banner_Message" - Then verify "Info_Pane_Tab_Selector" element visibility on "Files_Info_Pane" wizard - Then verify "Info_Pane_Tab_Selector" on "Files_Info_Pane" wizard should contains "Files_Info_Pane"."Tab_List" - Then verify "Overview" tab is active in "Info_Pane_Tab_Selector" on "Files_Info_Pane" wizard - Then verify "Header" element visibility on "Files_Info_Pane" wizard - Then click on "Cross_Close_Button" element on "Files_Info_Pane" wizard - And wait load page - Then verify "Header" element not exists on "Files_Info_Pane" wizard - When click on cell with value "test-file" in "name" column in "Files_Table" table on "Files" wizard - And wait load page - Then verify "Info_Pane_Tab_Selector" element visibility on "Files_Info_Pane" wizard - Then verify "Not_In_Filtered_List_Message" element not exists on "Files_Info_Pane" wizard - Then verify "Info_Pane_Tab_Selector" element visibility on "Files_Info_Pane" wizard - Then verify "Info_Pane_Tab_Selector" on "Files_Info_Pane" wizard should contains "Files_Info_Pane"."Tab_List" - Then verify "Overview" tab is active in "Info_Pane_Tab_Selector" on "Files_Info_Pane" wizard - Then verify "Header" element visibility on "Files_Info_Pane" wizard - @MLA @passive @inProgress @@ -403,11 +333,19 @@ Feature: Artifacts Page Then verify "Pop_Out_Button" element visibility on "Files_Info_Pane" wizard Then click on "Pop_Out_Button" element on "Files_Info_Pane" wizard And wait load page - Then verify "Preview_Row" element visibility on "Artifact_Preview_Popup" wizard - Then verify "Cross_Cancel_Button" element visibility on "Artifact_Preview_Popup" wizard - Then verify "Preview_Header" on "Artifact_Preview_Popup" wizard should contains "Preview_Pop_Up"."Table_Header" - Then check "download_btn" visibility in "Preview_Row" on "Artifact_Preview_Popup" wizard with 1 offset - Then click on "Download_Button" element on "Artifact_Preview_Popup" wizard + Then verify "Preview_Table" element visibility on "Preview_Popup" wizard + Then verify visibility of header column "name" in "Preview_Table" table on "Preview_Popup" wizard + Then check "Name" header value in "name" column in "Preview_Table" table on "Preview_Popup" wizard + Then verify visibility of header column "path" in "Preview_Table" table on "Preview_Popup" wizard + Then check "Path" header value in "path" column in "Preview_Table" table on "Preview_Popup" wizard + Then verify visibility of header column "size" in "Preview_Table" table on "Preview_Popup" wizard + Then check "Size" header value in "size" column in "Preview_Table" table on "Preview_Popup" wizard + Then verify visibility of header column "updated" in "Preview_Table" table on "Preview_Popup" wizard + Then check "Updated" header value in "updated" column in "Preview_Table" table on "Preview_Popup" wizard + Then value in "name" column with "text" in "Preview_Table" on "Preview_Popup" wizard should contains "download_content" + Then verify "Cross_Cancel_Button" element visibility on "Preview_Popup" wizard + Then verify "Download_Button" element visibility on "Preview_Popup" wizard + Then click on "Download_Button" element on "Preview_Popup" wizard And wait load page And wait load page Then verify "Download_Pop_Up" element visibility on "Downloads_Popup" wizard @@ -417,7 +355,7 @@ Feature: Artifacts Page Then verify "Header_Download_Pop_Up" element visibility on "Downloads_Popup" wizard Then "Header_Download_Pop_Up" element on "Downloads_Popup" should contains "Downloads" value Then click on "Download_Pop_Up_Cross_Cancel_Button" element on "Downloads_Popup" wizard - Then click on "Cross_Cancel_Button" element on "Artifact_Preview_Popup" wizard + Then click on "Cross_Cancel_Button" element on "Preview_Popup" wizard Then verify "Preview_Tab_Info_Pane_Table" element visibility on "Files_Info_Pane" wizard @MLA @@ -471,7 +409,6 @@ Feature: Artifacts Page When select "V3IO" option in "Path_Scheme_Combobox" combobox on "Target_Path" accordion on "Register_File_Popup" wizard When type value "target/path" to "Path_Scheme_Combobox" field on "Target_Path" on "Register_File_Popup" wizard Then click on "Register_Button" element on "Register_File_Popup" wizard - And wait load page Then verify if "Confirm_Popup" popup dialog appears Then "Title" element on "Confirm_Popup" should contains "Overwrite artifact?" value When click on "Overwrite_Button" element on "Confirm_Popup" wizard @@ -480,11 +417,11 @@ Feature: Artifacts Page When click on cell with row index 1 in "name" column in "Files_Table" table on "Files" wizard And wait load page Then verify "Header" element visibility on "Files_Info_Pane" wizard - Then "Header" element on "Files_Info_Pane" should contains "test-file" value - #TODO: Verify text message 'The you are viewing was updated. Close the detail panel and refresh the list to see the current version.' on Files_Info_Pane + Then "Header" element on "Files_Info_Pane" should contains "survival-curves_km-survival" value + Then verify "Not_In_Filtered_List_Message" element visibility on "Files_Info_Pane" wizard + Then "Not_In_Filtered_List_Message" component on "Files_Info_Pane" should be equal "Files_Info_Pane"."Info_Banner_Message" #TODO: Verify that editing the tag to an empty string '' will delete the artifact instance - @MLA @passive @inProgress @@ -513,7 +450,7 @@ Feature: Artifacts Page Then verify "Title" element visibility on "Modal_Transition_Popup" wizard Then "Title" element on "Modal_Transition_Popup" should contains "survival-curves_km-timelines" value Then verify "Data_Status" element visibility on "Modal_Transition_Popup" wizard - Then "Data_Status" element on "Modal_Transition_Popup" should contains "Aug 29, 2021, 10:54:15 PM" value + Then "Data_Status" element on "Modal_Transition_Popup" should contains "Aug 29, 2021, 07:54:15 PM" value Then verify "Refresh_Button" element visibility on "Modal_Transition_Popup" wizard Then click on "Refresh_Button" element on "Modal_Transition_Popup" wizard And wait load page @@ -823,7 +760,6 @@ Feature: Artifacts Page When select "V3IO" option in "Path_Scheme_Combobox" combobox on "Target_Path" accordion on "Register_File_Popup" wizard When type value "target/path" to "Path_Scheme_Combobox" field on "Target_Path" on "Register_File_Popup" wizard Then click on "Register_Button" element on "Register_File_Popup" wizard - And wait load page Then verify if "Confirm_Popup" popup dialog appears Then "Title" element on "Confirm_Popup" should contains "Overwrite artifact?" value When click on "Overwrite_Button" element on "Confirm_Popup" wizard @@ -875,7 +811,6 @@ Feature: Artifacts Page When select "V3IO" option in "Path_Scheme_Combobox" combobox on "Target_Path" accordion on "Register_File_Popup" wizard When type value "target/path" to "Path_Scheme_Combobox" field on "Target_Path" on "Register_File_Popup" wizard Then click on "Register_Button" element on "Register_File_Popup" wizard - And wait load page Then verify if "Confirm_Popup" popup dialog appears Then "Title" element on "Confirm_Popup" should contains "Overwrite artifact?" value When click on "Overwrite_Button" element on "Confirm_Popup" wizard @@ -896,6 +831,101 @@ Feature: Artifacts Page And wait load page Then verify "Table_Tree_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected attribute option value "All tags" + @MLA + @passive + @smoke + Scenario: MLA013 - Check Details panel still active on page refresh + Given open url + And wait load page + And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard + And click on cell with value "Artifacts" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard + And wait load page + Then select "Add a tag" option in action menu on "Files" wizard in "Files_Table" table at row with "training_iteration_results" value in "name" column + And wait load page + Then verify "Add_Tag_Popup" element visibility on "Add_Tag_Popup" wizard + Then type value "test" to "Tag_Input" field on "Add_Tag_Popup" wizard + Then click on "Add_Button" element on "Add_Tag_Popup" wizard + And wait load page + Then verify "Notification_Pop_Up" element visibility on "Notification_Popup" wizard + And wait load page + Then "Notification_Pop_Up" element on "Notification_Popup" should contains "Tag was added successfully" value + And wait load page + Then verify "Notification_Pop_Up_Cross_Close_Button" element visibility on "Notification_Popup" wizard + Then click on "Notification_Pop_Up_Cross_Close_Button" element on "Notification_Popup" wizard + Then verify "Table_FilterBy_Button" element on "Files" wizard should display hover tooltip "Common_Tooltips"."FilterBy_Button" + Then click on "Table_FilterBy_Button" element on "Files" wizard + Then select "test" option in "Table_Tree_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard + Then click on "Apply_Button" element on "FilterBy_Popup" wizard + And wait load page + When click on cell with value "training_iteration_results" in "name" column in "Files_Table" table on "Files" wizard + And wait load page + Then check "test" value in "tag" column in "Overview_Table" table on "Files_Info_Pane" wizard + Then click on "Edit_btn_table_view" element on "Files_Info_Pane" wizard + And wait load page + When type value "v1" to "Version_tag_Input" field on "Files_Info_Pane" wizard + Then click on "Apply_Button" element on "Files_Info_Pane" wizard + Then click on "Apply_Changes_Button" element on "Files_Info_Pane" wizard + And wait load page + Then verify "Info_Pane_Tab_Selector" element visibility on "Files_Info_Pane" wizard + Then verify "Not_In_Filtered_List_Message" element visibility on "Files_Info_Pane" wizard + Then "Not_In_Filtered_List_Message" component on "Files_Info_Pane" should be equal "Files_Info_Pane"."Info_Banner_Message" + Then verify "Info_Pane_Tab_Selector" element visibility on "Files_Info_Pane" wizard + Then verify "Info_Pane_Tab_Selector" on "Files_Info_Pane" wizard should contains "Files_Info_Pane"."Tab_List" + Then verify "Overview" tab is active in "Info_Pane_Tab_Selector" on "Files_Info_Pane" wizard + Then verify "Header" element visibility on "Files_Info_Pane" wizard + Then "Header" element on "Files_Info_Pane" should contains "training_iteration_results" value + Then refresh a page + And wait load page + Then verify "Info_Pane_Tab_Selector" element visibility on "Files_Info_Pane" wizard + Then verify "Not_In_Filtered_List_Message" element visibility on "Files_Info_Pane" wizard + Then "Not_In_Filtered_List_Message" component on "Files_Info_Pane" should be equal "Files_Info_Pane"."Info_Banner_Message" + Then verify "Info_Pane_Tab_Selector" element visibility on "Files_Info_Pane" wizard + Then verify "Info_Pane_Tab_Selector" on "Files_Info_Pane" wizard should contains "Files_Info_Pane"."Tab_List" + Then verify "Overview" tab is active in "Info_Pane_Tab_Selector" on "Files_Info_Pane" wizard + Then verify "Header" element visibility on "Files_Info_Pane" wizard + Then "Header" element on "Files_Info_Pane" should contains "training_iteration_results" value + Then verify "Table_Refresh_Button" element visibility on "Files" wizard + Then verify "Table_Refresh_Button" element on "Files" wizard should display hover tooltip "Common_Tooltips"."Refresh_Button" + Then click on "Table_Refresh_Button" element on "Files" wizard + And wait load page + Then verify "Info_Pane_Tab_Selector" element visibility on "Files_Info_Pane" wizard + Then verify "Not_In_Filtered_List_Message" element visibility on "Files_Info_Pane" wizard + Then "Not_In_Filtered_List_Message" component on "Files_Info_Pane" should be equal "Files_Info_Pane"."Info_Banner_Message" + Then verify "Info_Pane_Tab_Selector" element visibility on "Files_Info_Pane" wizard + Then verify "Info_Pane_Tab_Selector" on "Files_Info_Pane" wizard should contains "Files_Info_Pane"."Tab_List" + Then verify "Overview" tab is active in "Info_Pane_Tab_Selector" on "Files_Info_Pane" wizard + Then verify "Header" element visibility on "Files_Info_Pane" wizard + Then click on "Cross_Close_Button" element on "Files_Info_Pane" wizard + And wait load page + Then verify "Header" element not exists on "Files_Info_Pane" wizard + And verify "No_Data_Message" element visibility on "commonPagesHeader" wizard + Then "No_Data_Message" component on "commonPagesHeader" should be equal "No_Data_Message"."Common_Message_Artifact_Tag" + Then click on "Table_FilterBy_Button" element on "LLM_Prompts" wizard + Then click on "Clear_Button" element on "FilterBy_Popup" wizard + And wait load page + When click on cell with value "training_iteration_results" in "name" column in "Files_Table" table on "Files" wizard + And wait load page + Then verify "Info_Pane_Tab_Selector" element visibility on "Files_Info_Pane" wizard + Then verify "Not_In_Filtered_List_Message" element not exists on "Files_Info_Pane" wizard + Then verify "Info_Pane_Tab_Selector" element visibility on "Files_Info_Pane" wizard + Then verify "Info_Pane_Tab_Selector" on "Files_Info_Pane" wizard should contains "Files_Info_Pane"."Tab_List" + Then verify "Overview" tab is active in "Info_Pane_Tab_Selector" on "Files_Info_Pane" wizard + Then verify "Header" element visibility on "Files_Info_Pane" wizard + Then click on "Table_FilterBy_Button" element on "Files" wizard + Then select "v1" option in "Table_Tree_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard + Then click on "Apply_Button" element on "FilterBy_Popup" wizard + And wait load page + When click on cell with value "training_iteration_results" in "name" column in "Files_Table" table on "Files" wizard + And wait load page + Then verify "Info_Pane_Tab_Selector" element visibility on "Files_Info_Pane" wizard + Then verify "Not_In_Filtered_List_Message" element not exists on "Files_Info_Pane" wizard + Then verify "Info_Pane_Tab_Selector" element visibility on "Files_Info_Pane" wizard + Then verify "Info_Pane_Tab_Selector" on "Files_Info_Pane" wizard should contains "Files_Info_Pane"."Tab_List" + Then verify "Overview" tab is active in "Info_Pane_Tab_Selector" on "Files_Info_Pane" wizard + Then verify "Header" element visibility on "Files_Info_Pane" wizard + @MLA @smoke Scenario: MLA023 - Check components on artifact Full view content diff --git a/tests/features/common-tools/common-consts.js b/tests/features/common-tools/common-consts.js index 9bb10f8560..137ae8dde0 100644 --- a/tests/features/common-tools/common-consts.js +++ b/tests/features/common-tools/common-consts.js @@ -17,21 +17,27 @@ illegal under applicable law, and the grant of the foregoing license under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ -module.exports = { +export default { Project: { - Create_New_Options: [ - 'Batch run', - 'Feature set', + Quick_Actions_Options: [ + 'Register dataset', 'Register artifact', - 'Register dataset' + 'Batch run', + 'Train model', + 'Batch inference', + 'Create real-time function' ], - Create_New_Options_Demo: [ + Quick_Actions_Options_Demo: [ + 'Register dataset', + 'Register artifact', 'Batch run', + 'Train model', + 'Batch inference', + 'Create real-time function', + 'Register model', 'ML function', 'Feature set', - 'Register artifact', - 'Register model', - 'Register dataset' + 'Create feature vector' ], Online_Status: 'online', Data_Collection_Description: @@ -62,20 +68,38 @@ module.exports = { ] }, Real_Time_Pipeline_Pane: { + In_Monitoring_State: 'In monitoring', + Chip_Tooltip: 'my-endpoint', Overview_Headers: [ 'Type:', - 'After:', 'Class name:', 'Function name:', + 'Arguments:', 'Handler:', 'Input path:', 'Result path:' + ], + Overview_Headers_Model_Runner: [ + 'Type:', + 'Class name:', + 'Function name:', + 'Arguments:', + 'Input path:', + 'Result path:' + ], + Running_Models_Headers: [ + 'Model endpoint:', + 'Model artifact:', + 'Class name:', + 'Input path:', + 'Result path:', + 'Outputs:', + 'Execution mechanism:' ] }, Feature_Sets_Info_Pane: { Created_State: 'Created', - Tab_List: ['Overview', 'Features', 'Transformations', 'Preview', 'Statistics'], - Tab_List_Demo: ['Overview', 'Features', 'Transformations', 'Preview', 'Statistics', 'Analysis'], + Tab_List: ['Overview', 'Features', 'Transformations', 'Preview', 'Statistics', 'Analysis'], Overview_General_Headers: [ 'Description:', 'Labels:', @@ -90,7 +114,8 @@ module.exports = { ] }, Feature_Vectors_Info_Pane: { - Tab_List: ['Overview', 'Requested Features'], + Tab_List: ['Overview', 'Requested Features', 'Analysis'], + Tab_List_Extended: ['Overview', 'Requested Features', 'Returned Features', 'Statistics', 'Analysis'], Overview_General_Headers: [ 'Description:', 'Labels:', @@ -105,6 +130,7 @@ module.exports = { }, Common_Lists: { Action_Menu_List: ['Add a tag', 'Download', 'Copy URI', 'View YAML', 'Delete', 'Delete all versions'], + Action_Menu_List_LLM_Prompt: ['Add a tag', 'Download', 'Copy URI', 'View YAML'], Action_Menu_List_Version_History: ['Add a tag', 'Download', 'Copy URI', 'View YAML', 'Delete'], Action_Menu_List_Expanded: ['Add a tag', 'Download', 'Copy URI', 'View YAML', 'Delete all'], Action_Menu_List_Dataset_Transition_Popup: ['Download', 'Copy URI', 'View YAML'], @@ -116,8 +142,8 @@ module.exports = { Ranking_Criteria_List: ['Min', 'Max'] }, Datasets_Info_Pane: { - Tab_List: ['Overview', 'Preview', 'Metadata'], - Info_Banner_Message: /The (.+?) is not in the filtered list\. Closing the details panel will return you to the current list\./, + Tab_List: ['Overview', 'Preview', 'Metadata', 'Analysis'], + Info_Banner_Message: /The dataset is not in the filtered list\. Closing the details panel will return you to the current list\./, Overview_General_Headers: [ 'Hash:', 'Key:', @@ -149,6 +175,26 @@ module.exports = { ], Overview_Producer_Headers: ['Name:', 'Kind:', 'Tag:', 'Owner:', 'UID:'] }, + LLM_Prompts_Info_Pane: { + Tab_List: ['Overview', 'Prompt Template', 'Generation Configuration'], + Tab_List_Prompt_Template: ['Prompt', 'Arguments'], + Info_Banner_Message: /The LLM prompt is not in the filtered list\. Closing the details panel will return you to the current list\./, + Overview_General_Headers: [ + 'Key:', + 'Description:', + 'Model name:', + 'Hash:', + 'Version tag:', + 'Original source:', + 'Iter:', + 'URI:', + 'Path:', + 'UID:', + 'Updated:', + 'Labels:' + ], + Overview_Producer_Headers: ['Name:', 'Kind:', 'Tag:', 'Owner:', 'UID:'] + }, Alerts_Jobs_Info_Pane: { Overview_General_Headers: [ 'Project Name:', @@ -177,6 +223,14 @@ module.exports = { 'Timestamp:', 'Severity:' ], + Overview_General_Headers_Per_Project: [ + 'Endpoint ID:', + 'Application Name:', + 'Result Name:', + 'Type:', + 'Timestamp:', + 'Severity:' + ], Overview_Trigger_Criteria_Headers: ['Trigger criteria count:', 'Trigger criteria time period:'] }, Alerts_Application_Info_Pane: { @@ -187,6 +241,12 @@ module.exports = { 'Timestamp:', 'Severity:' ], + Overview_General_Headers_Per_Project: [ + 'Application Name:', + 'Type:', + 'Timestamp:', + 'Severity:' + ], Overview_Trigger_Criteria_Headers: ['Trigger criteria count:', 'Trigger criteria time period:'] }, ML_Functions_Tab: { @@ -217,14 +277,14 @@ module.exports = { 'Kind:', 'Code entry point:', 'Internal URL:', - 'Image:', + //'Image:', hidden due to ML-7988, ML-8014 'Application image:', 'Version tag:', 'Hash:', 'Internal port:', - 'Code origin:', + // 'Code origin:', hidden due to ML-7988, ML-8014 'Updated:', - 'Default handler:', + // 'Default handler:', hidden due to ML-7988, ML-8014 'Description:' ] }, @@ -268,6 +328,7 @@ module.exports = { 'Metrics:' ], Overview_Producer_Headers: ['Name:', 'Kind:', 'URI:', 'Owner:', 'Workflow:', 'UID:'], + Overview_Producer_Headers_Kind_Project: ['Name:', 'Kind:', 'Tag:', 'Owner:', 'UID:'], Overview_Sources_Headers: ['Name:', 'Path:'] }, Models_Endpoints_Info_Pane: { @@ -380,15 +441,22 @@ module.exports = { Auto_Refresh: 'Uncheck Auto Refresh to view more results', FilterBy_Button: 'Filter', FilterBy_Button_1: 'Filter (1)', + FilterBy_Button_2: 'Filter (2)', + Argument: 'The essence of all things', Show_All_Versions: 'Show all versions', + Open_Metrics: 'Open metrics', Refresh_Button: 'Refresh', + Back_Button: 'Back', Expand_All_Button: 'Expand all', - In_Process_Jobs: 'Aborting, Pending, Running', - In_Process_Workflows: 'Running', + In_Process_Jobs: 'Aborting, Pending, Pending retry, Running', + Running_Tip: 'Running, Terminating', + Running: 'Running', + Failed_Tip: 'Error, Unhealthy', Failed_Jobs: 'Aborted, Error', Failed_Worflows: 'Error, Failed', Succeeded: 'Completed', Statistics_Tab_Tip: 'Statistics reflect the data for the latest ingestion. \n Note that some values may be empty due to the use of different engines for calculating statistics', + Monitoring_Jobs_Box_Title_Tip: 'Number of Job runs, clicking on the counters navigates to jobs screen.', Error_Content: 'Error. Columns must be same length as key', Error_Content_Workflow: "Error. 2021-08-29 20:01:36.582972: W tensorflow/stream_executor/platform/default/dso_loader.cc:60] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /usr/local/lib:/usr/local/lib: 2021-08-29 20:01:36.583019: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine. 2021-08-29 20:01:46.470042: I tensorflow/compiler/jit/xla_cpu_device.cc:41] Not creating XLA devices, tf_xla_enable_xla_devices not set 2021-08-29 20:01:46.470263: W tensorflow/stream_executor/platform/default/dso_loader.cc:60] Could not load dynamic library 'libcuda.so.1'; dlerror: libcuda.so.1: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /usr/local/lib:/usr/local/lib: 2021-08-29 20:01:46.470283: W tensorflow/stream_executor/cuda/cuda_driver.cc:326] failed call to cuInit: UNKNOWN ERROR (303) 2021-08-29 20:01:46.470306: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:156] kernel driver does not appear to be running on this host (train-1193bacd-worker-0): /proc/driver/nvidia/version does not exist 2021-08-29 20:01:46.518782: I tensorflow/core/platform/cpu_feature_guard.cc:142] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX2 FMA To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags. 2021-08-29 20:01:46.518927: I tensorflow/compiler/jit/xla_gpu_device.cc:99] Not creating XLA devices, tf_xla_enable_xla_devices not set Some callbacks may not have access to the averaged metrics, see https://github.com/horovod/horovod/issues/2440 Traceback (most recent call last): File \"/User/demos/image-classification-with-distributed-training/src-tfv2/horovod-training.py\", line 116, in hvd.callbacks.LearningRateWarmupCallback(warmup_epochs=5, verbose=1), TypeError: __init__() missing 1 required positional argument: 'initial_lr'" @@ -489,6 +557,14 @@ module.exports = { Distinct_Keys: 'The partition is based on key.', Source_URL_Input: 'Source URL is the Git Repo that is associated with the project. When the user pulls the project it will use the source URL to pull from', + Secret_Name_Rule_Options: + 'Valid characters: a–z, A–Z, 0–9, –, _, .\n' + + 'Must begin and end with: a–z, A–Z, 0–9\n' + + 'No consecutive characters: ..,, .–,, –.\n' + + 'Max length between two periods: 63\n' + + 'Length – max: 253\n'+ + 'This field is required\n'+ + 'Secret does not reference an MLRun secret defined in another project', SECRET_INPUT_HINT: '• Valid characters: A-Z, a-z, 0-9, -, _, .\n' + '• Must begin and end with: A-Z, a-z, 0-9\n' + @@ -522,9 +598,20 @@ module.exports = { FeatureSets_Stats_Tip: 'Each feature set can have multiple versions, produced by multiple runs and given multiple tags.\n' + ' You can browse them in the Feature store page.', + Model_Version_Tag: 'Enter a model name to enable field.', Artifacts_Stats_Tip: 'Each artifact can have multiple versions, produced by multiple runs and given multiple tags.\n' + - ' You can browse them in the Artifacts page.' + ' You can browse them in the Artifacts page.', + Model_Endpoint_With_Detections: + 'This chart displays the number of model endpoints that had at least one detected issue, in any monitoring application, in the relevant time period', + Project_Monitoring_Counters: 'Counters use a caching mechanism, and are not auto-refreshed.', + Operating_Functions: 'System functions that are used for the monitoring application operation', + Lag: 'Number of messages currently waiting in the app\'s queue', + Commited_Offset: 'Total number of messages handled by the app', + Endpoints_Tip: 'Model endpoints processed by the monitoring app during the selected time frame', + Metrics_Tip: 'This table displays the values of the last metrics captured by the monitoring application. If there are metrics for more than one model endpoint at the same time, the table displays only one of those.', + Shards_Partitions_Status_Tip: 'This table displays the current status of each shard', + Runs_Statistic_Section_Title_Tip: 'Number of Job runs, clicking on the counters navigates to jobs screen.' }, Descriptions: { Archive_Project: @@ -538,7 +625,9 @@ module.exports = { Delete_Scheduled_Job: /Are you sure you want to delete the scheduled job "[^"]+[$"]\? Deleted scheduled jobs can not be restored\./, Delete_Feature: - /You try to delete feature "[^"]+[$"] from vector "[^"]+[$"]\. The feature could be added back later./ + /You try to delete feature "[^"]+[$"] from vector "[^"]+[$"]\. The feature could be added back later./, + Add_A_Tag_Overwrite_Message: + /That combination of name and tag is already in use in an existing (artifact|dataset|plotly|LLM prompt)\. If you proceed, the existing (artifact|dataset|plotly|LLM prompt) will be overwritten/ }, Messages: { How_To_Create: @@ -556,15 +645,21 @@ module.exports = { Running_Job_Action_Menu_Options: ['Run\'s resource monitoring', 'Abort', 'View YAML'], Delete_Run_Message: /Are you sure you want to delete the run with the UID "(.+?)" of the job "(.+?)"\? Deleted runs can not be restored./, Delete_All_Runs_Message: /Are you sure you want to delete all runs of the job "(.+?)"\? Deleted runs can not be restored./, - Workflows_Action_Menu_Options: ['View YAML', 'Retry'], + Terminate_Workflow_Message: /Are you sure you want to terminate the workflow "(.+?)" \(stop its execution\)\? Workflows termination cannot be undone\./, + Workflows_Action_Menu_Options: ['View YAML', 'Retry', 'Terminate'], + Workflows_Running_Action_Menu_Options: ['View YAML', 'Terminate'], Workflows_Info_Pane_Action_Menu_Options: ['Batch re-run', 'Monitoring', 'View YAML', 'Delete'], Pending_Job_Action_Menu_Options: ['Batch re-run', 'Run\'s resource monitoring', 'Abort', 'View YAML'], Schedule_Action_Menu_Options: ['Run now', 'Edit', 'Delete', 'View YAML'], - Workflows_Unsuccessful_Run_Message: 'Workflow did not run successfully\nRETRY' + Workflows_Unsuccessful_Run_Message: 'Workflow did not run successfully\nRETRY', + Workflows_Successful_Run_Message: 'Workflow run successfully.', + Workflows_Unsuccessful_Terminate_Message: 'Workflow "stocks-admin-main 2021-08-30 05-36-35 failed to terminate', + Workflows_Trigger_Termination_Message: 'A request to terminate workflow "stocks-admin-main 2021-08-30 05-36-35" was issued' }, Jobs_Monitor_Tab_Info_Pane: { Pending_State: 'Pending', Error_State: 'Error', + Error_State_With_Message: 'Error. This function intentionally fails', Tab_List: ['Overview', 'Inputs', 'Artifacts', 'Results', 'Logs', 'Pods'], Overview_Headers: [ 'UID:', @@ -581,7 +676,9 @@ module.exports = { 'Labels:', 'Log level:', 'Output path:', - 'Total iterations:' + 'Total iterations:', + 'Attempt count:', + 'Maximum attempts:' ] }, Jobs_Monitor_Tab: { @@ -617,6 +714,7 @@ module.exports = { Event_Type_Endpoint_Filter_Options: ['All', 'Data drift detected', 'Data drift suspected', 'Conc drift detected', 'Conc drift suspected', 'MM performance detected', 'MM performance suspected', 'System performance detected', 'System performance suspected', 'MM app anomaly detected', 'MM app anomaly suspected'], Event_Type_Job_Filter_Options: ['All', 'Job failed'], Event_Type_Application_Filter_Options: ['All', 'MM app failed'], + Endpoint_Mode_Filter_Options: ['All', 'Real-time', 'Batch'], Jobs_Status_Filter_Options: [ 'All', 'Aborted', @@ -624,18 +722,19 @@ module.exports = { 'Completed', 'Error', 'Running', - 'Pending' + 'Pending', + 'Pending retry' ], - Workflows_Status_Filter_Options: ['All', 'Error', 'Failed', 'Running', 'Completed'], + Workflows_Status_Filter_Options: ['All', 'Error', 'Failed', 'Running', 'Completed', 'Terminating'], Jobs_Type_Filter_Options: [ 'All', - 'Local', - 'Dask', - 'Databricks', - 'Handler', 'Job', + 'Spark', 'Horovod', - 'Spark' + 'Dask', + 'Databricks', + 'Local', + 'Handler' ], Scheduled_Type_Filter_Options: [ 'All', @@ -672,6 +771,13 @@ module.exports = { 'Past month', 'Custom range' ], + Date_Picker_Filter_Options_Monitoring_App: [ + 'Past hour', + 'Past 24 hours', + 'Past week', + 'Past month', + 'Custom range' + ], Scheduled_Date_Picker_Filter_Options: [ 'Any time', 'Next hour', @@ -714,18 +820,29 @@ module.exports = { }, No_Data_Message: { Common_Message_Jobs_Monitoring: - /No data matches the filter: "Start time: \d{2}\/\d{2}\/\d{4} \d{2}:\d{2} - \d{2}\/\d{2}\/\d{4} \d{2}:\d{2}, Project: test"/, + /No data matches the filter: "Start time: \d{2}\/\d{2}\/\d{4} \d{2}:\d{2} - \d{2}\/\d{2}\/\d{4} \d{2}:\d{2}, Project: (.+?)"/, Common_Message_Monitor_Jobs_Name: /No data matches the filter: "Name: (.+?)"/, + Common_Message_LLM_Prompt_Name: /No data matches the filter: "Name: (.+?), LLM prompt version tag: (.+?), Show best iteration only: (.+?)"/, + Common_Message_LLM_Prompt_Label: /No data matches the filter: "Name: (.+?), LLM prompt version tag: (.+?), Labels: (.+?), Show best iteration only: (.+?), Model name: (.+?), Model version tag: (.+?)"/, + Common_Message_LLM_Prompt_Tag: /No data matches the filter: "LLM prompt version tag: (.+?), Show best iteration only: (.+?)"/, + Common_Message_LLM_Prompt_Model_Name_Tag: /No data matches the filter: "LLM prompt version tag: (.+?), Show best iteration only: (.+?)"/, + Common_Message_Artifact_Tag: /No data matches the filter: "Version tag: (.+?), Show best iteration only: (.+?)"/, Common_Message_Jobs_Monitoring_Workflow_Project: - /No data matches the filter: "Created at: \d{2}\/\d{2}\/\d{4} \d{2}:\d{2} - \d{2}\/\d{2}\/\d{4} \d{2}:\d{2}, Project: test"/, + /No data matches the filter: "Created at: \d{2}\/\d{2}\/\d{4} \d{2}:\d{2} - \d{2}\/\d{2}\/\d{4} \d{2}:\d{2}, Project: (.+?)"/, Common_Message_Jobs_Monitoring_Status: /No data matches the filter: "Created at: \d{2}\/\d{2}\/\d{4} \d{2}:\d{2} - \d{2}\/\d{2}\/\d{4} \d{2}:\d{2}, Status: (.+?)"/, + Common_Message_Monitoring_Workflow: + /No data matches the filter: "Created at: \d{2}\/\d{2}\/\d{4} \d{2}:\d{2} - \d{2}\/\d{2}\/\d{4} \d{2}:\d{2}"/, + Common_Message_Monitoring_Workflow_Status: + /No data matches the filter: "Status: (.+?)"/, Common_Message_Jobs_Monitoring_Type: /No data matches the filter: "Start time: \d{2}\/\d{2}\/\d{4} \d{2}:\d{2} - \d{2}\/\d{2}\/\d{4} \d{2}:\d{2}, Type: (.+?)"/, Common_Message_Monitor_Jobs: /No data matches the filter: "Start time: \d{2}\/\d{2}\/\d{4} \d{2}:\d{2} - \d{2}\/\d{2}\/\d{4} \d{2}:\d{2}"/, Common_Message_Jobs_Monitoring_Scheduled: - /No data matches the filter: "Scheduled at: \d{2}\/\d{2}\/\d{4} \d{2}:\d{2} - \d{2}\/\d{2}\/\d{4} \d{2}:\d{2}, Project: test"/, + /No data matches the filter: "Scheduled at: \d{2}\/\d{2}\/\d{4} \d{2}:\d{2} - \d{2}\/\d{2}\/\d{4} \d{2}:\d{2}, Project: (.+?)"/, + Common_Message_Scheduled_Type: + /No data matches the filter: "Scheduled at: \d{2}\/\d{2}\/\d{4} \d{2}:\d{2} - \d{2}\/\d{2}\/\d{4} \d{2}:\d{2}, Type: (.+?)"/, Common_Message: 'No data matches the filter: "Version Tag: latest, Name: ccccc"', Common_Message_Feature: 'No data matches the filter: "Version Tag: latest"', Common_Message_Feature_Vector_Tab: @@ -739,9 +856,7 @@ module.exports = { No_Documents_data: 'No data matches the filter: "Version tag: latest, Show best iteration only: true"', No_Files_data: 'No data matches the filter: "Version tag: latest, Labels: v3io_user=123, Show best iteration only: true"', No_Models_data: 'No data matches the filter: "Version tag: latest, Labels: MY-KEY, Show best iteration only: true"', - No_Pods_data: 'Pods not found, it is likely because Kubernetes removed these pods listing' - }, - Preview_Pop_Up: { - Table_Header: ['Name', 'Path', 'Size', 'Updated'] + No_Pods_data: 'Pods not found, it is likely because Kubernetes removed these pods listing', + No_Pods_data_Completion: 'Pods not found, it is likely because Kubernetes removed these pods listing after their completion' } } diff --git a/tests/features/common-tools/common-tools.js b/tests/features/common-tools/common-tools.js index 4383c2891f..7346e0f43d 100644 --- a/tests/features/common-tools/common-tools.js +++ b/tests/features/common-tools/common-tools.js @@ -28,19 +28,19 @@ import { deleteAPISchedule } from '../common/actions/api.actions' -module.exports = { - locatorBuilder: function (strings, ...keys) { - return function (...values) { - const dict = values[values.length - 1] || {} - const result = [strings[0]] - keys.forEach(function (key, i) { - const value = Number.isInteger(key) ? values[key] : dict[key] - result.push(value, strings[i + 1]) - }) - return result.join('') - } - }, - generateInputGroup: function ( +export function locatorBuilder(strings, ...keys) { + return function (...values) { + const dict = values[values.length - 1] || {} + const result = [strings[0]] + keys.forEach(function (key, i) { + const value = Number.isInteger(key) ? values[key] : dict[key] + result.push(value, strings[i + 1]) + }) + return result.join('') + } +} + +export function generateInputGroup ( root, label = false, hint = false, @@ -62,8 +62,9 @@ module.exports = { } return structure - }, - generateNumberInputGroup: function ( + } + +export function generateNumberInputGroup ( root, incDecBtn = false, label = false, @@ -91,8 +92,9 @@ module.exports = { } return structure - }, - generateLabelGroup: function (root, label = false, hintButton = false, hint = false) { + } + +export function generateLabelGroup (root, label = false, hintButton = false, hint = false) { const structure = { elements: {} } structure.root = root @@ -108,8 +110,9 @@ module.exports = { } return structure - }, - generateDropdownGroup: function ( + } + +export function generateDropdownGroup ( root, open_button = false, options = false, @@ -129,8 +132,9 @@ module.exports = { structure.optionsInRoot = options_in_root return structure - }, - generateCheckboxGroup: function (root, checkbox, name, icon) { + } + +export function generateCheckboxGroup (root, checkbox, name, icon) { const structure = { root, elements: {} } structure.elements.checkbox = checkbox ? 'svg[class]' : '' @@ -140,8 +144,9 @@ module.exports = { structure.elements.icon = icon ? 'svg:not([class])' : '' return structure - }, - generateTextAreaGroup: function (root, counter = '.form-field__counter') { + } + +export function generateTextAreaGroup (root, counter = '.form-field__counter') { return { root, elements: { @@ -152,8 +157,9 @@ module.exports = { counter } } - }, - parseString: function (string) { + } + +export function parseString (string) { const rulesArray = string.split('\n') const lengthRule = getLength(rulesArray) const validCharactersRule = getRule(rulesArray, 'valid characters') @@ -172,8 +178,9 @@ module.exports = { notStartWith, notConsecutiveCharacters ) - }, - clearBackendAfterTest: function (driver, items) { + } + +export function clearBackendAfterTest (driver, items) { items.forEach(item => { switch (item.type) { case 'project': @@ -194,15 +201,15 @@ module.exports = { return null } }) - }, - setRequestsFailureCondition: async shouldFail => { - try { - const response = await axios.post('http://localhost:30000/set-failure-condition', { - shouldFail - }) - console.log(response.data) - } catch (error) { - console.error(`Error setting failure condition: ${error}`) - } + } + +export async function setRequestsFailureCondition(shouldFail) { + try { + const response = await axios.post('http://localhost:30000/set-failure-condition', { + shouldFail + }) + console.log(response.data) + } catch (error) { + console.error(`Error setting failure condition: ${error}`) } } diff --git a/tests/features/common-tools/utils.js b/tests/features/common-tools/utils.js index 8f8dfb88c1..53b3aeeaf4 100644 --- a/tests/features/common-tools/utils.js +++ b/tests/features/common-tools/utils.js @@ -17,7 +17,7 @@ illegal under applicable law, and the grant of the foregoing license under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ -const RandExp = require('randexp') +import RandExp from 'randexp' // const rules = `• Valid characters: A-Z, a-z, 0-9, -, _, .\n // • Must begin and end with: A-Z, a-z, 0-9\n diff --git a/tests/features/common/actions/action-menu.action.js b/tests/features/common/actions/action-menu.action.js index 92d5320159..a3356dcb0c 100644 --- a/tests/features/common/actions/action-menu.action.js +++ b/tests/features/common/actions/action-menu.action.js @@ -26,14 +26,14 @@ async function getOptionValues(driver, options) { }) } -const action = { - openActionMenu: async function(driver, actionMenu) { +export const openActionMenu = async (driver, actionMenu) => { const element = await driver.findElement(actionMenu.open_button) if (element) { element.click() } - }, - selectOptionInActionMenu: async function(driver, actionMenu, option) { + } + +export const selectOptionInActionMenu = async (driver, actionMenu, option) => { const elements = await driver.findElements(actionMenu.options) for (const element of elements) { element.getText().then(txt => { @@ -42,8 +42,9 @@ const action = { } }) } - }, - checkActionMenuOptions: async function(driver, actionMenu, values) { + } + +export const checkActionMenuOptions = async (driver, actionMenu, values) => { const options = await getOptionValues(driver, actionMenu.options) if (options.length === values.length){ @@ -54,8 +55,9 @@ const action = { expect(options.length).equal(values.length, `Actual options in action menu [${options}] don't match with expected values [${values}]`) } - }, - verifyOptionInActionMenuEnabled: async function(driver, actionMenu, option){ + } + +export const verifyOptionInActionMenuEnabled = async (driver, actionMenu, option) => { const elements = await driver.findElements(actionMenu.options) for (const element of elements) { const attributes = await element.getAttribute('class') @@ -66,8 +68,9 @@ const action = { expect(flag).to.equal(false) } } - }, - verifyOptionInActionMenuDisabled: async function(driver, actionMenu, option){ + } + +export const verifyOptionInActionMenuDisabled = async (driver, actionMenu, option) => { const elements = await driver.findElements(actionMenu.options) for (const element of elements) { const attributes = await element.getAttribute('class') @@ -79,6 +82,3 @@ const action = { } } } -} - -module.exports = action diff --git a/tests/features/common/actions/api.actions.js b/tests/features/common/actions/api.actions.js index db7914c241..1769c01669 100644 --- a/tests/features/common/actions/api.actions.js +++ b/tests/features/common/actions/api.actions.js @@ -53,13 +53,12 @@ const newJobTemplate = { } } -const action = { - deleteAPIMLProject: async function( +export const deleteAPIMLProject = async ( driver, mlProjectName, expectedStatusCode, deleteNonEmpty = false - ) { + ) => { await driver.sleep(1000) await mainHttpClient .delete( @@ -75,7 +74,7 @@ const action = { }) .catch(error => { if (error.response?.status === 412) { - action.deleteAPIMLProject( + deleteAPIMLProject( driver, mlProjectName, expectedStatusCode, @@ -83,12 +82,13 @@ const action = { ) } }) - }, - deleteAPIFeatureSet: async function( + } + +export const deleteAPIFeatureSet = async ( projectName, featureSetName, expectedStatusCode - ) { + ) => { await mainHttpClient .delete( `${REACT_APP_MLRUN_API_URL}/projects/${projectName}/feature-sets/${featureSetName}` @@ -96,12 +96,13 @@ const action = { .then(res => { expect(res.status).equal(expectedStatusCode) }) - }, - deleteAPIFeatureVector: async function( + } + +export const deleteAPIFeatureVector = async ( projectName, featureVectorName, expectedStatusCode - ) { + ) => { await mainHttpClient .delete( `${REACT_APP_MLRUN_API_URL}/projects/${projectName}/feature-vectors/${featureVectorName}` @@ -109,12 +110,13 @@ const action = { .then(res => { expect(res.status).equal(expectedStatusCode) }) - }, - deleteAPIFunction: async function( + } + +export const deleteAPIFunction = async ( projectName, functionName, expectedStatusCode - ) { + ) => { await mainHttpClient .delete( `${REACT_APP_MLRUN_API_URL_V2}/projects/${projectName}/functions/${functionName}` @@ -122,12 +124,13 @@ const action = { .then(res => { expect(res.status).equal(expectedStatusCode) }) - }, - deleteAPISchedule: async function( + } + +export const deleteAPISchedule = async ( projectName, scheduleName, expectedStatusCode - ) { + ) => { await mainHttpClient .delete( `${REACT_APP_MLRUN_API_URL}/projects/${projectName}/schedules/${scheduleName}` @@ -135,12 +138,13 @@ const action = { .then(res => { expect(res.status).equal(expectedStatusCode) }) - }, - deleteAPIArtifact: async function( + } + +export const deleteAPIArtifact = async ( projectName, artifactName, expectedStatusCode - ) { + ) => { await mainHttpClient .delete( `${REACT_APP_MLRUN_API_URL}/artifacts?project=${projectName}&name=${artifactName}` @@ -148,8 +152,9 @@ const action = { .then(res => { expect(res.status).equal(expectedStatusCode) }) - }, - createAPIMLProject: async function(mlProjectName, expectedStatusCode) { + } + +export const createAPIMLProject = async (mlProjectName, expectedStatusCode) => { const project_data = { metadata: { name: mlProjectName @@ -164,13 +169,13 @@ const action = { .then(res => { expect(res.status).equal(expectedStatusCode) }) - }, + } - createAPISchedule: async function( +export const createAPISchedule = async ( mlProjectName, mlScheduleName, expectedStatusCode - ) { + ) => { const data = newJobTemplate data.task.metadata.name = mlScheduleName data.task.metadata.project = mlProjectName @@ -180,14 +185,15 @@ const action = { .then(res => { expect(res.status).equal(expectedStatusCode) }) - }, - createAPIFunction: async function( + } + +export const createAPIFunction = async ( mlProjectName, mlFunctionKind, mlFunctionTag, mlFunctionName, expectedStatusCode - ) { + ) => { const data = { kind: mlFunctionKind, metadata: { @@ -216,12 +222,13 @@ const action = { .then(res => { expect(res.status).equal(expectedStatusCode) }) - }, - createAPIFeatureSet: async function( + } + +export const createAPIFeatureSet = async ( mlProjectName, mlFeatureSetName, expectedStatusCode - ) { + ) => { const data = { kind: 'FeatureSet', metadata: { @@ -244,12 +251,13 @@ const action = { .then(res => { expect(res.status).equal(expectedStatusCode) }) - }, - createAPIFeatureVector: async function( + } + +export const createAPIFeatureVector = async ( mlProjectName, mlFeatureVectorName, expectedStatusCode - ) { + ) => { const data = { kind: 'FeatureVector', metadata: { @@ -270,19 +278,16 @@ const action = { .then(res => { expect(res.status).equal(expectedStatusCode) }) - }, - createAPIArtifact: async function( + } + +export const createAPIArtifact = async ( mlProjectName, mlArtifactName, mlArtifactTag, mlArtifactType, expectedStatusCode - ) { + ) => { const uid = uuidv4() - //TODO: description ML-4583 - // const data = { - // description: '', - // } const data = { kind: mlArtifactType === 'file' ? '' : mlArtifactType, @@ -332,14 +337,10 @@ const action = { .then(res => { expect(res.status).equal(expectedStatusCode) }) - }, - getProjects: () => { - return mainHttpClient - .get(`${REACT_APP_MLRUN_API_URL}/projects`) - .then(res => { - return res.data.projects - }) } -} -module.exports = action +export const getProjects = async () => { + const res = await mainHttpClient.get(`${REACT_APP_MLRUN_API_URL}/projects`) + + return res.data.projects + } diff --git a/tests/features/common/actions/checkbox.action.js b/tests/features/common/actions/checkbox.action.js index aceab8a507..35346dfe55 100644 --- a/tests/features/common/actions/checkbox.action.js +++ b/tests/features/common/actions/checkbox.action.js @@ -19,41 +19,42 @@ such restriction. */ import { expect } from 'chai' -const action = { - isCheckboxChecked: async function(driver, checkbox) { +export const isCheckboxChecked = async (driver, checkbox) => { const checkboxElement = await driver.findElement(checkbox['checkbox']) const classes = await checkboxElement.getAttribute('class') expect(classes.includes('unchecked')).equal(false) - }, - isCheckboxUnchecked: async function(driver, checkbox) { + } + +export const isCheckboxUnchecked = async (driver, checkbox) => { const checkboxElement = await driver.findElement(checkbox['checkbox']) const classes = await checkboxElement.getAttribute('class') expect(classes.includes('unchecked')).equal(true) - }, - checkCheckbox: async function(driver, checkbox) { + } + +export const checkCheckbox = async (driver, checkbox) => { const checkboxElement = await driver.findElement(checkbox['checkbox']) const classes = await checkboxElement.getAttribute('class') if (classes.includes('unchecked')) { await checkboxElement.click() } - }, - uncheckCheckbox: async function(driver, checkbox) { + } + +export const uncheckCheckbox = async (driver, checkbox) => { const checkboxElement = await driver.findElement(checkbox['checkbox']) const classes = await checkboxElement.getAttribute('class') if (!classes.includes('unchecked')) { await checkboxElement.click() } - }, - verifyCheckboxEnabled: async function(driver, component) { + } + +export const verifyCheckboxEnabled = async (driver, component) => { const element = await driver.findElement(component) const flag = await element.getAttribute('class') expect(flag).equal('checkbox') - }, - verifyCheckboxDisabled: async function(driver, component) { + } + +export const verifyCheckboxDisabled = async (driver, component) => { const element = await driver.findElement(component) const flag = await element.getAttribute('class') expect(flag).equal('checkbox checkbox_disabled') } -} - -module.exports = action diff --git a/tests/features/common/actions/common.action.js b/tests/features/common/actions/common.action.js index a9b2dd96d8..15e7ae4a37 100644 --- a/tests/features/common/actions/common.action.js +++ b/tests/features/common/actions/common.action.js @@ -21,16 +21,10 @@ import { timeout } from '../../../config' import { until } from 'selenium-webdriver' import { expect } from 'chai' import { access, constants } from 'fs' -const path = require('path') -const os = require('os') +import path from 'path' +import os from 'os' -async function scrollToWebElement(driver, element) { - await driver.executeScript('arguments[0].scrollIntoView()', element) - await driver.sleep(250) -} - -const action = { - generatePath: async function(file, downloadsFolder){ +export const generatePath = async (file, downloadsFolder) => { const homeDirectory = os.homedir() // Define the path to the Downloads folder @@ -38,41 +32,50 @@ const action = { // Specify the full path to the file return path.join(downloadsFolderPath, file) - }, - determineFileAccess: async function(finalPath, file){ + } + +export const determineFileAccess = async (finalPath, file) => { access(finalPath, constants.F_OK, (err) => { const result = err ? `${file} doesn't exist` : true expect(result).equal(true) }) - }, - navigateToPage: async function(driver, baseURL) { + } + +export const navigateToPage = async (driver, baseURL) => { await driver.get(baseURL) await driver.sleep(1000) - }, - navigateForward: async function(driver) { + } + +export const navigateForward = async (driver) => { await driver.navigate().forward() - }, - navigateBack: async function(driver) { + } + +export const navigateBack = async (driver) => { await driver.navigate().back() - }, - refreshPage: async function(driver) { + } + +export const refreshPage = async (driver) => { await driver.navigate().refresh() - }, - waitPageLoad: async function(driver, loader) { + } + +export const waitPageLoad = async (driver, loader) => { await driver.wait(async function(driver) { const found = await driver.findElements(loader) return found.length === 0 }) - }, - waiteUntilComponent: async function(driver, component) { + } + +export const waiteUntilComponent = async (driver, component) => { await driver.wait(until.elementLocated(component), timeout) - }, - clickOnComponent: async function(driver, component) { + } + +export const clickOnComponent = async (driver, component) => { const element = await driver.findElement(component) await driver.sleep(250) await element.click() - }, - clickNearComponent: async function(driver, component) { + } + +export const clickNearComponent = async (driver, component) => { const element = await driver.findElement(component) const coordinates = await element.getRect() const actions = driver.actions({ async: true }) @@ -80,8 +83,9 @@ const action = { .move({ x: parseInt(coordinates.x) + 1, y: parseInt(coordinates.y) + 1 }) .click() .perform() - }, - hoverComponent: async function(driver, component, scroll = true) { + } + +export const hoverComponent = async (driver, component, scroll = true) => { const baseComponent = component.root ? component.root : component const element = await driver.findElement(baseComponent) if (scroll) { @@ -93,66 +97,85 @@ const action = { .move({ x: parseInt(coordinates.x), y: parseInt(coordinates.y) }) .perform() await driver.sleep(250) - }, - verifyClassDisabled: async function (driver, component) { + } + +export const verifyClassDisabled = async (driver, component) => { const inputField = await driver.findElement(component) const attributes = await inputField.getAttribute('class') const flag = attributes.includes('form-field__wrapper-disabled') expect(flag).equal(true) - }, - verifyElementDisabled: async function(driver, component) { + } + +export const verifyClassEnabled = async (driver, component) => { + const inputField = await driver.findElement(component) + const attributes = await inputField.getAttribute('class') + const flag = attributes.includes('form-field__wrapper-disabled') + expect(flag).equal(false) +} + +export const verifyElementDisabled = async (driver, component) => { const element = await driver.findElement(component) const flag = await element.getAttribute('disabled') expect(flag).equal('true') - }, - verifyElementEnabled: async function(driver, component) { + } + +export const verifyElementEnabled = async (driver, component) => { const element = await driver.findElement(component) const flag = await element.getAttribute('disabled') expect(flag).equal(null) - }, - verifyElementActive: async function(driver, component) { + } + +export const verifyElementActive = async (driver, component) => { const element = await driver.findElement(component) const flag = await element.getAttribute('class') expect(flag.includes('active')).equal(true) - }, - verifyElementNotActive: async function(driver, component) { + } + +export const verifyElementNotActive = async (driver, component) => { const element = await driver.findElement(component) const flag = await element.getAttribute('class') expect(flag.includes('false')).equal(true) - }, - componentIsPresent: async function(driver, component) { + } + +export const componentIsPresent = async (driver, component) => { const _component = component.root ?? component const elements = await driver.findElements(_component) expect(elements.length).above(0) - }, - componentIsNotPresent: async function(driver, component) { + } + +export const componentIsNotPresent = async (driver, component) => { const _component = component.root ?? component const elements = await driver.findElements(_component) expect(elements.length).equal(0) - }, - componentIsVisible: async function(driver, component) { + } + +export const componentIsVisible = async (driver, component) => { const _component = component.root ?? component const element = await driver.findElement(_component) const displayed = await element.isDisplayed() expect(displayed).equal(true) - }, - componentIsNotVisible: async function(driver, component) { + } + +export const componentIsNotVisible = async (driver, component) => { const _component = component.root ?? component const element = await driver.findElement(_component) await driver.sleep(250) const displayed = await element.isDisplayed() expect(displayed).equal(false) - }, - typeIntoInputField: async function(driver, component, value) { + } + +export const typeIntoInputField = async (driver, component, value) => { const element = await driver.findElement(component) return element.sendKeys(value) - }, - verifyTypedText: async function(driver, component, value) { + } + +export const verifyTypedText = async (driver, component, value) => { const element = await driver.findElement(component) const txt = await element.getAttribute('value') expect(txt).equal(value) - }, - verifyText: async function(driver, component, value) { + } + +export const verifyText = async (driver, component, value) => { const element = await driver.findElement(component) const txt = await element.getText('value') const arr = txt.split() @@ -168,94 +191,106 @@ const action = { `should be expected "${value}" but actual value "${txt}"` ) } - }, - verifyTextRegExp: async function(driver, component, regexp) { + } + +export const verifyTextRegExp = async (driver, component, regexp) => { const element = await driver.findElement(component) const txt = await element.getText('value') expect(true).equal(regexp.test(txt)) - }, - isComponentContainsAttributeValue: async function( + } + +export const isComponentContainsAttributeValue = async ( driver, component, attribute, value - ) { + ) => { const element = await driver.findElement(component) return (await element.getAttribute(attribute)) === value - }, - isComponentContainsClass: async function( + } + +export const isComponentContainsClass = async ( driver, component, className - ) { + ) => { const element = await driver.findElement(component) const classes = await element.getAttribute('class') expect(classes.includes(className)).equal(true) - }, - verifyComponentContainsAttributeValue: async function( + } + +export const verifyComponentContainsAttributeValue = async ( driver, component, attribute, value - ) { + ) => { const element = await driver.findElement(component) const attributes = await element.getAttribute(attribute) expect(attributes.includes(value)).equal( true, `Attribute "${value}" does not present in "${attribute}" values list "${attributes}"` ) - }, - verifyComponentNotContainsAttributeValue: async function( + } + +export const verifyComponentNotContainsAttributeValue = async ( driver, component, attribute, value - ) { + ) => { const element = await driver.findElement(component) const attributes = await element.getAttribute(attribute) expect(attributes.includes(value)).equal( false, `Attribute "${value}" does present in "${attribute}" values list "${attributes}"` ) - }, - collapseAccordionSection: async function(driver, collapseComponent) { + } + +export const collapseAccordionSection = async (driver, collapseComponent) => { const element = await driver.findElement(collapseComponent) const attributes = await element.getAttribute('class') const flag = attributes.includes('open') if (flag) { await element.click() } - }, - expandAccordionSection: async function(driver, collapseComponent) { + } + +export const expandAccordionSection = async (driver, collapseComponent) => { const element = await driver.findElement(collapseComponent) const attributes = await element.getAttribute('class') const flag = attributes.includes('open') if (!flag) { await element.click() } - }, - isAccordionSectionExpanded: async function(driver, collapseComponent) { + } + +export const isAccordionSectionExpanded = async (driver, collapseComponent) => { const element = await driver.findElement(collapseComponent) const attributes = await element.getAttribute('class') const flag = attributes.includes('open') expect(flag).equal(true) - }, - isAccordionSectionCollapsed: async function(driver, collapseComponent) { + } + +export const isAccordionSectionCollapsed = async (driver, collapseComponent) => { const element = await driver.findElement(collapseComponent) const attributes = await element.getAttribute('class') const flag = attributes.includes('open') expect(flag).equal(false) - }, - getElementText: async function(driver, component) { + } + +export const getElementText = async (driver, component) => { const element = await driver.findElement(component) return await element.getText('value') - }, - scrollToElement: async function(driver, component) { + } + +export const scrollToElement = async (driver, component) => { const element = await driver.findElement(component) await driver.executeScript('arguments[0].scrollIntoView()', element) await driver.sleep(250) - }, - checkComponentHintTextWithHover:async function (driver, component, hintComponent, text) { + } + +export const checkComponentHintTextWithHover = async (driver, component, hintComponent, text) => { const hintButton = await driver.findElement(component) const coordinates = await hintButton.getRect() const actions = driver.actions({ async: true }) @@ -267,13 +302,14 @@ const action = { const hintText = await hint.getText() expect(hintText).equal(text) - }, - putToTestContextElementValue: async function(driver, testContext, element, pageValue) { - const pageElement = await driver.findElement(element) + } +export const putToTestContextElementValue = async (driver, testContext, element, pageValue) => { + const pageElement = await driver.findElement(element) testContext[pageValue] = await pageElement.getText() - }, - scrollToWebElement -} - -module.exports = action + } + +export const scrollToWebElement = async (driver, element) => { + await driver.executeScript('arguments[0].scrollIntoView()', element) + await driver.sleep(250) + } diff --git a/tests/features/common/actions/date-picker.action.js b/tests/features/common/actions/date-picker.action.js index d589cbc741..5b0e75d5ed 100644 --- a/tests/features/common/actions/date-picker.action.js +++ b/tests/features/common/actions/date-picker.action.js @@ -87,8 +87,7 @@ async function setPickerTime(driver, dateTimePicker, datetimePoint) { await timeInput.sendKeys(timeString) } -const action = { - verifyTimeFilterBand: async function(driver, dropdown, diff) { +export const verifyTimeFilterBand = async (driver, dropdown, diff) => { const selectedBand = await driver.findElement(dropdown.open_button) const datetimePointsText = await selectedBand.getAttribute('value') const datetimePoints = datetimePointsText.split('-') @@ -102,13 +101,14 @@ const action = { result = datetimeDiff - diff === 0 } expect(result).to.equal(true) - }, - pickUpCustomDatetimeRange: async function( + } + +export const pickUpCustomDatetimeRange = async ( driver, datetimePicker, fromDatetime, toDatetime - ) { + ) => { await selectMonthYear(driver, datetimePicker.fromDatePicker, fromDatetime) await selectCalendarDay(driver, datetimePicker.fromDatePicker, fromDatetime) await setPickerTime(driver, datetimePicker.fromDatePicker, fromDatetime) @@ -116,11 +116,10 @@ const action = { await selectMonthYear(driver, datetimePicker.toDatePicker, toDatetime) await selectCalendarDay(driver, datetimePicker.toDatePicker, toDatetime) await setPickerTime(driver, datetimePicker.toDatePicker, toDatetime) - }, - applyDatetimePickerRange: async function(driver, datetimePicker) { + } + +export const applyDatetimePickerRange = async (driver, datetimePicker) => { const applyButton = await driver.findElement(datetimePicker.applyButton) await applyButton.click() } -} - -module.exports = action + \ No newline at end of file diff --git a/tests/features/common/actions/dropdown.action.js b/tests/features/common/actions/dropdown.action.js index 3b3c36a2ee..dab8af11eb 100644 --- a/tests/features/common/actions/dropdown.action.js +++ b/tests/features/common/actions/dropdown.action.js @@ -21,15 +21,13 @@ import { expect } from 'chai' import { differenceWith, isEqual } from 'lodash' import { clickNearComponent, scrollToWebElement } from './common.action' -async function getOptionValues(driver, options) { - return await driver.findElements(options).then(function(elements) { +export const getOptionValues = async (driver, options) => { + return await driver.findElements(options).then(function(elements) { return Promise.all(elements.map(element => element.getText())) - }) -} + }) + } -const action = { - getOptionValues: getOptionValues, - openDropdown: async function(driver, dropdown, scroll = true) { +export const openDropdown = async (driver, dropdown, scroll = true) => { const element = await driver.findElement(dropdown.open_button) if (scroll) { await scrollToWebElement(driver, element) @@ -38,13 +36,15 @@ const action = { await element.click() } await driver.sleep(1500) - }, - collapseDropdown: async function(driver, dropdown) { + } + +export const collapseDropdown = async (driver, dropdown) => { // const element = await driver.findElement(dropdown.root) await clickNearComponent(dropdown.root) await driver.sleep(100) - }, - selectOptionInDropdown: async function(driver, dropdown, option) { + } + +export const selectOptionInDropdown = async (driver, dropdown, option) => { const selectedElement = await driver.findElement(dropdown.open_button) const selectedText = await selectedElement.getText() if (selectedText !== option) { @@ -62,8 +62,9 @@ const action = { selectedElement.click() await driver.sleep(500) } - }, - selectOptionInDropdownWithoutCheck: async function(driver, dropdown, option) { + } + +export const selectOptionInDropdownWithoutCheck = async (driver, dropdown, option) => { const elements = await driver.findElements(dropdown.options) for (const element of elements) { const txt = await element.getText() @@ -73,23 +74,27 @@ const action = { break } } - }, - checkDropdownSelectedOption: async function(driver, dropdown, option) { + } + +export const checkDropdownSelectedOption = async (driver, dropdown, option) => { const element = await driver.findElement(dropdown.open_button) const txt = await element.getText() expect(txt).equal(option) - }, - checkDropdownSelectedOptionWithAttribute: async function(driver, dropdown, option) { + } + +export const checkDropdownSelectedOptionWithAttribute = async (driver, dropdown, option) => { const element = await driver.findElement(dropdown.open_button) const attributeTxt = await element.getAttribute('value') expect(attributeTxt).equal(option) - }, - checkDropdownOptions: async function(driver, dropdown, values) { + } + +export const checkDropdownOptions = async (driver, dropdown, values) => { const options = await getOptionValues(driver, dropdown.options) const diff = differenceWith(options, values, isEqual) expect(diff.length).equal(0, `Options difference: "${diff}"`) - }, - checkDropdownContainsOptions: async function(driver, dropdown, values) { + } + +export const checkDropdownContainsOptions = async (driver, dropdown, values) => { const options = await getOptionValues(driver, dropdown.options) let notPresent = [] for (let option of values) { @@ -97,17 +102,33 @@ const action = { notPresent.push(option) } } + + let extraPresent = [] + for (let option of options) { + if (values.every(item => item !== option)) { + extraPresent.push(option) + } + } + expect(notPresent.length).equal( 0, '\nOptions not present: ' + notPresent + '\noptions: ' + options + - '\nconst: ' + + '\nexpected: ' + values + '\n' ) - } -} -module.exports = action + expect(extraPresent.length).equal( + 0, + '\nExtra unexpected options: ' + + extraPresent + + '\noptions: ' + + options + + '\nexpected: ' + + values + + '\n' + ) + } diff --git a/tests/features/common/actions/graph.action.js b/tests/features/common/actions/graph.action.js index 9312e01b7f..f544320c4f 100644 --- a/tests/features/common/actions/graph.action.js +++ b/tests/features/common/actions/graph.action.js @@ -39,8 +39,7 @@ function diffMapper(array0, array1, deviation) { return tmpDiff } -const action = { - checkNodesConnectionsNPandas: async function(driver, graphComponent) { +export const checkNodesConnectionsNPandas = async (driver, graphComponent) => { const nodesGeometry = await getNamedRowsGeometry( driver, graphComponent.nodesTable @@ -133,6 +132,3 @@ const action = { expect(numjs.sum(endMarks.slice([i]))).equal(true, 'Arrow not ended') } } -} - -module.exports = action diff --git a/tests/features/common/actions/input-group.action.js b/tests/features/common/actions/input-group.action.js index 6ac71c701b..47d6266b30 100644 --- a/tests/features/common/actions/input-group.action.js +++ b/tests/features/common/actions/input-group.action.js @@ -21,37 +21,44 @@ import { expect } from 'chai' import { Key } from 'selenium-webdriver' import { parseString } from '../../common-tools/common-tools' -async function verifyInputInvalid(driver, inputGroup) { - const inputField = await driver.findElement(inputGroup.inputField) +async function verifyFormInputInvalid(driver, inputGroup) { + const inputField = await driver.findElement(inputGroup.root) + await driver.sleep(500) const flag = await inputField.getAttribute('class') - await driver.sleep(500) - expect(flag.includes('invalid')).equal(true) + expect(flag.includes('form-field__wrapper-invalid')).equal(true) } -async function verifyFormInputInvalid(driver, inputGroup) { +async function verifyFormInputValid(driver, inputGroup) { const inputField = await driver.findElement(inputGroup.root) - await driver.sleep(500) const flag = await inputField.getAttribute('class') - expect(flag.includes('form-field__wrapper-invalid')).equal(true) + expect(flag.includes('form-field__wrapper-invalid')).equal(false) } -async function verifyInputValid(driver, inputGroup) { +async function getInputPlaceholder(driver, inputGroup) { + const inputField = await driver.findElement(inputGroup.inputField) + + return inputField.getAttribute('placeholder') +} + + +export const verifyInputInvalid = async (driver, inputGroup) => { const inputField = await driver.findElement(inputGroup.inputField) const flag = await inputField.getAttribute('class') - expect(flag.includes('invalid')).equal(false) + await driver.sleep(500) + expect(flag.includes('invalid')).equal(true) } -async function verifyFormInputValid(driver, inputGroup) { - const inputField = await driver.findElement(inputGroup.root) +export const verifyInputValid = async (driver, inputGroup) => { + const inputField = await driver.findElement(inputGroup.inputField) const flag = await inputField.getAttribute('class') - expect(flag.includes('form-field__wrapper-invalid')).equal(false) + expect(flag.includes('invalid')).equal(false) } -async function clearManually(inputField) { +export const clearManually = async (inputField) => { const existValue = await inputField.getAttribute('value') for (let i = 0; i <= existValue.length; i++) { @@ -59,47 +66,33 @@ async function clearManually(inputField) { } } -async function getInputValue(driver, inputGroup) { +export const getInputValue = async (driver, inputGroup) => { const inputField = await driver.findElement(inputGroup.inputField) return inputField.getAttribute('value') } -async function getInputPlaceholder(driver, inputGroup) { - const inputField = await driver.findElement(inputGroup.inputField) - - return inputField.getAttribute('placeholder') -} - -async function getInputValueWithoutInputgroup(driver, input) { +export const getInputValueWithoutInputgroup = async (driver, input) => { const inputField = await driver.findElement(input) return inputField.getAttribute('value') } -async function typeValue(driver, inputGroup, value) { +export const typeValue = async (driver, inputGroup, value) => { const inputField = await driver.findElement(inputGroup.inputField) await clearManually(inputField) return inputField.sendKeys(value) } -async function typeValueWithoutInputgroup(driver, input, value) { +export const typeValueWithoutInputgroup = async (driver, input, value) => { const inputField = await driver.findElement(input) await clearManually(inputField) return inputField.sendKeys(value) } -const action = { - clearManually, - getInputValue, - getInputValueWithoutInputgroup, - typeValue, - typeValueWithoutInputgroup, - verifyInputValid, - verifyInputInvalid, - checkHintText: async function (driver, inputGroup, hintComponent, text) { +export const checkHintText = async (driver, inputGroup, hintComponent, text) => { const hintButton = await driver.findElement(inputGroup.hintButton) await hintButton.click() await driver.sleep(250) @@ -107,8 +100,9 @@ const action = { const hintText = await hint.getText() expect(hintText).equal(text) - }, - checkHintTextWithHover:async function (driver, inputGroup, hintComponent, text) { + } + +export const checkHintTextWithHover = async (driver, inputGroup, hintComponent, text) => { const hintButton = await driver.findElement(inputGroup.hintButton) const coordinates = await hintButton.getRect() const actions = driver.actions({ async: true }) @@ -120,15 +114,16 @@ const action = { const hintText = await hint.getText() expect(hintText).equal(text) - }, - checkInputAccordingHintText: async function ( + } + +export const checkInputAccordingHintText = async ( driver, attach, inputGroup, hintComponent, isForm = false, isLabel = false - ) { + ) => { if (!isLabel){ const hintButton = await driver.findElement(inputGroup.hintButton) @@ -168,8 +163,9 @@ const action = { await clearManually(input) } - }, - checkWarningHintText: async function (driver, inputGroup, hintComponent, text) { + } + +export const checkWarningHintText = async (driver, inputGroup, hintComponent, text) => { const hintButton = await driver.findElement(inputGroup.warningHint) await driver.sleep(250) await hintButton.click() @@ -179,8 +175,9 @@ const action = { const hintText = await hint.getText() expect(hintText).equal(text) - }, - checkWarningHintTextWithHover: async function (driver, inputGroup, hintComponent, text) { + } + +export const checkWarningHintTextWithHover = async (driver, inputGroup, hintComponent, text) => { const hintButton = await driver.findElement(inputGroup.warningHint) await driver.sleep(250) const coordinates = await hintButton.getRect() @@ -194,56 +191,65 @@ const action = { const hintText = await hint.getText() expect(hintText).equal(text) - }, - checkWarningText: async function (driver, hintComponent, text) { + } + +export const checkWarningText = async (driver, hintComponent, text) => { const hint = await driver.findElement(hintComponent) await driver.sleep(250) const hintText = await hint.getText() expect(hintText).equal(text) - }, - verifyTypedValue: async function (driver, inputGroup, value) { + } + +export const verifyTypedValue = async (driver, inputGroup, value) => { const txt = await getInputValue(driver, inputGroup) expect(txt).equal(value) - }, - verifyPlaceholder: async function (driver, inputGroup, value) { + } + +export const verifyPlaceholder = async (driver, inputGroup, value) => { const txt = await getInputPlaceholder(driver, inputGroup) expect(txt).equal(value) - }, - verifyTypedValueWithoutInputgroup: async function (driver, input, value) { + } + +export const verifyTypedValueWithoutInputgroup = async (driver, input, value) => { const txt = await getInputValueWithoutInputgroup(driver, input) expect(txt).equal(value) - }, - verifyInputDisabled: async function (driver, inputGroup) { + } + +export const verifyInputDisabled = async (driver, inputGroup) => { const inputField = await driver.findElement(inputGroup.inputField) const flag = await inputField.getAttribute('disabled') expect(flag).equal('true') - }, - verifyInputClassDisabled: async function (driver, inputGroup) { + } + +export const verifyInputClassDisabled = async (driver, inputGroup) => { const inputField = await driver.findElement(inputGroup.root) const attributes = await inputField.getAttribute('class') const flag = attributes.includes('form-field__wrapper-disabled') expect(flag).equal(true) - }, - verifyInputClassEnabled: async function (driver, inputGroup) { + } + +export const verifyInputClassEnabled = async (driver, inputGroup) => { const inputField = await driver.findElement(inputGroup.inputField) const attributes = await inputField.getAttribute('class') const flag = attributes.includes('form-field__wrapper-disabled') expect(flag).equal(false) - }, - verifyInputEnabled: async function (driver, inputGroup) { + } + +export const verifyInputEnabled = async (driver, inputGroup) => { const inputField = await driver.findElement(inputGroup.inputField) const flag = await inputField.getAttribute('disabled') expect(flag).equal(null) - }, - verifyTextAreaCounter: async function (driver, textAreaGroup) { + } + +export const verifyTextAreaCounter = async (driver, textAreaGroup) => { const textAreaField = await driver.findElement(textAreaGroup.inputField) const textAreaText = await textAreaField.getText() const textAreaCounter = await driver.findElement(textAreaGroup.counter) @@ -252,6 +258,3 @@ const action = { expect(+counterValue.split(' ')[0]).equal(maxLength - textAreaText.length) } -} - -module.exports = action diff --git a/tests/features/common/actions/input-with-autocomplete.action.js b/tests/features/common/actions/input-with-autocomplete.action.js index c3be98a834..5a20fe1318 100644 --- a/tests/features/common/actions/input-with-autocomplete.action.js +++ b/tests/features/common/actions/input-with-autocomplete.action.js @@ -20,38 +20,37 @@ such restriction. import { expect } from 'chai' import { Key } from 'selenium-webdriver' -async function clearManually(inputField) { +export const clearManually = async (inputField) => { const existValue = await inputField.getAttribute('value') for (let i = 0; i <= existValue.length; i++) { await inputField.sendKeys(Key.BACK_SPACE, Key.DELETE) } } -async function getOptionValues(driver, options) { +export const getOptionValues = async (driver, options) => { return await driver.findElements(options).then(function(elements) { return Promise.all(elements.map(element => element.getText())) }) } -const action = { - clearManually, - getOptionValues: getOptionValues, - typeSearchableValue: async function(driver, inputGroup, value) { +export const typeSearchableValue = async (driver, inputGroup, value) => { const inputField = await driver.findElement(inputGroup.inputField) await clearManually(inputField) return await inputField.sendKeys(value) - }, - verifyTypedValue: async function(driver, inputGroup, value) { + } + +export const verifyTypedValue = async (driver, inputGroup, value) => { const inputField = await driver.findElement(inputGroup.inputField) const txt = await inputField.getAttribute('value') expect(txt).equal(value) - }, - isContainsSubstringInSuggestedOptions: async function( + } + +export const isContainsSubstringInSuggestedOptions = async ( driver, inputGroup, value, caseSensitive = false - ) { + ) => { let arr = await getOptionValues(driver, inputGroup.options) let tmpValue = value @@ -66,6 +65,3 @@ const action = { `Searcheble string "${tmpValue}" do not find in all values of: [${arr}]` ) } -} - -module.exports = action diff --git a/tests/features/common/actions/number-input-group.action.js b/tests/features/common/actions/number-input-group.action.js index 507ea3fa13..dbd61be189 100644 --- a/tests/features/common/actions/number-input-group.action.js +++ b/tests/features/common/actions/number-input-group.action.js @@ -17,21 +17,18 @@ illegal under applicable law, and the grant of the foregoing license under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ -const action = { - incrementValue: async function(driver, inputGroup, value) { +export const incrementValue = async (driver, inputGroup, value) => { const inc_btn = await driver.findElement(inputGroup.inc_btn) for (let i = 0; i < value; i++) { await inc_btn.click() await driver.sleep(100) } - }, - decrementValue: async function(driver, inputGroup, value) { + } + +export const decrementValue = async (driver, inputGroup, value) => { const dec_btn = await driver.findElement(inputGroup.dec_btn) for (let i = 0; i < value; i++) { await dec_btn.click() await driver.sleep(100) } } -} - -module.exports = action diff --git a/tests/features/common/actions/radio-button.action.js b/tests/features/common/actions/radio-button.action.js index c7e7a67db1..fd78b55738 100644 --- a/tests/features/common/actions/radio-button.action.js +++ b/tests/features/common/actions/radio-button.action.js @@ -19,18 +19,19 @@ such restriction. */ import { expect } from 'chai' -const action = { - isRadioButtonSelected: async function(driver, radiobutton) { +export const isRadioButtonSelected = async (driver, radiobutton) => { const element = await driver.findElement(radiobutton['radiobutton']) const selected = await element.isSelected() expect(selected).equal(true) - }, - isRadioButtonUnselected: async function(driver, radiobutton) { + } + +export const isRadioButtonUnselected = async (driver, radiobutton) => { const element = await driver.findElement(radiobutton['radiobutton']) const selected = await element.isSelected() expect(selected).equal(false) - }, - selectRadiobutton: async function(driver, radiobutton) { + } + +export const selectRadiobutton = async (driver, radiobutton) => { const element = await driver.findElement(radiobutton['radiobutton']) const elementName = await driver.findElement(radiobutton['name']) const selected = await element.isSelected() @@ -38,6 +39,3 @@ const action = { await elementName.click() } } -} - -module.exports = action diff --git a/tests/features/common/actions/tab-selector.action.js b/tests/features/common/actions/tab-selector.action.js index fbeeaad2b1..01b55dda85 100644 --- a/tests/features/common/actions/tab-selector.action.js +++ b/tests/features/common/actions/tab-selector.action.js @@ -19,8 +19,7 @@ such restriction. */ import { expect } from 'chai' -const action = { - isTabActive: async function(driver, component, indx) { +export const isTabActive = async (driver, component, indx) => { const element1 = await driver.findElement(component.rowRoot(indx)) const element2 = await driver.findElement( component.tableFields['key'](indx) @@ -34,8 +33,9 @@ const action = { attributes2.includes('tabs-slider__tab_active')|| attributes2.includes('content-menu__tab_active') expect(flag).equal(true) - }, - isRowActive: async function(driver, component, indx) { + } + +export const isRowActive = async (driver, component, indx) => { const element = await driver.findElement(component.rowRoot(indx)) const attributes = await element.getAttribute('class') const flag = attributes.includes('row_active') @@ -46,6 +46,3 @@ const action = { expect(flag).equal(false) } } -} - -module.exports = action diff --git a/tests/features/common/actions/table.action.js b/tests/features/common/actions/table.action.js index 508ddb11cd..0a8a1a1cf9 100644 --- a/tests/features/common/actions/table.action.js +++ b/tests/features/common/actions/table.action.js @@ -25,28 +25,33 @@ import { selectOptionInDropdownWithoutCheck } from './dropdown.action' import { getElementText, hoverComponent } from './common.action' - import { DataFrame } from 'pandas-js' -async function getColumnValues(driver, table, columnName) { +async function getColumnValuesAttribute(driver, table, columnName) { return await driver .findElements(table.tableColumns[columnName]) .then(function(elements) { - return Promise.all(elements.map(element => element.getText())) + return Promise.all(elements.map(element => element.getAttribute('value'))) }) } -async function getColumnValuesAttribute(driver, table, columnName) { +export const getColumnValues = async (driver, table, columnName) => { return await driver .findElements(table.tableColumns[columnName]) .then(function(elements) { - return Promise.all(elements.map(element => element.getAttribute('value'))) + return Promise.all(elements.map(element => element.getText())) }) } -async function getTableRows(driver, table) { +export const getHeaderColumnValue = async (driver, table, columnName) => { + const element = await driver.findElement(table.headerSorters[columnName]) + + return await element.getText() +} + +export const getTableRows = async (driver, table) => { const arr = await driver .findElements(table.tableColumns[table.tableCulumnNames[0]]) .then(function(elements) { @@ -56,23 +61,31 @@ async function getTableRows(driver, table) { return await arr.length } -const action = { - getColumnValues: getColumnValues, - getTableRows: getTableRows, - isContainsValueInColumn: async function(driver, table, columnName, value) { +export const isContainsValueInColumn = async (driver, table, columnName, value) => { const arr = await getColumnValues(driver, table, columnName) expect(arr.includes(value)).equal(true, `Column values [${arr}] is not equal with "${value}" `) - }, - isNotContainsValueInColumn: async function(driver, table, columnName, value) { + } + +export const isContainsValueInHeaderColumn = async (driver, table, columnName, value) => { + const actualValue = await getHeaderColumnValue(driver, table, columnName) + + expect(actualValue.includes(value)).equal( + true, + `Header column "${columnName}" value "${actualValue}" does not include "${value}"` + ) +} + +export const isNotContainsValueInColumn = async (driver, table, columnName, value) => { const arr = await getColumnValues(driver, table, columnName) expect(arr.includes(value)).equal(false) - }, - isContainsSubstringInColumnCells: async function( + } + +export const isContainsSubstringInColumnCells = async ( driver, table, columnName, value - ) { + ) => { const arr = await getColumnValues(driver, table, columnName) const subString = value.replace('=', '\n:\n') expect(arr.length > 0).equal(true) @@ -80,39 +93,42 @@ const action = { true, `Value "${subString}" does not includes in all values: [${arr}]` ) - }, - isContainsSubstringInColumnAttributeCells: async function( + } + +export const isContainsSubstringInColumnAttributeCells = async ( driver, table, columnName, value - ) { + ) => { const arr = await getColumnValuesAttribute(driver, table, columnName) expect(arr.length > 0).equal(true) expect(arr.every(item => item.includes(value))).equal( true, `Value "${value}" does not includes in all values: [${arr}]` ) - }, - isContainsSubstringInColumnAttributeListCells: async function( + } + +export const isContainsSubstringInColumnAttributeListCells = async ( driver, table, columnName, value - ) { + ) => { const arr = await getColumnValuesAttribute(driver, table, columnName) expect(arr.length > 0).to.equal(true) expect(arr.every(item => value.includes(item))).to.equal( true, `Value "${value}" does not includes in all values: [${arr}]` ) - }, - isContainsSubstringInColumnDropdownCells: async function( + } + +export const isContainsSubstringInColumnDropdownCells = async ( driver, table, column, value - ) { + ) => { const subString = value.replace('=', '\n:\n') const rows = await getTableRows(driver, table) let flag = true @@ -135,14 +151,15 @@ const action = { } expect(flag).equal(true) - }, - isContainsSubstringInColumnDropdownCellsOverlay: async function( + } + +export const isContainsSubstringInColumnDropdownCellsOverlay = async ( driver, table, overlay, column, value - ) { + ) => { const subString = value.replace('=', '\n:\n') const rows = await getTableRows(driver, table) let flag = true @@ -165,13 +182,14 @@ const action = { } expect(flag).equal(true) - }, - isContainsSubstringInColumnTooltipCells: async function( + } + +export const isContainsSubstringInColumnTooltipCells = async ( driver, table, column, value - ) { + ) => { const rows = await getTableRows(driver, table) expect(rows).not.equal(0) @@ -189,14 +207,15 @@ const action = { } expect(arr.some(item => item.includes(value))).equal(true) - }, - isDatetimeCelsValueInRange: async function( + } + +export const isDatetimeCelsValueInRange = async ( driver, table, columnName, fromDateTime, toDateTime - ) { + ) => { const arr = await getColumnValues(driver, table, columnName) const minDate = new Date(fromDateTime) @@ -216,13 +235,14 @@ const action = { true, `values "${arr}" is not in range: (${fromDateTime}..${toDateTime})` ) - }, - findRowIndexesByColumnValue: async function( + } + +export const findRowIndexesByColumnValue = async ( driver, table, columnName, value - ) { + ) => { const arr = await getColumnValues(driver, table, columnName) const indexes = [] @@ -232,13 +252,14 @@ const action = { } } return indexes - }, - findRowIndexesByColumnValueExpand: async function( + } + +export const findRowIndexesByColumnValueExpand = async ( driver, table, columnName, value - ) { + ) => { const columnValues = await getColumnValues(driver, table, columnName) return columnValues.reduce((acc, currentValue, index) => { @@ -248,13 +269,14 @@ const action = { return acc }, []) - }, - findRowIndexesByColumnValueAttribute: async function( + } + +export const findRowIndexesByColumnValueAttribute = async ( driver, table, columnName, value - ) { + ) => { const arr = await getColumnValuesAttribute(driver, table, columnName) const indexes = [] @@ -264,13 +286,14 @@ const action = { } } return indexes - }, - findRowIndexesByColumnTooltipsValue: async function( + } + +export const findRowIndexesByColumnTooltipsValue = async ( driver, table, columnName, value - ) { + ) => { const indexes = [] const rowsNumber = await getTableRows(driver, table) for (let row = rowsNumber; row >= 1; row--) { @@ -298,8 +321,9 @@ const action = { } return indexes.reverse() - }, - openActionMenuByIndex: async function(driver, table, index) { + } + +export const openActionMenuByIndex = async (driver, table, index) => { const elements = await driver.findElements( table.tableFields['action_menu'](index) ) @@ -314,16 +338,18 @@ const action = { return table.tableFields['action_menu'](index) } } - }, - getCellByIndexColumn: async function(driver, table, index, column) { + } + +export const getCellByIndexColumn = async (driver, table, index, column) => { return await table.tableFields[column](index) - }, - isTableColumnSorted: async function( + } + +export const isTableColumnSorted = async ( driver, table, columnName, order = 'asc' - ) { + ) => { const columnArray = await getColumnValues(driver, table, columnName) let sortedArr = [] if (order === 'asc') { @@ -334,8 +360,9 @@ const action = { } expect(sortedArr).equal(columnArray) - }, - checkTableColumnValues: async function(driver, table, columnName, values) { + } + +export const checkTableColumnValues = async (driver, table, columnName, values) => { const arr = await getColumnValues(driver, table, columnName) if (arr.length === 0) { throw new Error('Array is empty, nothing to compare') @@ -352,8 +379,9 @@ const action = { } return true - }, - getAllCellsWithAttribute: async function(driver, table, attribute) { + } + +export const getAllCellsWithAttribute = async (driver, table, attribute) => { const result = [] for (const column of table.tableCulumnNames) { @@ -376,8 +404,9 @@ const action = { } return result - }, - getRowsGeometry: async function(driver, table) { + } + +export const getRowsGeometry = async (driver, table) => { const rowsNumber = await getTableRows(driver, table) const result = [] @@ -389,8 +418,9 @@ const action = { } return result - }, - getFieldsGeometry: async function(driver, table, column, attribute) { + } + +export const getFieldsGeometry = async (driver, table, column, attribute) => { const rowsNumber = await getTableRows(driver, table) const result = [] @@ -401,8 +431,9 @@ const action = { } return result - }, - getNamedRowsGeometry: async function(driver, table, name = 'name') { + } + +export const getNamedRowsGeometry = async (driver, table, name = 'name') => { const rowsNumber = await getTableRows(driver, table) const result = [] @@ -418,8 +449,9 @@ const action = { } return new DataFrame(result) - }, - getNamedFieldsGeometry: async function(driver, table, column) { + } + +export const getNamedFieldsGeometry = async (driver, table, column) => { const rowsNumber = await getTableRows(driver, table) const result = [] @@ -430,15 +462,16 @@ const action = { } return new DataFrame(result) - }, - putToTestContextCellParameters: async function( + } + +export const putToTestContextCellParameters = async ( driver, testContext, table, index, column, attribute - ) { + ) => { const cellElement = await driver.findElement( table.tableFields[column](index) ) @@ -447,8 +480,9 @@ const action = { if (attribute) { testContext[attribute] = await cellElement.getAttribute(attribute) } - }, - checkCellHintText: async function (driver, table, hintComponent, hintValue, index) { + } + +export const checkCellHintText = async (driver, table, hintComponent, hintValue, index) => { await hoverComponent(driver, table.tableFields['hintButton'](index)) await driver.sleep(250) const hint = await driver.findElement(hintComponent) @@ -456,6 +490,3 @@ const action = { expect(text).equal(hintValue) } -} - -module.exports = action diff --git a/tests/features/common/components/action-menu.component.js b/tests/features/common/components/action-menu.component.js index 216c03f3e2..5ee76e95f5 100644 --- a/tests/features/common/components/action-menu.component.js +++ b/tests/features/common/components/action-menu.component.js @@ -19,7 +19,7 @@ such restriction. */ import { By } from 'selenium-webdriver' -module.exports = function(menuStructure) { +export default function(menuStructure) { return { root: By.css(menuStructure.root), open_button: By.css( diff --git a/tests/features/common/components/breadcrumbs.component.js b/tests/features/common/components/breadcrumbs.component.js index 744c5354f0..7eb022d2a2 100644 --- a/tests/features/common/components/breadcrumbs.component.js +++ b/tests/features/common/components/breadcrumbs.component.js @@ -17,10 +17,10 @@ illegal under applicable law, and the grant of the foregoing license under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ -const { By } = require('selenium-webdriver') -const inputWithAutocomplete = require('./input-with-autocomplete.component') +import { By } from 'selenium-webdriver' +import inputWithAutocomplete from './input-with-autocomplete.component' -module.exports = { +export default { root: By.css('nav.breadcrumbs'), projectsPageLabel: By.css('.breadcrumbs__item:nth-of-type(1)'), projectLabel: By.css('.breadcrumbs__item:nth-of-type(3)'), diff --git a/tests/features/common/components/checkbox.component.js b/tests/features/common/components/checkbox.component.js index 1bea023501..f0b45fa00f 100644 --- a/tests/features/common/components/checkbox.component.js +++ b/tests/features/common/components/checkbox.component.js @@ -19,7 +19,7 @@ such restriction. */ import { By } from 'selenium-webdriver' -module.exports = function(checkboxStructure) { +export default function(checkboxStructure) { const element = {} element.root = By.css(checkboxStructure.root) element.checkbox = By.css( diff --git a/tests/features/common/components/combo-box.component.js b/tests/features/common/components/combo-box.component.js index 746398fc69..b05f7e2df7 100644 --- a/tests/features/common/components/combo-box.component.js +++ b/tests/features/common/components/combo-box.component.js @@ -21,7 +21,7 @@ import { By } from 'selenium-webdriver' import dropdownComponent from './dropdown.component' import { generateDropdownGroup } from '../../common-tools/common-tools' -module.exports = function(comboBoxRoot, newClassLocator = false) { +export default function(comboBoxRoot, newClassLocator = false) { const element = {} element.root = By.css(comboBoxRoot) diff --git a/tests/features/common/components/date-picker.component.js b/tests/features/common/components/date-picker.component.js index 90ca9a3cb0..cda827ef7c 100644 --- a/tests/features/common/components/date-picker.component.js +++ b/tests/features/common/components/date-picker.component.js @@ -22,7 +22,7 @@ import { locatorBuilder } from '../../common-tools/common-tools' import { cloneDeep } from 'lodash' -module.exports = function(datepickerStructure) { +export default function(datepickerStructure) { const datepickerRoot = locatorBuilder`${0} ${1}` const options = locatorBuilder`${0} ${1}` diff --git a/tests/features/common/components/dropdown.component.js b/tests/features/common/components/dropdown.component.js index 1864a47adb..a74a1741b8 100644 --- a/tests/features/common/components/dropdown.component.js +++ b/tests/features/common/components/dropdown.component.js @@ -20,7 +20,7 @@ such restriction. import { By } from 'selenium-webdriver' import { locatorBuilder } from '../../common-tools/common-tools' -module.exports = function(dropdownStructure) { +export default function(dropdownStructure) { const root = dropdownStructure.optionsInRoot ? dropdownStructure.root : '#overlay_container' diff --git a/tests/features/common/components/graph.component.js b/tests/features/common/components/graph.component.js index 1feff94192..909961591f 100644 --- a/tests/features/common/components/graph.component.js +++ b/tests/features/common/components/graph.component.js @@ -20,7 +20,7 @@ such restriction. import { By } from 'selenium-webdriver' import { locatorBuilder } from '../../common-tools/common-tools' -module.exports = function(graphStructure) { +export default function(graphStructure) { const options = locatorBuilder`${0} ${1}` const nodesTable = { ...graphStructure.elements.workflowGraphNodesTable.structure diff --git a/tests/features/common/components/input-group.component.js b/tests/features/common/components/input-group.component.js index c724f16a16..9b80bf555e 100644 --- a/tests/features/common/components/input-group.component.js +++ b/tests/features/common/components/input-group.component.js @@ -19,7 +19,7 @@ such restriction. */ import { By } from 'selenium-webdriver' -module.exports = function(inputStructure) { +export default function(inputStructure) { const element = {} element.root = By.css(inputStructure.root) element.inputField = By.css( diff --git a/tests/features/common/components/input-with-autocomplete.component.js b/tests/features/common/components/input-with-autocomplete.component.js index 776c6e7700..ec9493438a 100644 --- a/tests/features/common/components/input-with-autocomplete.component.js +++ b/tests/features/common/components/input-with-autocomplete.component.js @@ -20,7 +20,7 @@ such restriction. import { By } from 'selenium-webdriver' import { locatorBuilder } from '../../common-tools/common-tools' -module.exports = function(inputStructure) { +export default function(inputStructure) { const options = locatorBuilder`${0} ${1} ${2}` const option = locatorBuilder`${0} ${1}:nth-of-type(${2}) ${3}` diff --git a/tests/features/common/components/label.component.js b/tests/features/common/components/label.component.js index 69073805a7..816900ab25 100644 --- a/tests/features/common/components/label.component.js +++ b/tests/features/common/components/label.component.js @@ -19,7 +19,7 @@ such restriction. */ import { By } from 'selenium-webdriver' -module.exports = function(labelStructure) { +export default function(labelStructure) { const element = {} element.root = By.css(labelStructure.root) element.label = By.css( diff --git a/tests/features/common/components/number-input-group.component.js b/tests/features/common/components/number-input-group.component.js index 7a5b4d311d..87323aabc0 100644 --- a/tests/features/common/components/number-input-group.component.js +++ b/tests/features/common/components/number-input-group.component.js @@ -19,7 +19,7 @@ such restriction. */ import { By } from 'selenium-webdriver' -module.exports = function(inputStructure) { +export default function(inputStructure) { const element = {} element.root = By.css(inputStructure.root) element.inputField = By.css( diff --git a/tests/features/common/components/radio-button.component.js b/tests/features/common/components/radio-button.component.js index a3c41a3e3f..235c02bd50 100644 --- a/tests/features/common/components/radio-button.component.js +++ b/tests/features/common/components/radio-button.component.js @@ -19,7 +19,7 @@ such restriction. */ import { By } from 'selenium-webdriver' -module.exports = function(radiobuttonStructure) { +export default function(radiobuttonStructure) { const element = {} element.root = By.css(radiobuttonStructure.root) element.radiobutton = By.css( diff --git a/tests/features/common/components/single-date-picker.component.js b/tests/features/common/components/single-date-picker.component.js index 3174abab4e..4571711dba 100644 --- a/tests/features/common/components/single-date-picker.component.js +++ b/tests/features/common/components/single-date-picker.component.js @@ -22,7 +22,7 @@ import { locatorBuilder } from '../../common-tools/common-tools' import { cloneDeep } from 'lodash' -module.exports = function(datepickerStructure) { +export default function(datepickerStructure) { const datepickerRoot = locatorBuilder`${0} ${1}` const options = locatorBuilder`${0} ${1}` diff --git a/tests/features/common/components/table.component.js b/tests/features/common/components/table.component.js index 50f99e85be..ec99f2905a 100644 --- a/tests/features/common/components/table.component.js +++ b/tests/features/common/components/table.component.js @@ -51,7 +51,7 @@ import { locatorBuilder } from '../../common-tools/common-tools' * } * @returns - js object which allow access to table describle page components */ -module.exports = function(tableStructure) { +export default function(tableStructure) { const table = tableStructure const sortersBuilder = locatorBuilder`${0} ${1} ${2}` const columnBuilder = locatorBuilder`${0} ${1} ${2} ${3}` diff --git a/tests/features/common/components/text-area.component.js b/tests/features/common/components/text-area.component.js index 297e604589..c3f78737ec 100644 --- a/tests/features/common/components/text-area.component.js +++ b/tests/features/common/components/text-area.component.js @@ -19,7 +19,7 @@ such restriction. */ import { By } from 'selenium-webdriver' -module.exports = function (textAreaStructure) { +export default (textAreaStructure) => { const element = {} element.root = By.css(textAreaStructure.root) element.inputField = By.css(`${textAreaStructure.root} ${textAreaStructure.elements.input}`) diff --git a/tests/features/common/page-objects.js b/tests/features/common/page-objects.js index 2692cc7549..71d93687cc 100644 --- a/tests/features/common/page-objects.js +++ b/tests/features/common/page-objects.js @@ -34,8 +34,9 @@ import models from './page-objects/models.po' import documents from './page-objects/documents.po' import alerts from './page-objects/alerts.po' import monitoringApp from './page-objects/monitoring-app.po' +import llmPrompts from './page-objects/llm-prompts.po' -module.exports = { +export default { Add_To_Feature_Vector_Popup: interactivePopup['addToFeatureVectorPopup'], Add_To_Feature_Vector_Tab: featureStore['addToFeatureVector'], Add_Tag_Popup: interactivePopup['addTagPopup'], @@ -45,7 +46,8 @@ module.exports = { Alerts_Endpoint_Info_Pane: infoPane['alertsEndpointInfoPane'], Alerts_Application_Info_Pane: infoPane['alertsApplicationInfoPane'], Analysis_Info_Pane: infoPane['analysisInfoPane'], - Artifact_Preview_Popup: interactivePopup['artifactPreviewPopup'], + Application_Metrics: monitoringApp['applicationMetrics'], + Application_Monitoring: monitoringApp['applicationMonitoring'], Artifacts_Info_Pane: infoPane['artifactsInfoPane'], Change_Project_Owner_Popup: interactivePopup['changeProjectOwnerPopup'], Common_Popup: interactivePopup['commonPopup'], @@ -81,6 +83,8 @@ module.exports = { Jobs_Monitoring_Workflows_Tab: jobsMonitoring['crossWorkflowsMonitorTab'], Jobs_Monitoring_Scheduled_Tab: jobsMonitoring['crossScheduledMonitorTab'], Jobs_Monitor_Tab_Info_Pane: infoPane['jobsMonitorTabInfoPane'], + LLM_Prompts: llmPrompts['llmPrompts'], + LLM_Prompts_Info_Pane: infoPane['llmPromptsInfoPane'], Metrics_Selector_Popup: interactivePopup['metricsSelectorPopup'], ML_Function_Info_Pane: infoPane['mlFunctionInfoPane'], ML_Functions: Functions['mlFunctions'], diff --git a/tests/features/common/page-objects/alerts-monitoring.po.js b/tests/features/common/page-objects/alerts-monitoring.po.js index 8be7b6a0f2..0c8a08444c 100644 --- a/tests/features/common/page-objects/alerts-monitoring.po.js +++ b/tests/features/common/page-objects/alerts-monitoring.po.js @@ -169,7 +169,7 @@ const dateTimePickerCalendars = { const commonErrorMessage = By.css('[data-testid="no-data"] h3') -module.exports = { +export default { alertsMonitoring: { Table_FilterBy_Button: By.css('[data-testid="filter-menu-btn-tooltip-wrapper"]'), Refresh_Button: By.css('[data-testid="refresh"] [data-testid="refresh-tooltip-wrapper"]'), diff --git a/tests/features/common/page-objects/alerts.po.js b/tests/features/common/page-objects/alerts.po.js index f8b4f24fd7..4b277d6360 100644 --- a/tests/features/common/page-objects/alerts.po.js +++ b/tests/features/common/page-objects/alerts.po.js @@ -169,7 +169,7 @@ const dateTimePickerCalendars = { const commonErrorMessage = By.css('[data-testid="no-data"] h3') -module.exports = { +export default { alerts: { Table_FilterBy_Button: By.css('[data-testid="filter-menu-btn-tooltip-wrapper"]'), Refresh_Button: By.css('[data-testid="refresh"] [data-testid="refresh-tooltip-wrapper"]'), diff --git a/tests/features/common/page-objects/commonPagesHeader.po.js b/tests/features/common/page-objects/commonPagesHeader.po.js index 55b8480907..44a63cd5f1 100644 --- a/tests/features/common/page-objects/commonPagesHeader.po.js +++ b/tests/features/common/page-objects/commonPagesHeader.po.js @@ -35,7 +35,7 @@ const generalInfoQuickLinks = { } } -module.exports = { +export default { loader: By.css('.loader-wrapper .loader'), See_On_Github: By.css('header.header a[alt="MLRUN on Gihub"]'), See_On_Slack: By.css('header.header a[alt="MLRUN on Slack"]'), @@ -90,11 +90,6 @@ module.exports = { Alerts_Button: By.css('[data-testid="nav-link-alerts"] .nav-link__label'), Alerts_Icon: By.css('[data-testid="nav-link-alerts"] svg'), General_Info_Quick_Panel: By.css('.ml-app .navbar .navbar__body'), - Project_Quick_Actions_Instance: By.css('.project-details__details .link'), - Quick_actions_Active: By.css('#quick-actions'), - Project_Monitoring_First_Instance: By.css('.project-details__details .link'), - Project_Monitoring_Second_Instance: By.css('.project-overview-card:nth-of-type(3) .link:nth-of-type(4)'), - Project_Monitoring_Active: By.css('#monitor'), Step_1_Button: By.css('.modal .modal__content .modal__body .wizard-steps .btn:nth-of-type(1)'), Step_1_Button_text: By.css('.modal .modal__content .modal__body .wizard-steps .btn:nth-of-type(1) .data-ellipsis span'), Step_2_Button: By.css('.modal .modal__content .modal__body .wizard-steps .btn:nth-of-type(2)'), diff --git a/tests/features/common/page-objects/documents.po.js b/tests/features/common/page-objects/documents.po.js index d618689ec4..675ce44021 100644 --- a/tests/features/common/page-objects/documents.po.js +++ b/tests/features/common/page-objects/documents.po.js @@ -83,7 +83,7 @@ const documentsTable = { } } -module.exports = { +export default { documents: { Table_Name_Filter_Input: inputGroup( generateInputGroup( diff --git a/tests/features/common/page-objects/feature-store.po.js b/tests/features/common/page-objects/feature-store.po.js index 74cc647f39..bccd4f6d1a 100644 --- a/tests/features/common/page-objects/feature-store.po.js +++ b/tests/features/common/page-objects/feature-store.po.js @@ -47,7 +47,7 @@ const tabSelector = { const actionMenuStructure = { root: '.actions-menu__container', menuElements: { - open_button: 'button', + open_button: '[data-testid="actions-menu"]', options: '.actions-menu__body .actions-menu__option' } } @@ -378,7 +378,7 @@ const commonTableTreeFilterDropdown = dropdownComponent( ) ) -module.exports = { +export default { featureSetsTab: { Table_FilterBy_Button: tableFilterByButton, Table_Refresh_Button: tableRefreshButton, diff --git a/tests/features/common/page-objects/files.po.js b/tests/features/common/page-objects/files.po.js index 149f1a2ec8..41fdbe3693 100644 --- a/tests/features/common/page-objects/files.po.js +++ b/tests/features/common/page-objects/files.po.js @@ -94,7 +94,7 @@ const filesTable = { } } -module.exports = { +export default { filesTab: { Table_Name_Filter_Input: inputGroup( generateInputGroup( diff --git a/tests/features/common/page-objects/info-pane.po.js b/tests/features/common/page-objects/info-pane.po.js index c6e55c9d42..c6a69807ce 100644 --- a/tests/features/common/page-objects/info-pane.po.js +++ b/tests/features/common/page-objects/info-pane.po.js @@ -63,6 +63,62 @@ const infoPaneTabSelector = { } } +const promptTemplateTabSelector = { + root: '.table__item .item-header-wrapper .content-menu__tabs', + header: {}, + body: { + row: { + root: '.content-menu__tab', + fields: { + key: '', + hintButton: '.tip-container' + } + } + } +} + +const promptArgumentsTabSelector = { + root: '.table__item .item-info .content-menu__tabs', + header: {}, + body: { + row: { + root: '.content-menu__tab', + fields: { + key: '', + hintButton: '.tip-container' + } + } + } +} + +const argumentsTabTable = { + root: '.arguments-tab', + header: {}, + body: { + row: { + root: '.arguments-tab__row', + fields: { + key: '.arguments-tab__row-key', + value: '.arguments-tab__row-value' + } + } + } +} + +const generationConfigurationTabTable = { + root: '.generation-configuration-tab', + header: {}, + body: { + row: { + root: '.generation-configuration-tab__row', + fields: { + key: '.generation-configuration-tab__row-key', + value: '.generation-configuration-tab__row-value' + } + } + } +} + const infoPaneOverviewHeaders = { root: '.table__item .item-info__details-wrapper:nth-of-type(1)', header: {}, @@ -78,6 +134,20 @@ const infoPaneOverviewHeaders = { } } +const infoPaneOverviewPromptTable = { + root: '.table__item .prompt-tab__table', + header: {}, + body: { + row: { + root: '.prompt-tab__row', + fields: { + role: '.prompt-tab__role', + content: '.prompt-tab__content' + } + } + } +} + const infoPaneOverviewProducerHeaders = { root: '.table__item .item-info__details-wrapper:nth-of-type(2)', header: {}, @@ -87,6 +157,7 @@ const infoPaneOverviewProducerHeaders = { fields: { key: '.details-item__header', link: '.details-item__data .link', + producer_link: '.details-item__link', value: '.details-item__data' } } @@ -121,6 +192,7 @@ const infoPaneOverviewSourcesHeaders = { } } } + const artifactOverviewTable = { root: '.table__item .item-info__details:nth-of-type(1)', header: {}, @@ -143,6 +215,20 @@ const artifactOverviewTable = { } } +const llmPromptOverviewTable = { + root: '.table__item .item-info__details-wrapper:nth-of-type(1)', + header: {}, + body: { + row: { + root: '', + fields: { + key: '.details-item:nth-of-type(1) .details-item__data', + tag: '.details-item:nth-of-type(5) .details-item__data' + } + } + } +} + const datasetOverviewTable = { root: '.table__item .item-info__details:nth-of-type(1)', header: {}, @@ -228,7 +314,7 @@ const infoPaneDriftHeaders = { } const filesInfoSourcesTable = { - root: '.info-sources .info-sources-table', + root: '.info-sources', header: { root: '.info-sources-table__header', sorters: { @@ -238,10 +324,12 @@ const filesInfoSourcesTable = { }, body: { row: { - root: '.info-sources-table__content', + root: '.info-sources__table', fields: { - name: '.info-sources-table__content-key .data-ellipsis', - path: '.info-sources-table__content-value' + name_key: '.info-sources__table-row:nth-of-type(1) .info-sources__table-key', + name_value: '.info-sources__table-row:nth-of-type(1) .info-sources__table-value', + path_key: '.info-sources__table-row:nth-of-type(2) .info-sources__table-key', + path_value: '.info-sources__table-row:nth-of-type(2) .info-sources__table-value' } } } @@ -504,7 +592,7 @@ const modelsRealTimeinfoPaneOverviewHeaders = { root: '.table-container', header: {}, body: { - root: '.graph-pane', + root: '.graph-pane .graph-pane__section:nth-of-type(2)', offset: 1, row: { root: '.graph-pane__row', @@ -515,6 +603,22 @@ const modelsRealTimeinfoPaneOverviewHeaders = { } } +const modelsRealTimeinfoPaneRunningModelsHeaders = { + root: '.table-container', + header: {}, + body: { + root: '.graph-pane .graph-pane__section:nth-of-type(3)', + offset: 0, + row: { + root: '.graph-pane__row', + fields: { + key: '.graph-pane__row-label', + key_value:'.graph-pane__row-value .link' + } + } + } +} + const featureSetTransformationGraph = { root: '.react-flow', elements: { @@ -589,7 +693,7 @@ const commonVersionTagInput = inputGroup( const commonVersionTagInputFullView = By.css('.table__item_big .details-item__input-wrapper input') const commonLabelsApplyButton = By.css('.item-info__details-wrapper .details-item .details-item__data-chips .details-item__apply-btn-wrapper') -module.exports = { +export default { featureSetsInfoPane: { Header: header, Updated: updated, @@ -982,13 +1086,69 @@ module.exports = { Alerts_FilterBy_Button: By.css('[data-testid="detailsPanel"] [data-testid="filter-menu-btn-tooltip-wrapper"]'), Alerts_Refresh_Button: By.css('[data-testid="detailsPanel"] [data-testid="refresh-tooltip-wrapper"]'), Alerts_Table: commonTable(alertsTable), - Metrics_Stats_Card: By.css('.alert-row__expanded-row .alerts-table__metrics .stats-card') + Metrics_Stats_Card: By.css('.alert-row__expanded-row .alerts-table .stats-card') }, modelsRealTimePipelineInfoPane: { Arrow_Back: commonArrowBack, - Header: By.css('.graph-pane__title span'), + Header: By.css('.graph-pane__title .graph-pane__title-label'), + Title_Icon: By.css('.graph-pane__title .graph-pane__title-icon'), Cross_Close_Button: By.css('.graph-pane__title .round-icon-cp .round-icon-cp__circle'), - Overview_Headers: commonTable(modelsRealTimeinfoPaneOverviewHeaders) + General_Section_Title: By.css('.graph-pane .graph-pane__section:nth-of-type(2) .graph-pane__section-title'), + Overview_Headers: commonTable(modelsRealTimeinfoPaneOverviewHeaders), + Running_Models_Section_Title: By.css('.graph-pane .graph-pane__section:nth-of-type(3) .graph-pane__section-title'), + Graph_Pane_Expand_Icon: By.css('.graph-pane .graph-pane__section:nth-of-type(3) .graph-pane__expand-icon'), + Running_Models_Headers: commonTable(modelsRealTimeinfoPaneRunningModelsHeaders) + }, + llmPromptsInfoPane: { + Header: header, + Updated: updated, + Not_In_Filtered_List_Message: By.css('[data-testid="detailsPanel"] .item-header__status .info-banner'), + Action_Menu: commonActionMenu, + Apply_Changes_Button: applyChangesButton, + Apply_Button: applyButton, + Cross_Close_Button: crossCloseButton, + Full_View_Button: fullViewButton, + Tabel_View_Button: tabelViewButton, + Info_Pane_Tab_Selector: commonInfoPaneTabSelector, + Prompt_Template_Tab_Selector: commonTable(promptTemplateTabSelector), + Prompt_Arguments_Tab_Selector: commonTable(promptArgumentsTabSelector), + Arguments_Tab_Table: commonTable(argumentsTabTable), + Generation_Configuration_Tab_Table: commonTable(generationConfigurationTabTable), + Find_In_Prompt_Filter_Input: inputGroup( + generateInputGroup( + '.search-navigator [data-testid="search-container"]', + true, + false + ) + ), + Overview_General_Headers: commonTable(infoPaneOverviewHeaders), + Overview_Producer_Headers: commonTable(infoPaneOverviewProducerHeaders), + Overview_Hash_Header: labelComponent( + generateLabelGroup( + '.item-info__details:nth-of-type(1) .details-item:nth-of-type(4) .details-item__header', + false, + true + ) + ), + Overview_UID_Header: labelComponent( + generateLabelGroup( + '.item-info__details-wrapper:nth-of-type(2) .item-info__details .details-item:nth-of-type(5) .details-item__header', + false, + true + ) + ), + Overview_Table: commonTable(llmPromptOverviewTable), + Prompt_Template_Table: commonTable(infoPaneOverviewPromptTable), + Prompt_Template_Argument: By.css('.prompt-tab__table .prompt-tab__row:nth-of-type(3) .prompt-tab__content span'), + Generation_Configuration_Counter: By.css('.generation-configuration-tab .generation-configuration-tab__counter'), + Edit_btn_table_view: commonEditBtnTableView, + Version_tag_Input: inputGroup( + generateInputGroup( + '.details-item:nth-of-type(5) .details-item__input-wrapper', + false, + false + ) + ) }, paginationInfoPane: { BE_Pagination_Navigate_Prev: By.css( @@ -1030,8 +1190,11 @@ module.exports = { false ) ), - Metrics_App_Name: By.css('.item-info__details-metrics .alerts-table__metrics .metrics__app-name'), - Metrics_Stats_Card: By.css('.item-info__details-metrics .alerts-table__metrics .metrics__card'), + Metrics_App_Name: By.css('[data-testid="detailsPanel"] .metrics .alerts-table__metrics-header'), + Metrics_Stats_Card: By.css('[data-testid="detailsPanel"] .metrics .metrics__card'), + Metrics_Stats_Card_Metric_Name: By.css('[data-testid="detailsPanel"] .metrics .metrics__card .stats-card__title .stats-card__title-wrapper'), + Metrics_Stats_Card_Metric_BodyBar: By.css('[data-testid="detailsPanel"] .metrics .metrics__card .metrics__card-body .metrics__card-body-bar'), + Metrics_Stats_Card_Metric_BodyLine: By.css('[data-testid="detailsPanel"] .metrics .metrics__card .metrics__card-body .metrics__card-body-line'), Metrics_Stats_Card_Empty: By.css('[data-testid="detailsPanel"] .metrics__empty-select') }, alertsApplicationInfoPane: { diff --git a/tests/features/common/page-objects/interactive-popup.po.js b/tests/features/common/page-objects/interactive-popup.po.js index 213a3bc0cd..97e290a2e6 100644 --- a/tests/features/common/page-objects/interactive-popup.po.js +++ b/tests/features/common/page-objects/interactive-popup.po.js @@ -37,8 +37,7 @@ import { generateCheckboxGroup } from '../../common-tools/common-tools' import inputWithAutocomplete from '../components/input-with-autocomplete.component' - -const { By } = require('selenium-webdriver') +import { By } from 'selenium-webdriver' const memberOverviewLabelsTable = { root: '.settings__members', @@ -116,15 +115,20 @@ const deployModelTable = { } } -const artifactsPreviewRow = { - root: '.pop-up-dialog .preview-body', +const artifactsPreviewTable = { + root: '.pop-up-dialog .item-artifacts__modal-preview', header: { - root: '', - sorters: {} + root: '.preview-item:nth-of-type(1)', + sorters: { + name: '.item-data__header:nth-of-type(1)', + path: '.item-data__path', + size: '.item-data__header:nth-of-type(3)', + updated: '.item-data__header:nth-of-type(4)' + } }, body: { row: { - root: '.preview-item', + root: '.preview-item:nth-of-type(2)', fields: { name: '.item-data__name', path: '.item-data__path', @@ -136,20 +140,6 @@ const artifactsPreviewRow = { } } -const artifactsPreviewHeader = { - root: '.pop-up-dialog', - header: {}, - body: { - root: '.preview-body', - row: { - root: '.preview-item:nth-of-type(1)', - fields: { - key: '.item-data' - } - } - } -} - const createFeatureVectorLabelsTable = { root: '[data-testid="labels-chips"] .chips-cell', header: {}, @@ -303,7 +293,7 @@ const actionMenuStructure = { } const volumePathsTable = { - root: '.modal__content .form-row:nth-of-type(7)', + root: '[data-testid="resources.volumesTable"]', header: { root: '.form-table__header-row', sorters: { @@ -316,15 +306,16 @@ const volumePathsTable = { offset: 1, add_row_btn: '.form-table__action-row button', row: { - root: 'div[class=table__row]', + root: 'div.form-table__row.form-table__volume-row', fields: { - type: '.table__cell:nth-of-type(1) .data-ellipsis', - volume_name: '.table__cell:nth-of-type(2) .data-ellipsis', - path: '.table__cell:nth-of-type(3) .data-ellipsis', + type: '.form-table__cell:nth-of-type(1) .data-ellipsis', + volume_name: '.form-table__cell:nth-of-type(2) .data-ellipsis', + path: '.form-table__cell:nth-of-type(3) .data-ellipsis', action_menu: { componentType: actionMenu, structure: actionMenuStructure - } + }, + remove_btn: '[data-testid="delete-btn"]' } } } @@ -484,10 +475,9 @@ const advancedEnvironmentVariablesTable = { ) }, type_dropdown_verify: '.form-table__cell_1 .data-ellipsis', - value_input: '.form-table__cell_3 .form-field__control input', + value_input: '.form-table__cell_3 .form-field__control:nth-of-type(1) input', value_verify: '.form-table__cell_3 .data-ellipsis', - value_input_key: - '.form-table__cell_3 .form-field-input:nth-of-type(2) .form-field__control input' + value_input_key: '.form-table__cell_3 .form-field-input:nth-of-type(2) input' } } } @@ -717,7 +707,7 @@ const infoPaneOverviewSourcesHeaders = { } } -module.exports = { +export default { createNewProject: { Title: commonTitle, Name_Input: inputGroup( @@ -819,8 +809,12 @@ module.exports = { Content_Application_Log_Info: By.css('.item-info .table__item-logs:nth-of-type(1)'), Title_Function_Log_Info: By.css('.item-info > div > h3:nth-of-type(2)'), Content_Function_Log_Info: By.css('.item-info .table__item-logs:nth-of-type(2)'), - Logs_Text_container: By.css('.table__item .table__item-logs-content'), - Logs_Refresh_Button: By.css('.table__item .logs-refresh') + Logs_Text_container: By.css('#overlay_container .table__item .table__item-logs-content'), + Logs_Refresh_Button: By.css('#overlay_container .table__item .logs-refresh'), + Requested_Features_Table: By.css('.item-info .item-requested-features__table'), + Returned_Features_Table: By.css('.item-info .details-metadata__table'), + Statistics_Table: By.css('.item-info #DETAILS_STATISTICS_TABLE_ID'), + Pop_Out_Button: By.css('[data-testid="details-preview-tooltip-wrapper"]') }, modalWizardForm: { Title: By.css('.modal .modal__header-title'), @@ -1000,7 +994,7 @@ module.exports = { ), Volumes_Subheader: labelComponent( generateLabelGroup( - '.modal__content .wizard-form__content-container .form-row:nth-child(6)', + '.modal__content .wizard-form__content-container .job-wizard__resources .form-row:nth-child(6)', false, true ) @@ -1202,6 +1196,17 @@ module.exports = { false, true ) + ), + Env_Variables_Table_Secret_Name_Input: inputGroup( + generateInputGroup( + '[data-testid="advanced.environmentVariablesTable"] .form-table__cell:nth-of-type(3) .secret-name', + true, + true, + '.form-field__warning svg' + ) + ), + Delete_New_Row_Button: By.css( + '[data-testid="advanced.environmentVariablesTable"] .form-table__actions-cell .round-icon-cp:nth-of-type(2)' ) }, Hyperparameter_Strategy_Accordion: { @@ -1465,6 +1470,7 @@ module.exports = { previewPopup: { Title: By.css('.pop-up-dialog .pop-up-dialog__header'), Cross_Cancel_Button: commonCrossCancelButton, + Preview_Table: commonTable(artifactsPreviewTable), Preview_Modal_Container: By.css('.pop-up-dialog .item-artifacts__modal-preview'), Download_Button: By.css('.pop-up-dialog .preview-item:nth-of-type(2) .preview-body__download') }, @@ -1489,7 +1495,7 @@ module.exports = { } }), Discard_Button: By.css('.apply-discard-buttons .pop-up-dialog__btn_cancel'), - Apply_Button: By.css('.apply-discard-buttons button.btn-secondary') + Apply_Button: By.css('.apply-discard-buttons .btn-primary') }, projectMembersPopup: { Cross_Cancel_Button: commonCrossCancelButton, @@ -1552,7 +1558,7 @@ module.exports = { } }), Discard_Button: By.css('.apply-discard-buttons .pop-up-dialog__btn_cancel'), - Apply_Button: By.css('.apply-discard-buttons button.btn-secondary'), + Apply_Button: By.css('.apply-discard-buttons .btn-primary'), Footer_Annotation_Label: By.css('.footer-annotation') }, createNewSecretPopup: { @@ -1634,14 +1640,6 @@ module.exports = { ), Schedule_Button: By.css('.feature-set-panel__schedule .btn__schedule') }, - artifactPreviewPopup: { - Cross_Cancel_Button: commonCrossCancelButton, - Preview_Row: commonTable(artifactsPreviewRow), - Preview_Header: commonTable(artifactsPreviewHeader), - Download_Button: By.css( - '.pop-up-dialog .preview-body .preview-item:nth-of-type(2) .preview-body__download' - ) - }, removeMemberPopup: { Title: By.css('.delete-member__pop-up .pop-up-dialog__header-text'), Remove_Member_Button: By.css('.delete-member__pop-up .btn-danger') @@ -1664,6 +1662,13 @@ module.exports = { '.options-list [data-testid="select-option"]' ) ), + Mode_Filter_Dropdown: dropdownComponent( + generateDropdownGroup( + '#overlay_container [data-testid="me-mode-form-field-select"] [data-testid="select-header"]', + '.form-field__control', + '.options-list [data-testid="select-option"]' + ) + ), Entity_Type_Filter_Dropdown: dropdownComponent( generateDropdownGroup( '#overlay_container [data-testid="pop-up-dialog"] [data-testid="entity-type-form-field-select"]', @@ -1726,6 +1731,14 @@ module.exports = { true ) ), + Model_Name_Filter_Input: inputGroup( + generateInputGroup('[data-testid="model-name-form-field-input"]', true, false, 'svg') + ), + Model_Version_Tag_Filter_Input: inputGroup( + generateInputGroup('[data-testid="model-tag-form-field-input"]', true, false, 'svg') + ), + Model_Version_Tag_Filter_Field: By.css('[data-testid="model-tag-form-field-input"] > div:nth-child(2)'), + Model_Version_Tag_Filter_Tip: By.css('[data-testid="model-tag-form-field-input"] > div:nth-child(2) .form-field__icons svg'), Status_Filter_Element: By.css('[data-testid="state-form-field-select"]'), Status_Filter_Dropdown: dropdownComponent( generateDropdownGroup( @@ -1734,11 +1747,19 @@ module.exports = { '[data-testid="select-body"] label' ) ), + Type_Filter_Element: By.css('[data-testid="type-form-field-select"]'), Type_Filter_Dropdown: dropdownComponent( generateDropdownGroup( '[data-testid="type-form-field-select"]', '[data-testid="select-header"]', - '[data-testid="select-option"] [data-testid="tooltip-wrapper"]' + '.options-list .select__item:not(.hidden) .tooltip-wrapper' + ) + ), + Type_Filter_Dropdown_Schedule: dropdownComponent( + generateDropdownGroup( + '[data-testid="type-form-field-select"]', + '[data-testid="select-header"]', + '.select__item.multiple:not(.hidden) label' ) ), Show_Iterations_Checkbox: checkboxComponent({ @@ -1757,6 +1778,62 @@ module.exports = { icon: '' } }), + Type_All_Checkbox: checkboxComponent({ + root: '[data-testid="select-checkbox"]:nth-of-type(1)', + elements: { + checkbox: 'input', + name: 'label', + icon: '' + } + }), + Type_Job_Checkbox: checkboxComponent({ + root: '[data-testid="select-checkbox"]:nth-of-type(2)', + elements: { + checkbox: 'input', + name: 'label', + icon: '' + } + }), + Type_Workflow_Checkbox: checkboxComponent({ + root: '[data-testid="select-checkbox"]:nth-of-type(3)', + elements: { + checkbox: 'input', + name: 'label', + icon: '' + } + }), + Type_Spark_Checkbox: checkboxComponent({ + root: '[data-testid="select-checkbox"]:nth-of-type(7)', + elements: { + checkbox: 'input', + name: 'label', + icon: '' + } + }), + Type_Horovod_Checkbox: checkboxComponent({ + root: '[data-testid="select-checkbox"]:nth-of-type(8)', + elements: { + checkbox: 'input', + name: 'label', + icon: '' + } + }), + Type_Dask_Checkbox: checkboxComponent({ + root: '[data-testid="select-checkbox"]:nth-of-type(9)', + elements: { + checkbox: 'input', + name: 'label', + icon: '' + } + }), + Type_Databricks_Checkbox: checkboxComponent({ + root: '[data-testid="select-checkbox"]:nth-of-type(10)', + elements: { + checkbox: 'input', + name: 'label', + icon: '' + } + }), Status_All_Checkbox: checkboxComponent({ root: '[data-testid="select-checkbox"]:nth-of-type(1)', elements: { @@ -1797,6 +1874,14 @@ module.exports = { icon: '' } }), + Status_Pending_retry_Checkbox: checkboxComponent({ + root: '[data-testid="select-checkbox"]:nth-of-type(8)', + elements: { + checkbox: 'input', + name: 'label', + icon: '' + } + }), Status_Aborted_Checkbox: checkboxComponent({ root: '[data-testid="select-checkbox"]:nth-of-type(2)', elements: { diff --git a/tests/features/common/page-objects/jobs-and-workflows.po.js b/tests/features/common/page-objects/jobs-and-workflows.po.js index d0e8ce1207..7d5361cd43 100644 --- a/tests/features/common/page-objects/jobs-and-workflows.po.js +++ b/tests/features/common/page-objects/jobs-and-workflows.po.js @@ -196,7 +196,7 @@ const monitorWorkflowGraph = { row: { root: '.selectable', fields: { - name: '.react-flow__node-label .data-ellipsis .data-ellipsis', + name: '.react-flow__node-label .data-ellipsis', top_handler: '.data-ellipsis .react-flow__handle-top', bottom_handler: '.data-ellipsis .react-flow__handle-bottom' } @@ -460,7 +460,9 @@ const commonCustomRangeFilter = dropdownComponent( ) ) -module.exports = { +const commonActionMenu = actionMenu(actionMenuStructure) + +export default { JobsMonitorTab: { Jobs_Tab_Selector: jobsTabSelector, Date_Picker_Filter_Dropdown: commonDatePickerFilter, @@ -504,10 +506,12 @@ module.exports = { Date_Time_Picker: datepicker(dateTimePickerCalendars), Workflows_Monitor_Table: commonTable(workflowsMonitorTable), Toggle_View_Button: By.css('.workflow-container .actions .toggle-view-btn'), + Terminate_Button: By.css('.workflow-container .btn-danger'), Workflow_List_View_Table: commonTable(jobsMonitorTable), Workflow_Graph: graph(monitorWorkflowGraph), Table_Refresh_Button: tableRefreshButton, - Monitor_Workflows_Subtitle: By.css('.table-container .monitor-workflows__subtitle') + Monitor_Workflows_Subtitle: By.css('.table-container .monitor-workflows__subtitle'), + Action_Menu: commonActionMenu, }, ScheduleMonitorTab: { Table_Name_Filter_Input: commonTableNameFilter, diff --git a/tests/features/common/page-objects/jobs-monitoring.po.js b/tests/features/common/page-objects/jobs-monitoring.po.js index 014aed9ab5..123ba5e307 100644 --- a/tests/features/common/page-objects/jobs-monitoring.po.js +++ b/tests/features/common/page-objects/jobs-monitoring.po.js @@ -35,9 +35,9 @@ const tabSelector = { root: '.content .content-menu', header: {}, body: { - root: '.content-menu__list', + root: '.content-menu__tabs', row: { - root: '.content-menu__item', + root: '.content-menu__tab', fields: { key: '' } @@ -277,8 +277,9 @@ const dateTimePickerCalendars = { const commonRefreshButton = By.css('[data-testid="refresh"]') const commonErrorMessage = By.css('[data-testid="no-data"] h3') +const commonActionMenu = actionMenu(actionMenuStructure) -module.exports = { +export default { crossJobsMonitorTab: { Cross_Jobs_Tab_Selector: commonTable(tabSelector), Table_FilterBy_Button: By.css('[data-testid="filter-menu-btn-tooltip-wrapper"]'), @@ -309,7 +310,11 @@ module.exports = { Date_Time_Picker: datepicker(dateTimePickerCalendars), Refresh_Button: commonRefreshButton, Error_Message: commonErrorMessage, - Workflows_Table: commonTable(overallTable) + Workflows_Table: commonTable(overallTable), + Action_Menu: commonActionMenu, + Toggle_View_Button: By.css('.workflow-container .actions .toggle-view-btn'), + Terminate_Button: By.css('.workflow-container .btn-danger'), + Workflow_List_View_Table: commonTable(overallTable) }, crossScheduledMonitorTab: { Cross_Jobs_Tab_Selector: commonTable(tabSelector), diff --git a/tests/features/common/page-objects/llm-prompts.po.js b/tests/features/common/page-objects/llm-prompts.po.js new file mode 100644 index 0000000000..9e86b42f1d --- /dev/null +++ b/tests/features/common/page-objects/llm-prompts.po.js @@ -0,0 +1,108 @@ +/* +Copyright 2019 Iguazio Systems Ltd. + +Licensed under the Apache License, Version 2.0 (the "License") with +an addition restriction as set forth herein. You may not use this +file except in compliance with the License. You may obtain a copy of +the License at http://www.apache.org/licenses/LICENSE-2.0. + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +In addition, you may not use the software for any purposes that are +illegal under applicable law, and the grant of the foregoing license +under the Apache 2.0 license is conditioned upon your compliance with +such restriction. +*/ +import { By } from 'selenium-webdriver' +import commonTable from '../components/table.component' +import dropdownComponent from '../components/dropdown.component' +import { + generateInputGroup, + generateDropdownGroup +} from '../../common-tools/common-tools' +import inputGroup from '../components/input-group.component' +import actionMenu from '../components/action-menu.component' + +const commonSearchByNameFilterInput = inputGroup( + generateInputGroup( + '[data-testid="name-form-field-input"]', + true, + false + ) +) + +const actionMenuStructure = { + root: '.actions-menu__container', + menuElements: { + open_button: '[data-testid="actions-menu"] button', + options: '.actions-menu__body .actions-menu__option' + } +} + +const overallTable = { + root: '.table__content', + header: { + root: '.table-header', + sorters: { + name: '[data-testid="name"] .data-ellipsis', + labels: '[data-testid="labels"] .data-ellipsis', + producer: '[data-testid="producer"] .data-ellipsis', + owner: '[data-testid="owner"] .data-ellipsis', + updated: '[data-testid="updated"] .data-ellipsis', + size: '[data-testid="size"] .data-ellipsis' + } + }, + body: { + root: '.table-body', + row: { + root: '.table-row', + fields: { + name: '[data-testid="name"] a .link', + uid: '.table-body__cell:nth-of-type(1) a .name-wrapper .link', + labels: { + componentType: dropdownComponent, + structure: generateDropdownGroup( + '.table-body__cell:nth-of-type(3)', + '.chip-block span.chips_button', + '.chip-block-hidden_visible .data-ellipsis.tooltip-wrapper', + false, + false + ) + }, + producer: '[data-testid="producer"] .data-ellipsis', + owner: '[data-testid="owner"] .data-ellipsis', + updated: '[data-testid="updated"] .data-ellipsis', + size: '[data-testid="size"] .data-ellipsis', + show_all_versions: '[data-testid="quick-link-show-all-versions"]', + action_menu: { + componentType: actionMenu, + structure: actionMenuStructure + }, + preview: '.table-body__cell:nth-of-type(8) [data-testid="quick-link-artifact-preview"]', + model_name: '[data-testid="modelName"] .model-name .link', + model_tag: '[data-testid="modelName"] .item-tag .link-subtext' + } + } + } +} + +export default { + llmPrompts: { + Search_By_Name_Filter_Input: commonSearchByNameFilterInput, + Table_FilterBy_Button: By.css('[data-testid="filter-menu-btn-tooltip-wrapper"]'), + Refresh_Button: By.css('[data-testid="refresh"] [data-testid="refresh-tooltip-wrapper"]'), + LLMPrompts_Table: commonTable(overallTable), + Overlay: By.css('#overlay_container .chip-block-hidden_visible'), + History_Back_Button: By.css('.history-back-link .history-back-link__icon'), + Version_History_Title: By.css( + '.history-back-link .history-back-link__title [data-testid="version-history"]' + ), + Version_History_Prompt_Name: By.css( + '.history-back-link .history-back-link__title .data-ellipsis.tooltip-wrapper' + ) + } +} diff --git a/tests/features/common/page-objects/ml-functions.po.js b/tests/features/common/page-objects/ml-functions.po.js index 11cdd7a382..edba565146 100644 --- a/tests/features/common/page-objects/ml-functions.po.js +++ b/tests/features/common/page-objects/ml-functions.po.js @@ -86,7 +86,7 @@ const functionsTable = { } } -module.exports = { +export default { mlFunctions: { Table_Name_Filter_Input: inputGroup( generateInputGroup( diff --git a/tests/features/common/page-objects/models.po.js b/tests/features/common/page-objects/models.po.js index c20bd21112..9c35dc35f7 100644 --- a/tests/features/common/page-objects/models.po.js +++ b/tests/features/common/page-objects/models.po.js @@ -193,6 +193,7 @@ const realTimePipelinesTable = { ) }, name: '.table-body__cell:nth-of-type(1) a.data-ellipsis', + name_link: '.table-body__cell:nth-of-type(1) a .link', type: '.table-body__cell:nth-of-type(2) .data-ellipsis', function: '.table-body__cell:nth-of-type(3) .data-ellipsis', action_menu: { @@ -215,11 +216,12 @@ const realTimePipelinesGraph = { body: { root: '.react-flow__nodes', row: { - root: '.react-flow__node-ml-node', + root: '.react-flow__node', fields: { - name: '.react-flow__node-label .data-ellipsis .data-ellipsis', + name: '.react-flow__node-label .data-ellipsis', top_handler: '.data-ellipsis .react-flow__handle-top', - bottom_handler: '.data-ellipsis .react-flow__handle-bottom' + bottom_handler: '.data-ellipsis .react-flow__handle-bottom', + node_title: '.react-flow__node-chips-title' } } } @@ -257,7 +259,7 @@ const tableNameFilterInput = inputGroup( ) ) -module.exports = { +export default { modelsTab: { Delete_Artifact_Popup: By.css('[data-testid="pop-up-dialog"]'), Models_Tab_Selector: commonTable(tabSelector), @@ -292,6 +294,14 @@ module.exports = { Table_Name_Filter_Input: tableNameFilterInput, Table_Refresh_Button: tableRefreshButton, Real_Time_Pipelines_Table: commonTable(realTimePipelinesTable), - Real_Time_Pipelines_Graph: graph(realTimePipelinesGraph) + Real_Time_Pipelines_Graph: graph(realTimePipelinesGraph), + Pipeline_Back_Button: By.css('[data-testid="pipeline-back-btn-tooltip-wrapper"]'), + Pipeline_Link_Title: By.css('.pipeline-container .link-back__title'), + Model_Runner_Step_Icon: By.css('.react-flow__node-ml-model-runner-node .react-flow__node-header .react-flow__node-header-icon'), + Model_Runner_Step_Label: By.css('.react-flow__node-ml-model-runner-node .react-flow__node-header-title .react-flow__node-header-label'), + Model_Runner_Step_Sub_Label: By.css('.react-flow__node-ml-model-runner-node .react-flow__node-header-title .react-flow__node-header-sub-label'), + Model_Runner_Monitoring_Icon: By.css('.react-flow__node-ml-model-runner-node .react-flow__node-header .react-flow__node-header-monitoring-icon'), + Model_Runner_Chips_Title: By.css('.react-flow__node-ml-model-runner-node div.react-flow__node-chips-title'), + Model_Runner_Chip_Container: By.css('.react-flow__node-ml-model-runner-node [data-testid="runningModels-chips"] .chip-block .edit-chip-container'), } } diff --git a/tests/features/common/page-objects/monitoring-app.po.js b/tests/features/common/page-objects/monitoring-app.po.js index bf8e83658d..664711d890 100644 --- a/tests/features/common/page-objects/monitoring-app.po.js +++ b/tests/features/common/page-objects/monitoring-app.po.js @@ -21,9 +21,11 @@ import { By } from 'selenium-webdriver' import commonTable from '../components/table.component' import dropdownComponent from '../components/dropdown.component' import { - generateDropdownGroup + generateDropdownGroup, + generateInputGroup } from '../../common-tools/common-tools' import datepicker from '../components/date-picker.component' +import inputGroup from '../components/input-group.component' const commonDatePickerFilter = dropdownComponent( generateDropdownGroup( @@ -113,11 +115,250 @@ const dateTimePickerCalendars = { } // datepicker end -module.exports = { +const operatingFunctionsTable = { + root: '.monitoring-apps .monitoring-app__section-item .section-table', + header: { + root: '.section-table__table-header', + sorters: { + name: '.table-cell_big .data-ellipsis', + status: '.table-cell_small(1) .data-ellipsis', + started_at: '.table-cell_medium .data-ellipsis', + lag: '.table-cell_small(2) .data-ellipsis', + commited_offset: '.table-cell_small(3) .data-ellipsis' + } + }, + body: { + root: '.section-table__table-body', + row: { + root: '.section-table__table-row', + fields: { + name: '.table-cell_big a .data-ellipsis', + status: '.table-cell_small:nth-of-type(2) .data-ellipsis', + started_at: '.table-cell_medium .data-ellipsis' + } + } + } +} + +const allApplicationsTable = { + root: '.monitoring-apps #main-table', + header: { + root: '.table-header', + sorters: { + name: '[data-testid="name"] span', + lag: '[data-testid="lag"] span', + commited_offset: '[data-testid="commitedOffset"] span', + detections: '[data-testid="detections"] span', + possible_detections: '[data-testid="possibleDetections"] span', + class: '[data-testid="class"] span', + startedAt: '[data-testid="startedAt"] span', + updated: '[data-testid="updated"] span', + nuclioFunction: '[data-testid="nuclioFunction"] span' + } + }, + body: { + root: '#main-table-body', + row: { + root: '.table-row', + fields: { + name: '[data-testid="name"] a .data-ellipsis', + nuclioFunction: '[data-testid="nuclioFunction"] .link .item-name', + nuclioFunctionStatus: '[data-testid="nuclioFunction"] .link .status', + open_metrics: '[data-testid="quick-link-open-metrics"]' + } + } + } +} + +const artifactsTable = { + root: '.monitoring-app__section:nth-of-type(1) .section-table', + header: { + root: '.section-table__table-header', + sorters: { + name: '.section-table__table-cell:nth-of-type(1) .data-ellipsis' + } + }, + body: { + root: '.section-table__table-body', + row: { + root: '.section-table__table-row', + fields: { + name: '.section-table__table-cell:nth-of-type(1) .data-ellipsis', + labels: { + componentType: dropdownComponent, + structure: generateDropdownGroup( + '.table-cell_medium', + '', + '', + false, + false + ) + } + } + } + } +} + +const resultsTable = { + root: '.monitoring-app__section.section_small:nth-of-type(2) .monitoring-app__section-item:nth-of-type(1) .section-table', + header: { + root: '.section-table__table-header', + sorters: { + name: '.section-table__table-cell:nth-of-type(1) .data-ellipsis' + } + }, + body: { + root: '.section-table__table-body', + row: { + root: '.section-table__table-row', + fields: { + name: '.section-table__table-cell:nth-of-type(1) .data-ellipsis' + } + } + } +} + +const metricsTable = { + root: '.monitoring-app__section.section_small:nth-of-type(2) .monitoring-app__section-item:nth-of-type(2) .section-table', + header: { + root: '.section-table__table-header', + sorters: { + name: '.section-table__table-cell:nth-of-type(1) .data-ellipsis' + } + }, + body: { + root: '.section-table__table-body', + row: { + root: '.section-table__table-row', + fields: { + name: '.section-table__table-cell:nth-of-type(1) .data-ellipsis' + } + } + } +} + +const shardsPartitionsStatusTable = { + root: '.monitoring-app__section.section_small:nth-of-type(3) .monitoring-app__section-item:nth-of-type(1) .section-table', + header: { + root: '.section-table__table-header', + sorters: { + name: '.section-table__table-cell:nth-of-type(1) .data-ellipsis' + } + }, + body: { + root: '.section-table__table-body', + row: { + root: '.section-table__table-row', + fields: { + name: '.section-table__table-cell:nth-of-type(1) .data-ellipsis' + } + } + } +} + +const endpointsListTable = { + root: '.list-view .list-view__section:nth-of-type(1) .list-view__section-list__items-wrapper', + header: {}, + body: { + root: '#LIST_ID', + row: { + root: 'li', + fields: { + name: '.data-ellipsis' + } + } + } +} + +const searchByEndpointFilterInput = inputGroup( + generateInputGroup( + '.application-metrics-container .list-view .list-view__section:nth-of-type(1) .list-view__section-list__search__name-filter', + true, + false + ) +) + +export default { monitoringApp: { Refresh_Button: By.css('[data-testid="refresh"] [data-testid="refresh-tooltip-wrapper"]'), Date_Picker_Filter_Dropdown: commonDatePickerFilter, Custom_Range_Filter_Dropdown: commonCustomRangeFilter, Date_Time_Picker: datepicker(dateTimePickerCalendars), + Applications_Stats_Title: By.css('.monitoring-application__statistics-section .stats-card:nth-of-type(1) .stats-card__row:nth-of-type(1) .stats-card__title .data-ellipsis.tooltip-wrapper'), + Applications_Stats_Counter: By.css('.monitoring-application__statistics-section .stats-card:nth-of-type(1) .stats-card__row:nth-of-type(2) .stats__counter'), + Apps_Status_Title: By.css('.monitoring-application__statistics-section .stats-card:nth-of-type(2) .stats-card__row:nth-of-type(1) .stats-card__title .data-ellipsis.tooltip-wrapper'), + Apps_Status_Running_SubTitle: By.css('.monitoring-application__statistics-section .stats-card:nth-of-type(2) .stats-card__row:nth-of-type(2) [data-testid="running_status"] .stats__subtitle'), + Apps_Status_Failed_SubTitle: By.css('.monitoring-application__statistics-section .stats-card:nth-of-type(2) .stats-card__row:nth-of-type(2) [data-testid="failed_status"] .stats__subtitle'), + Apps_Status_Running_Counter: By.css('.monitoring-application__statistics-section .stats-card:nth-of-type(2) .stats-card__row:nth-of-type(2) [data-testid="monitoring-app-running"] .stats__counter'), + Apps_Status_Failed_Counter: By.css('.monitoring-application__statistics-section .stats-card:nth-of-type(2) .stats-card__row:nth-of-type(2) [data-testid="monitoring-app-failed"] .stats__counter'), + Apps_Status_Running_Tip: By.css('.monitoring-application__statistics-section .stats-card:nth-of-type(2) .stats-card__row:nth-of-type(2) [data-testid="running_status"] i'), + Apps_Status_Failed_Tip: By.css('.monitoring-application__statistics-section .stats-card:nth-of-type(2) .stats-card__row:nth-of-type(2) [data-testid="failed_status"] i'), + Endpoints_Stats_Title: By.css('.monitoring-application__statistics-section .stats-card:nth-of-type(3) .stats-card__row:nth-of-type(1) .stats-card__title .data-ellipsis.tooltip-wrapper'), + Endpoints_Batch_SubTitle: By.css('.monitoring-application__statistics-section .stats-card:nth-of-type(3) .stats-card__row:nth-of-type(2) [data-testid="batch_status"] .stats__subtitle'), + Endpoints_RealTime_SubTitle: By.css('.monitoring-application__statistics-section .stats-card:nth-of-type(3) .stats-card__row:nth-of-type(2) [data-testid="realTime_status"] .stats__subtitle'), + Endpoints_Batch_Counter: By.css('.monitoring-application__statistics-section .stats-card:nth-of-type(3) .stats-card__row:nth-of-type(2) [data-testid="monitoring-app-batch"] .stats__counter'), + Endpoints_RealTime_Counter: By.css('.monitoring-application__statistics-section .stats-card:nth-of-type(3) .stats-card__row:nth-of-type(2) [data-testid="monitoring-app-realTime"] .stats__counter'), + RunningFrequency_Stats_Title: By.css('.monitoring-application__statistics-section .stats-card:nth-of-type(4) .stats-card__row:nth-of-type(1) .stats-card__title .data-ellipsis.tooltip-wrapper'), + RunningFrequency_Value_Title: By.css('.monitoring-application__statistics-section .stats-card:nth-of-type(4) .stats-card__row:nth-of-type(2) [data-testid="monitoring-app-interval"] .stats__counter'), + Model_Endpoint_Detections_Title: By.css('.monitoring-apps .monitoring-app__section:nth-of-type(1) .monitoring-app__section-item:nth-of-type(1) .section-item_title span'), + Model_Endpoint_Detections_Tip: By.css('.monitoring-apps .monitoring-app__section:nth-of-type(1) .monitoring-app__section-item:nth-of-type(1) .section-item_title [data-testid="tip"]'), + Model_Endpoint_Detections_Chart: By.css('.monitoring-apps .monitoring-app__section:nth-of-type(1) .monitoring-app__section-item:nth-of-type(1) .section-item_chart-wrapper .chart-container'), + Operating_Functions_Title: By.css('.monitoring-apps .monitoring-app__section:nth-of-type(1) .monitoring-app__section-item:nth-of-type(2) .section-item_title span'), + Operating_Functions_Tip: By.css('.monitoring-apps .monitoring-app__section:nth-of-type(1) .monitoring-app__section-item:nth-of-type(2) .section-item_title [data-testid="tip"]'), + Operating_Functions_Table: commonTable(operatingFunctionsTable), + Operating_Functions_Lag_Tip: By.css('.monitoring-apps .monitoring-app__section-item .section-table .table-cell_small:nth-of-type(4) [data-testid="tip"] svg'), + Operating_Functions_Commited_Offset_Tip: By.css('.monitoring-apps .monitoring-app__section-item .section-table .table-cell_small:nth-of-type(5) [data-testid="tip"] svg'), + All_Applications_Title: By.css('.monitoring-apps .monitoring-app__section:nth-of-type(2) .section-item_title span'), + All_Applications_Table: commonTable(allApplicationsTable), + All_Applications_Lag_Tip: By.css('.monitoring-apps #main-table [data-testid="lag"] [data-testid="tip"] svg'), + All_Applications_Commited_Offset_Tip: By.css('.monitoring-apps #main-table [data-testid="commitedOffset"] [data-testid="tip"] svg'), + }, + applicationMonitoring: { + Back_Button: By.css('.content__action-bar-wrapper .table-top .link-back__icon button'), + Application_Name: By.css('.content__action-bar-wrapper .table-top .link-back__title .data-ellipsis'), + Date_Picker_Filter_Dropdown: commonDatePickerFilter, + Custom_Range_Filter_Dropdown: commonCustomRangeFilter, + Date_Time_Picker: datepicker(dateTimePickerCalendars), + Application_Metrics_Button: By.css('.action-bar [data-testid="btn"] span'), + Refresh_Button: By.css('.action-bar [data-testid="refresh"] button'), + App_Status_Title: By.css('.monitoring-application__statistics-section .stats-card:nth-of-type(1) .stats-card__title .data-ellipsis.tooltip-wrapper'), + App_Status_SubTitle: By.css('.monitoring-application__statistics-section .stats-card:nth-of-type(1) [data-testid="monitoring-app-appStatus"] .stats__counter'), + Endpoints_Title: By.css('.monitoring-application__statistics-section .stats-card:nth-of-type(2) .stats-card__title .data-ellipsis.tooltip-wrapper'), + Endpoints_Tip: By.css('.monitoring-application__statistics-section .stats-card:nth-of-type(2) [data-testid="tip"] svg'), + Endpoints_Counter: By.css('.monitoring-application__statistics-section .stats-card:nth-of-type(2) [data-testid="monitoring-app-endpoints"] .stats__counter'), + Detections_Title: By.css('.monitoring-application__statistics-section .stats-card:nth-of-type(3) .stats-card__title .data-ellipsis.tooltip-wrapper'), + Detections_Counter: By.css('.monitoring-application__statistics-section .stats-card:nth-of-type(3) [data-testid="monitoring-app-detections"] .stats__counter'), + Possible_Detections_Title: By.css('.monitoring-application__statistics-section .stats-card:nth-of-type(4) .stats-card__title .data-ellipsis.tooltip-wrapper'), + Possible_Detections_Counter: By.css('.monitoring-application__statistics-section .stats-card:nth-of-type(4) [data-testid="monitoring-app-possibleDetections"] .stats__counter'), + Lag_Title: By.css('.monitoring-application__statistics-section .stats-card:nth-of-type(5) .stats-card__title .data-ellipsis.tooltip-wrapper'), + Lag_Tip: By.css('.monitoring-application__statistics-section .stats-card:nth-of-type(5) [data-testid="tip"] svg'), + Lag_Counter: By.css('.monitoring-application__statistics-section .stats-card:nth-of-type(5) [data-testid="monitoring-app-lag"] .stats__counter'), + Commited_Offset_Title: By.css('.monitoring-application__statistics-section .stats-card:nth-of-type(6) .stats-card__title .data-ellipsis.tooltip-wrapper'), + Commited_Offset_Tip: By.css('.monitoring-application__statistics-section .stats-card:nth-of-type(6) [data-testid="tip"] svg'), + Commited_Offset_Counter: By.css('.monitoring-application__statistics-section .stats-card:nth-of-type(6) [data-testid="monitoring-app-commitedOffset"] .stats__counter'), + Artifacts_Title: By.css('.monitoring-app__section .section-item_title span'), + Artifacts_Table: commonTable(artifactsTable), + See_All_Link: By.css('.monitoring-app__section-item .monitoring-app__see-all-link'), + Results_Title: By.css('.monitoring-app__section.section_small:nth-of-type(2) .monitoring-app__section-item:nth-of-type(1) .section-item_title span'), + Results_Table: commonTable(resultsTable), + Metrics_Title: By.css('.monitoring-app__section.section_small:nth-of-type(2) .monitoring-app__section-item:nth-of-type(2) .section-item_title span'), + Metrics_Tip: By.css('.monitoring-app__section.section_small:nth-of-type(2) .monitoring-app__section-item:nth-of-type(2) [data-testid="tip"] svg'), + Metrics_Table: commonTable(metricsTable), + Shards_Partitions_Status_Title: By.css('.monitoring-app__section.section_small:nth-of-type(3) .monitoring-app__section-item:nth-of-type(1) .section-item_title span'), + Shards_Partitions_Status_Tip: By.css('.monitoring-app__section.section_small:nth-of-type(3) .monitoring-app__section-item:nth-of-type(1) [data-testid="tip"] svg'), + Shards_Partitions_Status_Table: commonTable(shardsPartitionsStatusTable), + Partitions_Status_Lag_Tip: By.css('.monitoring-app__section.section_small:nth-of-type(3) .monitoring-app__section-item:nth-of-type(1) .section-table .section-table__table-cell:nth-of-type(2) [data-testid="tip"] svg'), + Partitions_Status_Commited_Offset_Tip: By.css('.monitoring-app__section.section_small:nth-of-type(3) .monitoring-app__section-item:nth-of-type(1) .section-table .section-table__table-cell:nth-of-type(3) [data-testid="tip"] svg'), + }, + applicationMetrics: { + Back_Button: By.css('.content__action-bar-wrapper .history-back-link [data-testid="history-back-link-btn"]'), + Applications_Metrics_Title: By.css('.content__action-bar-wrapper .history-back-link .history-back-link__title [data-testid="version-history"]'), + Application_Name: By.css('.content__action-bar-wrapper .history-back-link .history-back-link__title .data-ellipsis'), + Application_Monitoring_Button: By.css('.action-bar [data-testid="btn"] span'), + Refresh_Button: By.css('[data-testid="refresh"] [data-testid="refresh-tooltip-wrapper"]'), + Endpoints_List_Section: By.css('.application-metrics-container .list-view .list-view__section:nth-of-type(1)'), + Search_By_Endpoint_Filter_Input: searchByEndpointFilterInput, + Search_Endpoints_Counter: By.css('.application-metrics-container .list-view .list-view__section:nth-of-type(1) .list-view__section-list__search_endpoints-counter'), + Endpoints_List_Table: commonTable(endpointsListTable), } } diff --git a/tests/features/common/page-objects/project-settings.po.js b/tests/features/common/page-objects/project-settings.po.js index 31c68c8bab..87fb7ade51 100644 --- a/tests/features/common/page-objects/project-settings.po.js +++ b/tests/features/common/page-objects/project-settings.po.js @@ -123,7 +123,7 @@ const secretsTable = { } } -module.exports = { +export default { generalTab: { Project_Settings_Tab_Selector: commonTable(tabSelector), Source_URL_Input: inputGroup( diff --git a/tests/features/common/page-objects/project.po.js b/tests/features/common/page-objects/project.po.js index 22cab8706f..eeb90a439b 100644 --- a/tests/features/common/page-objects/project.po.js +++ b/tests/features/common/page-objects/project.po.js @@ -29,11 +29,11 @@ import { } from '../../common-tools/common-tools' import inputGroup from '../components/input-group.component' -const createNewObject = dropdownComponent( +const quickActionsObject = dropdownComponent( generateDropdownGroup( '.main-info__toolbar .create-new-menu', '.select__header', - false, + '[data-testid="select-body"] [data-testid="select-option"]:not(.hidden) .tooltip-wrapper', false ) ) @@ -46,32 +46,54 @@ const actionMenuStructure = { } } -const projectDashboardRealtimeFunctionsTable = { - root: '.main-info__statistics-section .d-flex:nth-of-type(2) .project-data-card .project-data-card__table', +const realtimeFunctionsNuclioTable = { + root: '.d-flex:nth-of-type(2) .project-data-card', header: { - root: '.project-data-card__table-header', + root: '.project-data-card__header', sorters: { + title: '.project-data-card__header-text a', + running_counter_number: '.project-data-card__statistics-item:nth-of-type(1) .project-data-card__statistics-value.statistics_running', + running_counter_subtitle: '.project-data-card__statistics-item:nth-of-type(1) .project-data-card__statistics-label span', + running_counter_icon: '.project-data-card__statistics-item:nth-of-type(1) .project-data-card__statistics-label i', + failed_counter_number: '.project-data-card__statistics-item:nth-of-type(2) .project-data-card__statistics-value.statistics_failed', + failed_counter_subtitle: '.project-data-card__statistics-item:nth-of-type(2) .project-data-card__statistics-label span', + failed_counter_icon: '.project-data-card__statistics-item:nth-of-type(2) .project-data-card__statistics-label i', + api_gateways_counter_number: '.project-data-card__statistics-item:nth-of-type(3) .project-data-card__statistics-value .tooltip-wrapper', + api_gateways_counter_subtitle: '.project-data-card__statistics-item:nth-of-type(3) .project-data-card__statistics-label span', + consumer_groups_counter_number: '.project-data-card__statistics-item:nth-of-type(4) .project-data-card__statistics-value .tooltip-wrapper', + consumer_groups_counter_subtitle: '.project-data-card__statistics-item:nth-of-type(4) .project-data-card__statistics-label span', name: '.table-header__item:nth-of-type(1) .data-ellipsis', status: '.table-header__item:nth-of-type(2) .data-ellipsis' } }, body: { - root: '.project-data-card__table-body', + root: '.section-table__table-body', row: { - root: '.project-data-card__table-row', + root: '.section-table__table-row', fields: { - name: '.project-data-card__table-cell:nth-of-type(1) .data-ellipsis', - status: '.project-data-card__table-cell:nth-of-type(2) .data-ellipsis' + name: '.table-cell_big .data-ellipsis', + status: '.status-cell .data-ellipsis' } } } } - -const projectJobsAndWorkflows = { - root: '.main-info__statistics-section:nth-of-type(4) .project-data-card:nth-of-type(1)', + +const runsTable = { + root: '.d-flex:nth-of-type(1) .project-data-card', header: { - root: '.project-data-card__table-header', + root: '.project-data-card__header', sorters: { + title: '.project-data-card__header-text a', + time_period: '.project-data-card__header-info span', + in_process_counter_number: '.project-data-card__statistics-item:nth-of-type(1) .project-data-card__statistics-value', + in_process_counter_subtitle: '.project-data-card__statistics-item:nth-of-type(1) .project-data-card__statistics-label span', + in_process_counter_icon: '.project-data-card__statistics-item:nth-of-type(1) .project-data-card__statistics-label i', + failed_counter_number: '.project-data-card__statistics-item:nth-of-type(2) .project-data-card__statistics-value', + failed_counter_subtitle: '.project-data-card__statistics-item:nth-of-type(2) .project-data-card__statistics-label span', + failed_counter_icon: '.project-data-card__statistics-item:nth-of-type(2) .project-data-card__statistics-label i', + succeeded_counter_number: '.project-data-card__statistics-item:nth-of-type(3) .project-data-card__statistics-value', + succeeded_counter_subtitle: '.project-data-card__statistics-item:nth-of-type(3) .project-data-card__statistics-label span', + succeeded_counter_icon: '.project-data-card__statistics-item:nth-of-type(3) .project-data-card__statistics-label i', name: '.table-header__item:nth-of-type(1) .data-ellipsis', type: '.table-header__item:nth-of-type(2) .data-ellipsis', status: '.table-header__item:nth-of-type(3) .data-ellipsis', @@ -80,46 +102,16 @@ const projectJobsAndWorkflows = { } }, body: { - root: '.project-data-card__table-body', + root: '.section-table__table-body', row: { - root: '.project-data-card__table-row', + root: '.section-table__table-row', fields: { - name: '.project-data-card__table-cell:nth-of-type(1) .link', - type: '.project-data-card__table-cell:nth-of-type(2) .data-ellipsis', - status: '.project-data-card__table-cell:nth-of-type(2) .data-ellipsis', + name: '.table-cell_big:nth-of-type(1) .data-ellipsis', + type: '.table-cell_small .data-ellipsis', + status: '.status-cell .data-ellipsis', started_at: - '.project-data-card__table-cell:nth-of-type(2) .data-ellipsis', - duration: '.project-data-card__table-cell:nth-of-type(2) .data-ellipsis' - } - } - } -} - -const generalInfoJobsCardStat = { - root: '.main-info__statistics-section .project-data-card:nth-of-type(1)', - header: {}, - body: { - root: '.project-data-card__statistics', - row: { - root: '.project-data-card__statistics-item', - fields: { - name: '.project-data-card__statistics-label', - value: '.project-data-card__statistics-value' - } - } - } -} - -const generalInfoRealTimeFunctionsCardStat = { - root: '.main-info__statistics-section .d-flex:nth-of-type(2) .project-data-card', - header: {}, - body: { - root: '.project-data-card__statistics', - row: { - root: '.project-data-card__statistics-item', - fields: { - name: '.project-data-card__statistics-label', - value: '.project-data-card__statistics-value' + '.table-cell_big:nth-of-type(4) .data-ellipsis', + duration: '.table-cell_medium:nth-of-type(5) .data-ellipsis' } } } @@ -282,40 +274,93 @@ const shardLagsTable = { } } -module.exports = { +export default { project: { - Create_New: createNewObject, - Refresh_Button: By.css('.main-info__toolbar [data-testid="refresh"]'), - Dashboard_Realtime_Functions_Table: commonTable( - projectDashboardRealtimeFunctionsTable - ), - Jobs_And_Workflows: commonTable(projectJobsAndWorkflows), - Recent_text: By.css('.project-data-card .project-data-card__recent-text'), - See_All_Jobs_Link: By.css( - '.project-data-card:nth-of-type(1) .project-data-card__see-all-link' - ), - Mono_Values_Cards: By.css('.main-info__statistics-section:nth-of-type(3)'), - Model_Stats_Title: By.css('.main-info__statistics-section_left .stats-card:nth-of-type(1) .stats-card__row:nth-of-type(1) .stats-card__title span'), - Model_Stats_Tip: By.css('.stats-card:nth-of-type(1) .stats-card__row:nth-of-type(1) [data-testid="tip"]'), - Model_Stats_Counter: By.css('.stats-card:nth-of-type(1) .stats-card__row:nth-of-type(2) [data-testid="monitoring-Models"] .stats__counter'), - FeatureSets_Stats_Title: By.css('.main-info__statistics-section_left .stats-card:nth-of-type(2) .stats-card__row:nth-of-type(1) .stats-card__title span'), - FeatureSets_Stats_Tip: By.css('.stats-card:nth-of-type(2) .stats-card__row:nth-of-type(1) [data-testid="tip"]'), - FeatureSets_Stats_Counter: By.css('.stats-card:nth-of-type(2) .stats-card__row:nth-of-type(2) [data-testid="monitoring-Feature sets"] .stats__counter'), - Artifacts_Stats_Title: By.css('.main-info__statistics-section_left .stats-card:nth-of-type(3) .stats-card__row:nth-of-type(1) .stats-card__title span'), - Artifacts_Stats_Tip: By.css('.stats-card:nth-of-type(3) .stats-card__row:nth-of-type(1) [data-testid="tip"]'), - Artifacts_Stats_Counter: By.css('.stats-card:nth-of-type(3) .stats-card__row:nth-of-type(2) [data-testid="monitoring-Artifacts"] .stats__counter'), - ConsumerGroups_Stats_Title: By.css('.main-info__statistics-section_right .stats-card:nth-of-type(1) .stats-card__row:nth-of-type(1) .stats-card__title span'), - ConsumerGroups_Stats_Counter: By.css('.stats-card:nth-of-type(1) .stats-card__row:nth-of-type(2) [data-testid="monitoring-Consumer groups"] .stats__counter'), - Alerts_Stats_Title: By.css('.main-info__statistics-section_right .stats-card:nth-of-type(2) .stats-card__row:nth-of-type(1) .stats-card__title span'), - Alerts_Stats_Total_Number: By.css('.main-info__statistics-section_right .stats-card:nth-of-type(2) [data-testid="alerts_total_counter"] .stats__counter'), - Alerts_Stats_Endpoint_Number: By.css('.main-info__statistics-section_right .stats-card:nth-of-type(2) [data-testid="alerts_endpoint_counter"] .stats__counter'), - Alerts_Stats_Jobs_Number: By.css('.main-info__statistics-section_right .stats-card:nth-of-type(2) [data-testid="alerts_jobs_counter"] .stats__counter'), - Alerts_Stats_Application_Number: By.css('.main-info__statistics-section_right .stats-card:nth-of-type(2) [data-testid="alerts_application_counter stats__counter-large"] .stats__counter'), - Jobs_Info_Card_Statistics: commonTable(generalInfoJobsCardStat), - Real_Time_Functions_Card_Statistics: commonTable( - generalInfoRealTimeFunctionsCardStat - ), - Add_Source_URL_Label: By.css('.general-info .general-info__source') + Project_Name: By.css('.main-info .page-header__title'), + Created_Details: By.css('.project-details__details-label:nth-of-type(1)'), + Owner_Details: By.css('.project-details__details-label:nth-of-type(2)'), + Info_Baner_Icon: By.css('.main-info .page-header__title [data-testid="tip"] svg'), + Quick_Actions: quickActionsObject, + Refresh_Button: By.css('[data-testid="refresh"]'), + Mono_Values_Cards: By.css('.projects-monitoring-container .projects-monitoring-stats'), + Artifacts_Stats_Container: { + Artifacts_Stats_Title: By.css('.projects-monitoring-stats > div:nth-child(1) .stats-card__title .tooltip-wrapper'), + Artifacts_Stats_Counter: By.css('.projects-monitoring-stats > div:nth-child(1) [data-testid="artifacts_total_counter"] .stats__counter'), + Datasets_Counter_Subtitle: By.css('.projects-monitoring-stats > div:nth-child(1) .stats-card__row:nth-of-type(1) h6'), + Datasets_Counter_Number: By.css('.projects-monitoring-container > div > div:nth-child(1) .stats__details .stats-card__row:nth-of-type(1) .stats__counter'), + Documents_Counter_Subtitle: By.css('.projects-monitoring-stats > div:nth-child(1) .stats-card__row:nth-of-type(2) h6'), + Documents_Counter_Number: By.css('.projects-monitoring-stats > div:nth-child(1) .stats__details .stats-card__row:nth-of-type(2) .stats__counter'), + LLM_Prompts_Counter_Subtitle: By.css('.projects-monitoring-stats > div:nth-child(1) .stats-card__row:nth-of-type(3) h6'), + LLM_Prompts_Counter_Number: By.css('.projects-monitoring-stats > div:nth-child(1) .stats-card__row:nth-of-type(3) .stats__counter'), + Other_Artifacts_Counter_Subtitle: By.css('.projects-monitoring-stats > div:nth-child(1) .stats-card__row:nth-of-type(4) h6'), + Other_Artifacts_Counter_Number: By.css('.projects-monitoring-stats > div:nth-child(1) .stats-card__row:nth-of-type(4) .stats__counter') + }, + Workflows_Stats_Container: { + Workflows_Stats_Title: By.css('.projects-monitoring-stats > div:nth-child(2) .stats-card__title .tooltip-wrapper'), + Filtering_Time_Period: By.css('.projects-monitoring-stats > div:nth-child(2) .project-card__info span'), + Workflows_Stats_Counter: By.css('.projects-monitoring-stats > div:nth-child(2) [data-testid="wf_total_counter"] .stats__counter'), + In_Process_Counter_Subtitle: By.css('.projects-monitoring-stats > div:nth-child(2) .stats-card__row:nth-of-type(1) h6'), + In_Process_Counter_Status_Icon: By.css('.projects-monitoring-stats > div:nth-child(2) .stats-card__row:nth-of-type(1) i.state-running'), + In_Process_Counter_Number: By.css('.projects-monitoring-stats > div:nth-child(2) .stats__details .stats-card__row:nth-of-type(1) div:nth-child(2)'), + Failed_Counter_Subtitle: By.css('.projects-monitoring-stats > div:nth-child(2) .stats-card__row:nth-of-type(2) h6'), + Failed_Counter_Status_Icon: By.css('.projects-monitoring-stats > div:nth-child(2) .stats-card__row:nth-of-type(2) i.state-failed'), + Failed_Counter_Number: By.css('.projects-monitoring-stats > div:nth-child(2) .stats-card__row:nth-of-type(2) div:nth-child(2)'), + Succeeded_Counter_Subtitle: By.css('.projects-monitoring-stats > div:nth-child(2) .stats-card__row:nth-of-type(3) h6'), + Succeeded_Counter_Status_Icon: By.css('.projects-monitoring-stats > div:nth-child(2) .stats-card__row:nth-of-type(3) i.state-completed'), + Succeeded_Counter_Number: By.css('.projects-monitoring-stats > div:nth-child(2) .stats-card__row:nth-of-type(3) div:nth-child(2)') + }, + Scheduled_Stats_Container: { + Scheduled_Stats_Title: By.css('.projects-monitoring-stats > div:nth-child(3) .stats-card__title .tooltip-wrapper'), + Filtering_Time_Period: By.css('.projects-monitoring-stats > div:nth-child(3) .project-card__info span'), + Scheduled_Stats_Counter: By.css('.projects-monitoring-stats > div:nth-child(3) [data-testid="scheduled_total_counter"] .stats__counter'), + Jobs_Counter_Subtitle: By.css('.projects-monitoring-stats > div:nth-child(3) .stats-card__row:nth-of-type(1) h6'), + Jobs_Counter_Number: By.css('.projects-monitoring-stats > div:nth-child(3) .stats__details .stats-card__row:nth-of-type(1) div:nth-child(2)'), + Workflows_Counter_Subtitle: By.css('.projects-monitoring-stats > div:nth-child(3) .stats-card__row:nth-of-type(2) h6'), + Workflows_Counter_Number: By.css('.projects-monitoring-stats > div:nth-child(3) .stats-card__row:nth-of-type(2) div:nth-child(2)') + }, + Models_Stats_Container: { + Models_Stats_Title: By.css('.card__small-container > div.stats-card.monitoring-stats .stats-card__title .tooltip-wrapper'), + Model_Stats_Counter: By.css('.projects-monitoring-stats [data-testid="models_total_counter"] .stats__counter') + }, + Monitoring_App_Stats_Container: { + Monitoring_App_Stats_Title: By.css('.projects-monitoring-stats .application-card .stats-card__title .tooltip-wrapper'), + Monitoring_App_Running_Stats_Counter: By.css('.projects-monitoring-stats .application-card [data-testid="app_running_counter"] .stats__counter'), + Monitoring_App_Running_Counter_Subtitle: By.css('.application-card > div > div:nth-child(2) .stats__details .stats-card__col:nth-of-type(1) .stats__subtitle'), + Monitoring_App_Running_Counter_Status_Icon: By.css('.application-card > div > div:nth-child(2) .stats__details .stats-card__col:nth-of-type(1) .state-running'), + Monitoring_App_Failed_Stats_Counter: By.css('.projects-monitoring-stats .application-card [data-testid="app_failed_counter"] .stats__counter'), + Monitoring_App_Failed_Counter_Subtitle: By.css('.application-card > div > div:nth-child(2) .stats__details .stats-card__col:nth-of-type(2) .stats__subtitle'), + Monitoring_App_Failed_Counter_Status_Icon: By.css('.application-card > div > div:nth-child(2) .stats__details .stats-card__col:nth-of-type(2) .state-failed') + }, + Alerts_Stats_Container: { + Alerts_Stats_Title: By.css('.projects-monitoring-stats > div:nth-child(5) .stats-card__title .tooltip-wrapper'), + Alerts_Stats_Title_Icon: By.css('.projects-monitoring-stats > div:nth-child(5) .stats-card__title-icon'), + Filtering_Time_Period: By.css('.projects-monitoring-stats > div:nth-child(5) .project-card__info span'), + Alerts_Stats_Counter: By.css('.projects-monitoring-stats > div:nth-child(5) [data-testid="alerts_total_counter"]'), + Alerts_Stats_Endpoint_Subtitle: By.css('.projects-monitoring-stats > div:nth-child(5) .stats-card__row:nth-of-type(1) h6'), + Alerts_Stats_Endpoint_Counter: By.css('.projects-monitoring-stats > div:nth-child(5) .stats__details .stats-card__row:nth-of-type(1) div:nth-child(2)'), + Alerts_Stats_Jobs_Subtitle: By.css('.projects-monitoring-stats > div:nth-child(5) .stats-card__row:nth-of-type(2) h6'), + Alerts_Stats_Jobs_Counter: By.css('.projects-monitoring-stats > div:nth-child(5) .stats-card__row:nth-of-type(2) div:nth-child(2)'), + Alerts_Stats_Application_Subtitle: By.css('.projects-monitoring-stats > div:nth-child(5) .stats-card__row:nth-of-type(3) .stats__subtitle'), + Alerts_Stats_Application_Counter: By.css('.projects-monitoring-stats > div:nth-child(5) .stats-card__row:nth-of-type(3) div:nth-child(2)') + }, + Runs_Statistic_Table: commonTable(runsTable), + Runs_Statistic_Section_Container: { + Runs_Statistic_Section_Title_Tip: By.css('.d-flex:nth-of-type(1) [data-testid="tip"] svg'), + In_Process_Counter_Subtitle: By.css('.d-flex:nth-of-type(1) .project-data-card__statistics-item:nth-of-type(1) .project-data-card__statistics-label span'), + Failed_Counter_Subtitle: By.css('.d-flex:nth-of-type(1) .project-data-card__statistics-item:nth-of-type(2) .project-data-card__statistics-label span'), + Succeeded_Counter_Subtitle: By.css('.d-flex:nth-of-type(1) .project-data-card__statistics-item:nth-of-type(3) .project-data-card__statistics-label span'), + Recent_Text: By.css('.d-flex:nth-of-type(1) .project-data-card .project-data-card__recent-text span'), + Recent_Text_Sm: By.css('.d-flex:nth-of-type(1) .project-data-card .project-data-card__recent-text .text-sm'), + All_Jobs_Link: By.css('.d-flex:nth-of-type(1) .project-data-card__see-all-link') + }, + Realtime_Functions_Nuclio_Table: commonTable(realtimeFunctionsNuclioTable), + Realtime_Functions_Nuclio_Statistic_Section: { + ConsumerGroups_Stats_Counter: By.css('.d-flex:nth-of-type(2) .project-data-card__header .project-data-card__statistics-item:nth-of-type(4) .project-data-card__statistics-value'), + Recent_Text: By.css('.d-flex:nth-of-type(2) .project-data-card__recent-text span'), + All_Realtime_Functions_Link: By.css('.d-flex:nth-of-type(2) .project-data-card__see-all-link'), + Running_Counter_Subtitle: By.css('.d-flex:nth-of-type(2) .project-data-card__statistics .project-data-card__statistics-item:nth-of-type(1) span'), + Failed_Counter_Subtitle: By.css('.d-flex:nth-of-type(2) .project-data-card__statistics .project-data-card__statistics-item:nth-of-type(2) span') + } }, demoProject: { Header_Name_Label: labelComponent( diff --git a/tests/features/common/page-objects/projects.po.js b/tests/features/common/page-objects/projects.po.js index 7e261373ac..7d1782c2fa 100644 --- a/tests/features/common/page-objects/projects.po.js +++ b/tests/features/common/page-objects/projects.po.js @@ -101,9 +101,24 @@ const ProjectsTableSelector = { } } -module.exports = { +const projectsTabSelector = { + root: '.projects-content-header .content-menu', + header: {}, + body: { + root: '.content-menu__tabs', + row: { + root: '.content-menu__tab', + fields: { + key: '' + } + } + } +} + +export default { + Projects_Tab_Selector: commonTable(projectsTabSelector), Retrieving_Projects_Message: By.css('[data-testid=no-data]'), - No_Archived_Projects_Message: By.css('.no-filtered-data'), + No_Archived_Projects_Message: By.css('[data-testid="no-data"] h3'), New_Project_Button: By.css( '.projects__wrapper .projects-content-header-item .page-actions-container .btn_register' ), @@ -115,7 +130,7 @@ module.exports = { '.projects__wrapper .projects-content-header .projects-content-header-item [data-testid="active"]' ), Archive_Projects_Button: By.css( - '.projects__wrapper .projects-content-header .projects-content-header-item [data-testid=archived] a' + '.projects__wrapper .projects-content-header .projects-content-header-item [data-testid=archived]' ), Projects_Sorter: By.css('.projects-content-header-item .sort .split-btn__button:nth-of-type(1)'), Projects_Sort_Dropdown: dropdownComponent( @@ -135,12 +150,18 @@ module.exports = { Monitoring_Container_Title: By.css( '.projects-monitoring-container .page-header__title' ), + Monitoring_Artifacts_Box: By.css( + '.projects-monitoring-container .projects-monitoring-stats.projects-monitoring-stats_wide > div:nth-child(1)' + ), Monitoring_Jobs_Box: By.css( - '.projects-monitoring-container .projects-monitoring-stats .stats-card:nth-of-type(1)' + '.projects-monitoring-container .projects-monitoring-stats .stats-card:nth-of-type(2)' ), Monitoring_Workflows_Box: By.css( '.projects-monitoring-container .projects-monitoring-stats .stats-card:nth-of-type(2)' ), + Monitoring_Models_Box: By.css( + '.projects-monitoring-container .projects-monitoring-stats .card__small-container' + ), Monitoring_Scheduled_Box: By.css( '.projects-monitoring-container .projects-monitoring-stats .stats-card:nth-of-type(3)' ), @@ -148,139 +169,170 @@ module.exports = { '.projects-monitoring-container .projects-monitoring-stats .stats-card:nth-of-type(3)' ) }, + Monitoring_Artifacts_Box: { + Monitoring_Artifacts_Box_Title: By.css( + '.projects-monitoring-stats > div:nth-child(1) .stats-card__row .stats-card__title .tooltip-wrapper' + ), + Total_Counter_Number: By.css( + '.projects-monitoring-stats > div:nth-child(1) [data-testid="artifacts_total_counter"]' + ), + Counter_Datasets_Number: By.css( + '.projects-monitoring-stats > div:nth-child(1) .stats__details .stats-card__row:nth-of-type(1) .stats__counter' + ), + Counter_Datasets_Subtitle: By.css( + '.projects-monitoring-stats > div:nth-child(1) .stats-card__row:nth-of-type(1) .stats__subtitle' + ), + Counter_Documents_Number: By.css( + '.projects-monitoring-stats > div:nth-child(1) .stats__details .stats-card__row:nth-of-type(2) .stats__counter' + ), + Counter_Documents_Subtitle: By.css( + '.projects-monitoring-stats > div:nth-child(1) .stats-card__row:nth-of-type(2) .stats__subtitle' + ), + Counter_LLM_Prompt_Number: By.css( + '.projects-monitoring-stats > div:nth-child(1) .stats__details .stats-card__row:nth-of-type(3) .stats__counter' + ), + Counter_LLM_Prompt_Subtitle: By.css( + '.projects-monitoring-stats > div:nth-child(1) .stats-card__row:nth-of-type(3) .stats__subtitle' + ), + Counter_Other_Artifacts_Number: By.css( + '.projects-monitoring-stats > div:nth-child(1) .stats__details .stats-card__row:nth-of-type(4) .stats__counter' + ), + Counter_Other_Artifacts_Subtitle: By.css( + '.projects-monitoring-stats > div:nth-child(1) .stats-card__row:nth-of-type(4) .stats__subtitle' + ) + }, Monitoring_Jobs_Box: { Monitoring_Jobs_Box_Title: By.css( - '.projects-monitoring-stats .stats-card:nth-of-type(1) .stats-card__title' + '.projects-monitoring-stats > div:nth-child(2) .stats-card__title .tooltip-wrapper' ), - Filtering_Time_Period: By.css('.stats-card:nth-of-type(1) .stats-card__col > div > span'), - Total_Counter_Title: By.css( - '.stats-card:nth-of-type(1) .stats-card__col > div > div > span' + Monitoring_Jobs_Box_Title_Tip: By.css( + '.projects-monitoring-stats > div:nth-child(2) .stats-card__title [data-testid="tip"] svg' ), + Filtering_Time_Period: By.css('.projects-monitoring-stats > div:nth-child(2) span'), Total_Counter_Number: By.css( - '.stats-card:nth-of-type(1) .stats-card__col > div > div .stats__counter' + '.projects-monitoring-stats > div:nth-child(2) [data-testid="scheduled_total_counter"]' ), Counter_Running_Status_Number: By.css( - '.stats-card:nth-of-type(1) [data-testid="jobs_running_counter"] .stats__counter' + '.projects-monitoring-stats > div:nth-child(2) .stats__details .stats-card__row:nth-of-type(1) .stats__counter' ), Counter_Running_Status_Subtitle: By.css( - '.stats-card:nth-of-type(1) [data-testid="jobs_running_counter"] .stats__subtitle' + '.projects-monitoring-stats > div:nth-child(2) .stats-card__row:nth-of-type(1) .stats__subtitle' ), Counter_Running_Status_Icon: By.css( - '.stats-card:nth-of-type(1) [data-testid="jobs_running_counter"] .state-running' + '.projects-monitoring-stats > div:nth-child(2) .stats-card__row:nth-of-type(1) .state-running' ), Counter_Failed_Status_Number: By.css( - '.stats-card:nth-of-type(1) [data-testid="jobs_failed_counter"] .stats__counter' + '.projects-monitoring-stats > div:nth-child(2) .stats__details .stats-card__row:nth-of-type(2) .stats__counter' ), Counter_Failed_Status_Subtitle: By.css( - '.stats-card:nth-of-type(1) [data-testid="jobs_failed_counter"] .stats__subtitle' + '.projects-monitoring-stats > div:nth-child(2) .stats-card__row:nth-of-type(2) .stats__subtitle' ), Counter_Failed_Status_Icon: By.css( - '.stats-card:nth-of-type(1) [data-testid="jobs_failed_counter"] .state-failed' + '.projects-monitoring-stats > div:nth-child(2) .stats-card__row:nth-of-type(2) .state-failed' ), Counter_Completed_Status_Number: By.css( - '.stats-card:nth-of-type(1) [data-testid="jobs_completed_counter"] .stats__counter' + '.projects-monitoring-stats > div:nth-child(2) .stats__details .stats-card__row:nth-of-type(3) .stats__counter' ), Counter_Completed_Status_Subtitle: By.css( - '.stats-card:nth-of-type(1) [data-testid="jobs_completed_counter"] .stats__subtitle' + '.projects-monitoring-stats > div:nth-child(2) .stats-card__row:nth-of-type(3) .stats__subtitle' ), Counter_Completed_Status_Icon: By.css( - '.stats-card:nth-of-type(1) [data-testid="jobs_completed_counter"] .state-completed' + '.projects-monitoring-stats > div:nth-child(2) .stats-card__row:nth-of-type(3) .state-completed' ) }, Monitoring_Workflows_Box: { Monitoring_Workflows_Box_Title: By.css( - '.projects-monitoring-stats .stats-card:nth-of-type(2) .stats-card__title' - ), - Filtering_Time_Period: By.css('.stats-card:nth-of-type(2) .stats-card__col > div > span'), - Total_Counter_Title: By.css( - '.stats-card:nth-of-type(2) .stats-card__col > div > div > span' + '.projects-monitoring-stats .stats-card:nth-of-type(3) .stats-card__title' ), + Filtering_Time_Period: By.css('.stats-card:nth-of-type(3) .stats-card__row > div > span'), Total_Counter_Number: By.css( - '.stats-card:nth-of-type(2) .stats-card__col > div > div .stats__counter' + '.projects-monitoring-stats > div:nth-child(3) [data-testid="wf_total_counter"] .stats__counter' ), - Counter_Running_Status_Number: By.css( - '.stats-card:nth-of-type(2) [data-testid="wf_running_counter"] .stats__counter' + Counter_In_Process_Status_Number: By.css( + '.stats-card:nth-of-type(3) [data-testid="wf_running_counter"] .stats__counter' ), - Counter_Running_Status_Subtitle: By.css( - '.stats-card:nth-of-type(2) [data-testid="wf_running_counter"] .stats__subtitle' + Counter_In_Process_Status_Subtitle: By.css( + '.stats-card:nth-of-type(3) [data-testid="wf_running_counter"] .stats__subtitle' ), - Counter_Running_Status_Icon: By.css( - '.stats-card:nth-of-type(2) [data-testid="wf_running_counter"] .state-running' + Counter_In_Process_Status_Icon: By.css( + '.stats-card:nth-of-type(3) [data-testid="wf_running_counter"] .state-running' ), Counter_Failed_Status_Number: By.css( - '.stats-card:nth-of-type(2) [data-testid="wf_failed_counter"] .stats__counter' + '.stats-card:nth-of-type(3) [data-testid="wf_failed_counter"] .stats__counter' ), Counter_Failed_Status_Subtitle: By.css( - '.stats-card:nth-of-type(2) [data-testid="wf_failed_counter"] .stats__subtitle' + '.stats-card:nth-of-type(3) [data-testid="wf_failed_counter"] .stats__subtitle' ), Counter_Failed_Status_Icon: By.css( - '.stats-card:nth-of-type(2) [data-testid="wf_failed_counter"] .state-failed' + '.stats-card:nth-of-type(3) [data-testid="wf_failed_counter"] .state-failed' ), Counter_Completed_Status_Number: By.css( - '.stats-card:nth-of-type(2) [data-testid="wf_completed_counter"] .stats__counter' + '.stats-card:nth-of-type(3) [data-testid="wf_completed_counter"] .stats__counter' ), Counter_Completed_Status_Subtitle: By.css( - '.stats-card:nth-of-type(2) [data-testid="wf_completed_counter"] .stats__subtitle' + '.stats-card:nth-of-type(3) [data-testid="wf_completed_counter"] .stats__subtitle' ), Counter_Completed_Status_Icon: By.css( - '.stats-card:nth-of-type(2) [data-testid="wf_completed_counter"] .state-completed' + '.stats-card:nth-of-type(3) [data-testid="wf_completed_counter"] .state-completed' ) }, Monitoring_Scheduled_Box: { Monitoring_Scheduled_Box_Title: By.css( - '.projects-monitoring-stats .stats-card:nth-of-type(3) .stats-card__title' + '.projects-monitoring-stats .stats-card:nth-of-type(4) .stats-card__title' ), - Filtering_Time_Period: By.css('.stats-card:nth-of-type(3) .stats-card__col > div > span'), + Filtering_Time_Period: By.css('.stats-card:nth-of-type(4) .stats-card__row > div > span'), Total_Job_Counter_Title: By.css( - '.stats-card:nth-of-type(3) [data-testid="scheduled_jobs_counter"] .stats__subtitle' + '.stats-card:nth-of-type(4) [data-testid="scheduled_jobs_counter"] .stats__subtitle' ), Total_Workflows_Counter_Title: By.css( - '.stats-card:nth-of-type(3) [data-testid="scheduled_wf_counter"] .stats__subtitle' - ), - Total_Scheduled_Title: By.css( - '.stats-card:nth-of-type(3) .stats-card__col > div > div > span' + '.stats-card:nth-of-type(4) [data-testid="scheduled_workflows_counter"] .stats__subtitle' ), Total_Job_Counter_Number: By.css( - '.stats-card:nth-of-type(3) [data-testid="scheduled_jobs_counter"] .stats__counter' + '.stats-card:nth-of-type(4) [data-testid="scheduled_jobs_counter"] .stats__counter' ), Total_Workflows_Counter_Number: By.css( - '.stats-card:nth-of-type(3) [data-testid="scheduled_wf_counter"] .stats__counter' + '.stats-card:nth-of-type(4) [data-testid="scheduled_workflows_counter"] .stats__counter' ), Total_Scheduled_Number: By.css( - '.stats-card:nth-of-type(3) .stats-card__col > div > div .stats__counter' + '.projects-monitoring-stats > div:nth-child(4) [data-testid="scheduled_total_counter"]' + ) + }, + Monitoring_Models_Box: { + Monitoring_Models_Title: By.css( + '.projects-monitoring-stats .card__small-container .stats-card__row .stats-card__title .tooltip-wrapper' + ), + Total_Counter_Number: By.css( + '.projects-monitoring-stats .card__small-container [data-testid="models_total_counter"]' ) }, Monitoring_Alerts_Box: { Monitoring_Alerts_Box_Title: By.css( - '.projects-monitoring-stats .stats-card:nth-of-type(4) .stats-card__title' + '.projects-monitoring-stats .alerts-card .stats-card__title .data-ellipsis' ), Monitoring_Alerts_Box_Title_Icon: By.css( - '.projects-monitoring-stats .stats-card:nth-of-type(4) .stats-card__title svg' + '.projects-monitoring-stats .alerts-card .stats-card__title svg' ), - Filtering_Time_Period: By.css('.stats-card:nth-of-type(4) .stats-card__col > div > span'), + Filtering_Time_Period: By.css('.alerts-card .stats-card__row > div > span'), Total_Endpoint_Counter_Number: By.css( - '.stats-card:nth-of-type(4) [data-testid="alerts_endpoint_counter"] .stats__counter' + '.projects-monitoring-stats .alerts-card .stats__details [data-testid="alerts_endpoints_counter"] .stats__counter' ), Total_Endpoint_Counter_Title: By.css( - '.stats-card:nth-of-type(4) [data-testid="alerts_endpoint_counter"] .stats__subtitle' + '.projects-monitoring-stats .alerts-card .stats__details [data-testid="alerts_endpoints_counter"] h6' ), Total_Jobs_Counter_Number: By.css( - '.stats-card:nth-of-type(4) [data-testid="alerts_jobs_counter"] .stats__counter' + '.projects-monitoring-stats .alerts-card .stats__details [data-testid="alerts_job_counter"] .stats__counter' ), Total_Jobs_Counter_Title: By.css( - '.stats-card:nth-of-type(4) [data-testid="alerts_jobs_counter"] .stats__subtitle' + '.projects-monitoring-stats .alerts-card .stats__details [data-testid="alerts_job_counter"] h6' ), Total_Application_Counter_Number: By.css( - '.stats-card:nth-of-type(4) [data-testid="alerts_application_counter stats__counter-large"] .stats__counter' + '.projects-monitoring-stats .alerts-card .stats__details [data-testid="alerts_application_counter"] .stats__counter' ), Total_Application_Counter_Title: By.css( - '.stats-card:nth-of-type(4) [data-testid="alerts_application_counter"] .stats__subtitle' - ), - Total_Alerts_Title: By.css( - '.stats-card:nth-of-type(4) .stats-card__col > div > div > span' + '.projects-monitoring-stats .alerts-card .stats__details [data-testid="alerts_application_counter"] .stats__subtitle' ), Total_Alerts_Number: By.css( - '.stats-card:nth-of-type(4) .stats-card__col > div > div .stats__counter' + '.projects-monitoring-stats .alerts-card [data-testid="alerts_total_counter"]' ) } } diff --git a/tests/features/common/page-objects/side-panel.po.js b/tests/features/common/page-objects/side-panel.po.js index 5205c1b429..37f485fbf8 100644 --- a/tests/features/common/page-objects/side-panel.po.js +++ b/tests/features/common/page-objects/side-panel.po.js @@ -36,7 +36,7 @@ import { generateCheckboxGroup, generateTextAreaGroup } from '../../common-tools/common-tools' -const { By } = require('selenium-webdriver') +import { By } from 'selenium-webdriver' const actionMenuStructure = { root: '.table__cell-actions', @@ -734,7 +734,7 @@ const commonAccessKeyInput = inputGroup( ) ) -module.exports = { +export default { newFeatureSet: { Cross_Close_Button: commonCrossCloseButton, Feature_Set_Name_Input: inputGroup( diff --git a/tests/features/datasets.feature b/tests/features/datasets.feature index 1527a07436..9b5a543aa8 100644 --- a/tests/features/datasets.feature +++ b/tests/features/datasets.feature @@ -88,6 +88,7 @@ Feature: Datasets Page @MLD @passive @smoke + #TODO: Datasets Analysis tab - add the data to verify Scenario: MLD003 - Check all mandatory components in Item infopane on Overview tab table on Datasets page Given open url And wait load page @@ -142,6 +143,7 @@ Feature: Datasets Page @MLD @passive @smoke + #TODO: Datasets Analysis tab - add the data to verify Scenario: MLD005 - Check Details panel still active on page refresh # * set tear-down property "dataset" created in "automation-test" project with "test-file" value * create "test-dataset" Dataset with "v1" tag in "default" project with code 200 @@ -157,6 +159,7 @@ Feature: Datasets Page Then click on "show_all_versions" option on "Datasets" wizard in "Datasets_Table" table with "test-dataset" value in "name" column with scroll "false" And wait load page When click on cell with row index 1 in "uid" column in "Datasets_Table" table on "Datasets" wizard + And wait load page Then check "v1" value in "tag" column in "Overview_Table" table on "Datasets_Info_Pane" wizard Then click on "Edit_btn_table_view" element on "Datasets_Info_Pane" wizard And wait load page @@ -467,7 +470,6 @@ Feature: Datasets Page When select "V3IO" option in "Path_Scheme_Combobox" combobox on "Target_Path" accordion on "Register_Dataset" wizard When type value "target/path" to "Path_Scheme_Combobox" field on "Target_Path" on "Register_Dataset" wizard Then click on "Register_Button" element on "Register_Dataset" wizard - And wait load page Then verify if "Confirm_Popup" popup dialog appears Then "Title" element on "Confirm_Popup" should contains "Overwrite dataset?" value When click on "Overwrite_Button" element on "Confirm_Popup" wizard @@ -481,19 +483,22 @@ Feature: Datasets Page Then click on "History_Back_Button" element on "Datasets" wizard When click on cell with row index 1 in "name" column in "Datasets_Table" table on "Datasets" wizard And wait load page - Then verify "Notification_Pop_Up" element visibility on "Notification_Popup" wizard - And wait load page - Then "Notification_Pop_Up" element on "Notification_Popup" should contains "An error occurred while retrieving the dataset." value - And wait load page - Then verify "Notification_Pop_Up_Cross_Close_Button" element visibility on "Notification_Popup" wizard - Then click on "Notification_Pop_Up_Cross_Close_Button" element on "Notification_Popup" wizard + Then verify "Header" element visibility on "Datasets_Info_Pane" wizard + Then "Header" element on "Datasets_Info_Pane" should contains "test-regressor_cox-test-summary" value + Then verify "Not_In_Filtered_List_Message" element visibility on "Datasets_Info_Pane" wizard + Then "Not_In_Filtered_List_Message" component on "Datasets_Info_Pane" should be equal "Datasets_Info_Pane"."Info_Banner_Message" Then click on "Table_Refresh_Button" element on "Datasets" wizard And wait load page + Then "Header" element on "Datasets_Info_Pane" should contains "test-regressor_cox-test-summary" value + Then verify "Not_In_Filtered_List_Message" element not exists on "Datasets_Info_Pane" wizard + Then click on "Cross_Close_Button" element on "Datasets_Info_Pane" wizard + And wait load page + Then verify "Datasets_Table" element visibility on "Datasets" wizard When click on cell with row index 1 in "name" column in "Datasets_Table" table on "Datasets" wizard And wait load page - Then verify "Header" element visibility on "Files_Info_Pane" wizard + Then verify "Header" element visibility on "Datasets_Info_Pane" wizard Then "Header" element on "Files_Info_Pane" should contains "test-regressor_cox-test-summary" value - #TODO: Verify text message 'The you are viewing was updated. Close the detail panel and refresh the list to see the current version.' on Files_Info_Pane + Then verify "Not_In_Filtered_List_Message" element not exists on "Datasets_Info_Pane" wizard #TODO: Verify that editing the tag to an empty string '' will delete the artifact instance @MLD @@ -509,10 +514,19 @@ Feature: Datasets Page Then hover on cell with row index 2 in "name" column in "Datasets_Table" table on "Datasets" wizard When click on cell with row index 2 in "artifact_preview_btn" column in "Datasets_Table" table on "Datasets" wizard And wait load page - Then verify "Preview_Row" element visibility on "Artifact_Preview_Popup" wizard - Then verify "Cross_Cancel_Button" element visibility on "Artifact_Preview_Popup" wizard - Then check "download_btn" visibility in "Preview_Row" on "Artifact_Preview_Popup" wizard with 1 offset - Then click on "Download_Button" element on "Artifact_Preview_Popup" wizard + Then verify "Preview_Table" element visibility on "Preview_Popup" wizard + Then verify visibility of header column "name" in "Preview_Table" table on "Preview_Popup" wizard + Then check "Name" header value in "name" column in "Preview_Table" table on "Preview_Popup" wizard + Then verify visibility of header column "path" in "Preview_Table" table on "Preview_Popup" wizard + Then check "Path" header value in "path" column in "Preview_Table" table on "Preview_Popup" wizard + Then verify visibility of header column "size" in "Preview_Table" table on "Preview_Popup" wizard + Then check "Size" header value in "size" column in "Preview_Table" table on "Preview_Popup" wizard + Then verify visibility of header column "updated" in "Preview_Table" table on "Preview_Popup" wizard + Then check "Updated" header value in "updated" column in "Preview_Table" table on "Preview_Popup" wizard + Then value in "name" column with "text" in "Preview_Table" on "Preview_Popup" wizard should contains "test_new_structure" + Then verify "Cross_Cancel_Button" element visibility on "Preview_Popup" wizard + Then verify "Download_Button" element visibility on "Preview_Popup" wizard + Then click on "Download_Button" element on "Preview_Popup" wizard And wait load page And wait load page Then verify "Download_Pop_Up" element visibility on "Downloads_Popup" wizard @@ -522,7 +536,7 @@ Feature: Datasets Page Then verify "Header_Download_Pop_Up" element visibility on "Downloads_Popup" wizard Then "Header_Download_Pop_Up" element on "Downloads_Popup" should contains "Downloads" value Then click on "Download_Pop_Up_Cross_Cancel_Button" element on "Downloads_Popup" wizard - Then click on "Cross_Cancel_Button" element on "Artifact_Preview_Popup" wizard + Then click on "Cross_Cancel_Button" element on "Preview_Popup" wizard When click on cell with value "auto-trainer-train_test_set" in "name" column in "Datasets_Table" table on "Datasets" wizard And wait load page Then select "Preview" tab in "Info_Pane_Tab_Selector" on "Datasets_Info_Pane" wizard @@ -530,10 +544,19 @@ Feature: Datasets Page Then verify "Pop_Out_Button" element visibility on "Datasets_Info_Pane" wizard Then click on "Pop_Out_Button" element on "Datasets_Info_Pane" wizard And wait load page - Then verify "Preview_Row" element visibility on "Artifact_Preview_Popup" wizard - Then verify "Cross_Cancel_Button" element visibility on "Artifact_Preview_Popup" wizard - Then check "download_btn" visibility in "Preview_Row" on "Artifact_Preview_Popup" wizard with 1 offset - Then click on "Download_Button" element on "Artifact_Preview_Popup" wizard + Then verify "Preview_Table" element visibility on "Preview_Popup" wizard + Then verify visibility of header column "name" in "Preview_Table" table on "Preview_Popup" wizard + Then check "Name" header value in "name" column in "Preview_Table" table on "Preview_Popup" wizard + Then verify visibility of header column "path" in "Preview_Table" table on "Preview_Popup" wizard + Then check "Path" header value in "path" column in "Preview_Table" table on "Preview_Popup" wizard + Then verify visibility of header column "size" in "Preview_Table" table on "Preview_Popup" wizard + Then check "Size" header value in "size" column in "Preview_Table" table on "Preview_Popup" wizard + Then verify visibility of header column "updated" in "Preview_Table" table on "Preview_Popup" wizard + Then check "Updated" header value in "updated" column in "Preview_Table" table on "Preview_Popup" wizard + Then value in "name" column with "text" in "Preview_Table" on "Preview_Popup" wizard should contains "auto-trainer-train_test_set" + Then verify "Cross_Cancel_Button" element visibility on "Preview_Popup" wizard + Then verify "Download_Button" element visibility on "Preview_Popup" wizard + Then click on "Download_Button" element on "Preview_Popup" wizard And wait load page And wait load page Then verify "Download_Pop_Up" element visibility on "Downloads_Popup" wizard @@ -543,7 +566,7 @@ Feature: Datasets Page Then verify "Header_Download_Pop_Up" element visibility on "Downloads_Popup" wizard Then "Header_Download_Pop_Up" element on "Downloads_Popup" should contains "Downloads" value Then click on "Download_Pop_Up_Cross_Cancel_Button" element on "Downloads_Popup" wizard - Then click on "Cross_Cancel_Button" element on "Artifact_Preview_Popup" wizard + Then click on "Cross_Cancel_Button" element on "Preview_Popup" wizard @MLD @smoke @@ -667,6 +690,7 @@ Feature: Datasets Page @MLD @smoke + #TODO: check the loader after click on "Register_Button" element on "Register_Dataset" wizard Scenario: MLD011 - Check that version tag has "Click to add" status when it's empty after edited Given open url And wait load page @@ -690,7 +714,6 @@ Feature: Datasets Page When select "V3IO" option in "Path_Scheme_Combobox" combobox on "Target_Path" accordion on "Register_Dataset" wizard When type value "target/path" to "Path_Scheme_Combobox" field on "Target_Path" on "Register_Dataset" wizard Then click on "Register_Button" element on "Register_Dataset" wizard - And wait load page Then verify if "Confirm_Popup" popup dialog appears Then "Title" element on "Confirm_Popup" should contains "Overwrite dataset?" value When click on "Overwrite_Button" element on "Confirm_Popup" wizard @@ -704,6 +727,7 @@ Feature: Datasets Page @MLD @smoke + #TODO: check the loader after click on "Register_Button" element on "Register_Dataset" wizard Scenario: MLD012 - Check filter by "All" tag is performed when version tag was edited Given open url And wait load page @@ -742,7 +766,6 @@ Feature: Datasets Page When select "V3IO" option in "Path_Scheme_Combobox" combobox on "Target_Path" accordion on "Register_Dataset" wizard When type value "target/path" to "Path_Scheme_Combobox" field on "Target_Path" on "Register_Dataset" wizard Then click on "Register_Button" element on "Register_Dataset" wizard - And wait load page Then verify if "Confirm_Popup" popup dialog appears Then "Title" element on "Confirm_Popup" should contains "Overwrite dataset?" value When click on "Overwrite_Button" element on "Confirm_Popup" wizard @@ -1197,7 +1220,7 @@ Feature: Datasets Page | Secret | | | | yes | Then verify "Volume_Paths_Table_Volume_Name_Input" element in "Resources_Accordion" on "Modal_Wizard_Form" wizard should display hover warning "Input_Hint"."Input_Field_Require" Then verify "Volume_Paths_Table_Path_Input" element in "Resources_Accordion" on "Modal_Wizard_Form" wizard should display hover warning "Input_Hint"."Input_Field_Require" - Then verify "Volume_Paths_Table_Secret_Name_Input" element in "Resources_Accordion" on "Modal_Wizard_Form" wizard should display hover warning "Input_Hint"."Input_Field_Require" + Then verify "Volume_Paths_Table_Secret_Name_Input" in "Resources_Accordion" on "Modal_Wizard_Form" wizard should display options "Input_Hint"."Secret_Name_Rule_Options" Then verify "Volume_Paths_Table_Path_Input" element in "Resources_Accordion" on "Modal_Wizard_Form" wizard should display hint "Input_Hint"."Mount_Path_Hint" When click on "Delete_New_Row_Button" element in "Resources_Accordion" on "Modal_Wizard_Form" wizard When add new volume rows to "Volume_Paths_Table" table in "Resources_Accordion" on "Modal_Wizard_Form" wizard using nontable inputs @@ -1209,6 +1232,47 @@ Feature: Datasets Page Then verify "Volume_Paths_Table_Path_Input" element in "Resources_Accordion" on "Modal_Wizard_Form" wizard should display hint "Input_Hint"."Mount_Path_Hint" When click on "Delete_New_Row_Button" element in "Resources_Accordion" on "Modal_Wizard_Form" wizard + When add new volume rows to "Volume_Paths_Table" table in "Resources_Accordion" on "Modal_Wizard_Form" wizard using nontable inputs + | Volume_Paths_Table_Type_Dropdown | Volume_Paths_Table_Volume_Name_Input | Volume_Paths_Table_Path_Input | Volume_Paths_Table_Secret_Name_Input | Add_New_Row_Button | + | Secret | | | mlrun-project-secrets-defaultinv | yes | + Then verify "Volume_Paths_Table_Volume_Name_Input" element in "Resources_Accordion" on "Modal_Wizard_Form" wizard should display hover warning "Input_Hint"."Input_Field_Require" + Then verify "Volume_Paths_Table_Path_Input" element in "Resources_Accordion" on "Modal_Wizard_Form" wizard should display hover warning "Input_Hint"."Input_Field_Require" + Then verify "Volume_Paths_Table_Path_Input" element in "Resources_Accordion" on "Modal_Wizard_Form" wizard should display hint "Input_Hint"."Mount_Path_Hint" + Then verify "Volume_Paths_Table_Secret_Name_Input" in "Resources_Accordion" on "Modal_Wizard_Form" wizard should display options "Input_Hint"."Secret_Name_Rule_Options" + When click on "Delete_New_Row_Button" element in "Resources_Accordion" on "Modal_Wizard_Form" wizard + When add new volume rows to "Volume_Paths_Table" table in "Resources_Accordion" on "Modal_Wizard_Form" wizard using nontable inputs + | Volume_Paths_Table_Type_Dropdown | Volume_Paths_Table_Volume_Name_Input | Volume_Paths_Table_Path_Input | Volume_Paths_Table_Secret_Name_Input | Add_New_Row_Button | + | Secret | test | test | mlrun-project-secrets-default | yes | + Then verify values in "Volume_Paths_Table" table in "Resources_Accordion" on "Modal_Wizard_Form" wizard + | type | volume_name | path | + | Secret | test | test | + When click on data "remove_btn" in "Volume_Paths_Table" table in "Resources_Accordion" on "Modal_Wizard_Form" wizard + | type | + | Secret | + When add new volume rows to "Volume_Paths_Table" table in "Resources_Accordion" on "Modal_Wizard_Form" wizard using nontable inputs + | Volume_Paths_Table_Type_Dropdown | Volume_Paths_Table_Volume_Name_Input | Volume_Paths_Table_Path_Input | Volume_Paths_Table_Secret_Name_Input | Add_New_Row_Button | + | Secret | | | mlrun-auth-secrets. | yes | + Then verify "Volume_Paths_Table_Volume_Name_Input" element in "Resources_Accordion" on "Modal_Wizard_Form" wizard should display hover warning "Input_Hint"."Input_Field_Require" + Then verify "Volume_Paths_Table_Path_Input" element in "Resources_Accordion" on "Modal_Wizard_Form" wizard should display hover warning "Input_Hint"."Input_Field_Require" + Then verify "Volume_Paths_Table_Path_Input" element in "Resources_Accordion" on "Modal_Wizard_Form" wizard should display hint "Input_Hint"."Mount_Path_Hint" + Then verify "Volume_Paths_Table_Secret_Name_Input" in "Resources_Accordion" on "Modal_Wizard_Form" wizard should display options "Input_Hint"."Secret_Name_Rule_Options" + When click on "Delete_New_Row_Button" element in "Resources_Accordion" on "Modal_Wizard_Form" wizard + When add new volume rows to "Volume_Paths_Table" table in "Resources_Accordion" on "Modal_Wizard_Form" wizard using nontable inputs + | Volume_Paths_Table_Type_Dropdown | Volume_Paths_Table_Volume_Name_Input | Volume_Paths_Table_Path_Input | Volume_Paths_Table_Secret_Name_Input | Add_New_Row_Button | + | Secret | test | test | mlrun-auth-secrets | yes | + Then verify values in "Volume_Paths_Table" table in "Resources_Accordion" on "Modal_Wizard_Form" wizard + | type | volume_name | path | + | Secret | test | test | + When click on data "remove_btn" in "Volume_Paths_Table" table in "Resources_Accordion" on "Modal_Wizard_Form" wizard + | type | + | Secret | + Then verify "Cross_Close_Button" element visibility on "Modal_Wizard_Form" wizard + And click on "Cross_Close_Button" element on "Modal_Wizard_Form" wizard + And wait load page + Then verify "Info_Pane_Tab_Selector" element visibility on "Datasets_Info_Pane" wizard + Then verify "Overview" tab is active in "Info_Pane_Tab_Selector" on "Datasets_Info_Pane" wizard + Then verify "Header" element visibility on "Datasets_Info_Pane" wizard + @MLD @smoke Scenario: MLD024 - Check Advanced components on Train Model wizard @@ -1251,6 +1315,45 @@ Feature: Datasets Page | name1 | secret | sectretName1:sectretKey1 | | name2 | value | 1 | | name3 | secret | sectretName2:sectretKey2 | + When click on "delete_btn" in "Advanced_Environment_Variables_Table" table on "Modal_Wizard_Form" wizard with offset "false" + | name_verify | + | name1 | + | name2 | + | name3 | + When add data to "Advanced_Environment_Variables_Table" table on "Modal_Wizard_Form" wizard with several inputs + | name_input | type_dropdown | value_input | value_input_key | + | name1 | Secret | mlrun-project-secrets-defaultinv | sectretKey1 | + Then verify "Env_Variables_Table_Secret_Name_Input" in "Advanced_Accordion" on "Modal_Wizard_Form" wizard should display options "Input_Hint"."Secret_Name_Rule_Options1" + When click on "Delete_New_Row_Button" element in "Advanced_Accordion" on "Modal_Wizard_Form" wizard + When add data to "Advanced_Environment_Variables_Table" table on "Modal_Wizard_Form" wizard with several inputs + | name_input | type_dropdown | value_input | value_input_key | + | name1 | Secret | mlrun-project-secrets-default | sectretKey1 | + Then verify data in "Advanced_Environment_Variables_Table" table on "Modal_Wizard_Form" wizard + | name_verify | type_dropdown_verify | value_verify | + | name1 | secret | mlrun-project-secrets-default:sectretKey1 | + When click on "delete_btn" in "Advanced_Environment_Variables_Table" table on "Modal_Wizard_Form" wizard with offset "false" + | name_verify | + | name1 | + When add data to "Advanced_Environment_Variables_Table" table on "Modal_Wizard_Form" wizard with several inputs + | name_input | type_dropdown | value_input | value_input_key | + | name1 | Secret | mlrun-auth-secrets. | sectretKey1 | + Then verify "Env_Variables_Table_Secret_Name_Input" in "Advanced_Accordion" on "Modal_Wizard_Form" wizard should display options "Input_Hint"."Secret_Name_Rule_Options1" + When click on "Delete_New_Row_Button" element in "Advanced_Accordion" on "Modal_Wizard_Form" wizard + When add data to "Advanced_Environment_Variables_Table" table on "Modal_Wizard_Form" wizard with several inputs + | name_input | type_dropdown | value_input | value_input_key | + | name1 | Secret | mlrun-auth-secrets | sectretKey1 | + Then verify data in "Advanced_Environment_Variables_Table" table on "Modal_Wizard_Form" wizard + | name_verify | type_dropdown_verify | value_verify | + | name1 | secret | mlrun-auth-secrets:sectretKey1 | + When click on "delete_btn" in "Advanced_Environment_Variables_Table" table on "Modal_Wizard_Form" wizard with offset "false" + | name_verify | + | name1 | + Then verify "Cross_Close_Button" element visibility on "Modal_Wizard_Form" wizard + And click on "Cross_Close_Button" element on "Modal_Wizard_Form" wizard + And wait load page + Then verify "Info_Pane_Tab_Selector" element visibility on "Datasets_Info_Pane" wizard + Then verify "Overview" tab is active in "Info_Pane_Tab_Selector" on "Datasets_Info_Pane" wizard + Then verify "Header" element visibility on "Datasets_Info_Pane" wizard @MLD @smoke @@ -1337,127 +1440,64 @@ Feature: Datasets Page @MLD @smoke - Scenario: MLD027 - Verify dataset elements visibility on Datasets Table with high number of rows - * create "new_dataset_10" Dataset with "set_10" tag in "churn-project-admin" project with code 200 - * create "new_dataset_11" Dataset with "set_11" tag in "churn-project-admin" project with code 200 - * create "new_dataset_12" Dataset with "set_12" tag in "churn-project-admin" project with code 200 - * create "new_dataset_13" Dataset with "set_13" tag in "churn-project-admin" project with code 200 - * create "new_dataset_14" Dataset with "set_14" tag in "churn-project-admin" project with code 200 - * create "new_dataset_15" Dataset with "set_15" tag in "churn-project-admin" project with code 200 - * create "new_dataset_16" Dataset with "set_16" tag in "churn-project-admin" project with code 200 - * create "new_dataset_17" Dataset with "set_17" tag in "churn-project-admin" project with code 200 - * create "new_dataset_18" Dataset with "set_18" tag in "churn-project-admin" project with code 200 - * create "new_dataset_19" Dataset with "set_19" tag in "churn-project-admin" project with code 200 - * create "new_dataset_20" Dataset with "set_20" tag in "churn-project-admin" project with code 200 - * create "new_dataset_21" Dataset with "set_21" tag in "churn-project-admin" project with code 200 - * create "new_dataset_22" Dataset with "set_22" tag in "churn-project-admin" project with code 200 - * create "new_dataset_23" Dataset with "set_23" tag in "churn-project-admin" project with code 200 - * create "new_dataset_24" Dataset with "set_24" tag in "churn-project-admin" project with code 200 + Scenario: MLD027 - Verify not in filtered list message dataset from the main page and version history Given open url And wait load page And click on row root with value "churn-project-admin" in "name" column in "Projects_Table" table on "Projects" wizard And wait load page - And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard - And click on cell with value "Datasets" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard + And select "tab" with "Datasets" value in breadcrumbs menu And wait load page - And hover "MLRun_Logo" component on "commonPagesHeader" wizard + Then click on "show_all_versions" option on "Datasets" wizard in "Datasets_Table" table with "test-regressor_cox-test-summary" value in "name" column with scroll "false" And wait load page - Then verify that 24 row elements are displayed in "Datasets_Table" on "Datasets" wizard - Then check "new_dataset_10" value in "name" column in "Datasets_Table" table on "Datasets" wizard - Then check "new_dataset_24" value in "name" column in "Datasets_Table" table on "Datasets" wizard - Then check "data_clean_cleaned-data" value in "name" column in "Datasets_Table" table on "Datasets" wizard - Then verify "BE_Pagination_Navigate_Prev" element visibility on "Pagination_Info_Pane" wizard - Then verify "BE_Pagination_Navigate_Prev" element on "Pagination_Info_Pane" wizard is disabled - Then verify "BE_Pagination_Navigate_Next" element visibility on "Pagination_Info_Pane" wizard - Then verify "BE_Pagination_Navigate_Next" element on "Pagination_Info_Pane" wizard is disabled - Then verify "FE_Pagination_Navigate_Next" element visibility on "Pagination_Info_Pane" wizard - Then verify "FE_Pagination_Navigate_Next" element on "Pagination_Info_Pane" wizard is disabled - Then verify "FE_Pagination_Navigate_Prev" element visibility on "Pagination_Info_Pane" wizard - Then verify "FE_Pagination_Navigate_Prev" element on "Pagination_Info_Pane" wizard is disabled - Then verify "Pagination_Page_Number" element visibility on "Pagination_Info_Pane" wizard - Then "Pagination_Page_Number" element on "Pagination_Info_Pane" should contains "1" value - Then verify "Pagination_Count" element visibility on "Pagination_Info_Pane" wizard - Then "Pagination_Count" element on "Pagination_Info_Pane" should contains "Showing 1 - 24" value - Then click on cell with value "data_clean_cleaned-data" in "name" column in "Datasets_Table" table on "Datasets" wizard - And wait load page - Then "Header" element on "Datasets_Info_Pane" should contains "data_clean_cleaned-data" value - Then type value "new_dataset_10" to "Table_Name_Filter_Input" field on "Datasets" wizard - Then click on "Table_Refresh_Button" element on "Datasets" wizard + Then verify "History_Back_Button" element visibility on "Datasets" wizard + Then "Version_History_Model_Name" element on "Datasets" should contains "test-regressor_cox-test-summary" value + Then verify "Register_Dataset_Button" element visibility on "Datasets" wizard + Then click on "Register_Dataset_Button" element on "Datasets" wizard + Then verify if "Register_Dataset" popup dialog appears + Then type value "test-regressor_cox-test-summary" to "Name_Input" field on "Register_Dataset" wizard + When select "V3IO" option in "Path_Scheme_Combobox" combobox on "Target_Path" accordion on "Register_Dataset" wizard + When type value "target/path" to "Path_Scheme_Combobox" field on "Target_Path" on "Register_Dataset" wizard + Then click on "Register_Button" element on "Register_Dataset" wizard + Then verify if "Confirm_Popup" popup dialog appears + Then "Title" element on "Confirm_Popup" should contains "Overwrite dataset?" value + When click on "Overwrite_Button" element on "Confirm_Popup" wizard And wait load page - Then "Header" element on "Datasets_Info_Pane" should contains "data_clean_cleaned-data" value - Then verify "Not_In_Filtered_List_Message" element visibility on "Datasets_Info_Pane" wizard - Then "Not_In_Filtered_List_Message" component on "Datasets_Info_Pane" should be equal "Datasets_Info_Pane"."Info_Banner_Message" - Then click on "Cross_Close_Button" element on "Datasets_Info_Pane" wizard + Then verify "Notification_Pop_Up" element visibility on "Notification_Popup" wizard And wait load page - Then verify "Header" element not exists on "Datasets_Info_Pane" wizard - Then value in "name" column with "text" in "Datasets_Table" on "Datasets" wizard should contains "new_dataset_10" - Then verify "BE_Pagination_Navigate_Prev" element visibility on "Pagination_Info_Pane" wizard - Then verify "BE_Pagination_Navigate_Prev" element on "Pagination_Info_Pane" wizard is disabled - Then verify "BE_Pagination_Navigate_Next" element visibility on "Pagination_Info_Pane" wizard - Then verify "BE_Pagination_Navigate_Next" element on "Pagination_Info_Pane" wizard is disabled - Then verify "FE_Pagination_Navigate_Next" element visibility on "Pagination_Info_Pane" wizard - Then verify "FE_Pagination_Navigate_Next" element on "Pagination_Info_Pane" wizard is disabled - Then verify "FE_Pagination_Navigate_Prev" element visibility on "Pagination_Info_Pane" wizard - Then verify "FE_Pagination_Navigate_Prev" element on "Pagination_Info_Pane" wizard is disabled - Then verify "Pagination_Page_Number" element visibility on "Pagination_Info_Pane" wizard - Then "Pagination_Page_Number" element on "Pagination_Info_Pane" should contains "1" value - Then verify "Pagination_Count" element visibility on "Pagination_Info_Pane" wizard - Then "Pagination_Count" element on "Pagination_Info_Pane" should contains "Showing 1 - 1" value - Then type value "new_data" to "Table_Name_Filter_Input" field on "Datasets" wizard - Then click on "Table_Refresh_Button" element on "Datasets" wizard + Then "Notification_Pop_Up" element on "Notification_Popup" should contains "Register dataset initiated successfully" value And wait load page - Then value in "name" column with "text" in "Datasets_Table" on "Datasets" wizard should contains "new_data" - Then verify "BE_Pagination_Navigate_Prev" element visibility on "Pagination_Info_Pane" wizard - Then verify "BE_Pagination_Navigate_Prev" element on "Pagination_Info_Pane" wizard is disabled - Then verify "BE_Pagination_Navigate_Next" element visibility on "Pagination_Info_Pane" wizard - Then verify "BE_Pagination_Navigate_Next" element on "Pagination_Info_Pane" wizard is disabled - Then verify "FE_Pagination_Navigate_Next" element visibility on "Pagination_Info_Pane" wizard - Then verify "FE_Pagination_Navigate_Next" element on "Pagination_Info_Pane" wizard is disabled - Then verify "FE_Pagination_Navigate_Prev" element visibility on "Pagination_Info_Pane" wizard - Then verify "FE_Pagination_Navigate_Prev" element on "Pagination_Info_Pane" wizard is disabled - Then verify "Pagination_Page_Number" element visibility on "Pagination_Info_Pane" wizard - Then "Pagination_Page_Number" element on "Pagination_Info_Pane" should contains "1" value - Then verify "Pagination_Count" element visibility on "Pagination_Info_Pane" wizard - Then "Pagination_Count" element on "Pagination_Info_Pane" should contains "Showing 1 - 15" value - And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard - And click on cell with value "Feature store" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard + Then verify "Notification_Pop_Up_Cross_Close_Button" element visibility on "Notification_Popup" wizard + Then click on "Notification_Pop_Up_Cross_Close_Button" element on "Notification_Popup" wizard + Then click on "History_Back_Button" element on "Datasets" wizard And wait load page - And hover "MLRun_Logo" component on "commonPagesHeader" wizard + Then click on cell with value "test-regressor_cox-test-summary" in "name" column in "Datasets_Table" table on "Datasets" wizard And wait load page - And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard - And click on cell with value "Datasets" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard + Then "Header" element on "Datasets_Info_Pane" should contains "test-regressor_cox-test-summary" value + Then verify "Not_In_Filtered_List_Message" element visibility on "Datasets_Info_Pane" wizard + Then "Not_In_Filtered_List_Message" component on "Datasets_Info_Pane" should be equal "Datasets_Info_Pane"."Info_Banner_Message" + Then click on "Full_View_Button" element on "Datasets_Info_Pane" wizard + Then verify "Cross_Close_Button" element not exists on "Datasets_Info_Pane" wizard + Then verify "Header_Full_View" element visibility on "Datasets_Info_Pane" wizard + Then "Header_Full_View" element on "Datasets_Info_Pane" should contains "test-regressor_cox-test-summary" value + Then verify "Not_In_Filtered_List_Message" element visibility on "Datasets_Info_Pane" wizard + Then "Not_In_Filtered_List_Message" component on "Datasets_Info_Pane" should be equal "Datasets_Info_Pane"."Info_Banner_Message" + Then click on "Refresh_Button_Full_View" element on "Datasets_Info_Pane" wizard And wait load page - Then verify that 24 row elements are displayed in "Datasets_Table" on "Datasets" wizard - Then verify "BE_Pagination_Navigate_Prev" element visibility on "Pagination_Info_Pane" wizard - Then verify "BE_Pagination_Navigate_Prev" element on "Pagination_Info_Pane" wizard is disabled - Then verify "BE_Pagination_Navigate_Next" element visibility on "Pagination_Info_Pane" wizard - Then verify "BE_Pagination_Navigate_Next" element on "Pagination_Info_Pane" wizard is disabled - Then verify "FE_Pagination_Navigate_Next" element visibility on "Pagination_Info_Pane" wizard - Then verify "FE_Pagination_Navigate_Next" element on "Pagination_Info_Pane" wizard is disabled - Then verify "FE_Pagination_Navigate_Prev" element visibility on "Pagination_Info_Pane" wizard - Then verify "FE_Pagination_Navigate_Prev" element on "Pagination_Info_Pane" wizard is disabled - Then verify "Pagination_Page_Number" element visibility on "Pagination_Info_Pane" wizard - Then "Pagination_Page_Number" element on "Pagination_Info_Pane" should contains "1" value - Then verify "Pagination_Count" element visibility on "Pagination_Info_Pane" wizard - Then "Pagination_Count" element on "Pagination_Info_Pane" should contains "Showing 1 - 24" value - Then click on cell with value "test-regressor_cox-test-summary" in "name" column in "Datasets_Table" table on "Datasets" wizard + Then verify "Not_In_Filtered_List_Message" element visibility on "Datasets_Info_Pane" wizard + Then "Not_In_Filtered_List_Message" component on "Datasets_Info_Pane" should be equal "Datasets_Info_Pane"."Info_Banner_Message" + Then click on "Tabel_View_Button" element on "Datasets_Info_Pane" wizard And wait load page - Then verify that 24 row elements are displayed in "Datasets_Table" on "Datasets" wizard - Then verify "BE_Pagination_Navigate_Prev" element visibility on "Pagination_Info_Pane" wizard - Then verify "BE_Pagination_Navigate_Prev" element on "Pagination_Info_Pane" wizard is disabled - Then verify "BE_Pagination_Navigate_Next" element visibility on "Pagination_Info_Pane" wizard - Then verify "BE_Pagination_Navigate_Next" element on "Pagination_Info_Pane" wizard is disabled - Then verify "FE_Pagination_Navigate_Next" element visibility on "Pagination_Info_Pane" wizard - Then verify "FE_Pagination_Navigate_Next" element on "Pagination_Info_Pane" wizard is disabled - Then verify "FE_Pagination_Navigate_Prev" element visibility on "Pagination_Info_Pane" wizard - Then verify "FE_Pagination_Navigate_Prev" element on "Pagination_Info_Pane" wizard is disabled - Then verify "Pagination_Page_Number" element visibility on "Pagination_Info_Pane" wizard - Then "Pagination_Page_Number" element on "Pagination_Info_Pane" should contains "1" value - Then verify "Pagination_Count" element visibility on "Pagination_Info_Pane" wizard - Then "Pagination_Count" element on "Pagination_Info_Pane" should contains "Showing 1 - 24" value + Then verify "Cross_Close_Button" element visibility on "Datasets_Info_Pane" wizard + Then "Header" element on "Datasets_Info_Pane" should contains "test-regressor_cox-test-summary" value + Then verify "Not_In_Filtered_List_Message" element visibility on "Datasets_Info_Pane" wizard + Then "Not_In_Filtered_List_Message" component on "Datasets_Info_Pane" should be equal "Datasets_Info_Pane"."Info_Banner_Message" + Then click on "Table_Refresh_Button" element on "Datasets" wizard + And wait load page + Then "Header" element on "Datasets_Info_Pane" should contains "test-regressor_cox-test-summary" value + Then verify "Not_In_Filtered_List_Message" element not exists on "Datasets_Info_Pane" wizard Then click on "Cross_Close_Button" element on "Datasets_Info_Pane" wizard And wait load page - Then verify "Header" element not exists on "Datasets_Info_Pane" wizard + Then verify "Datasets_Table" element visibility on "Datasets" wizard @MLD @smoke diff --git a/tests/features/featureStore.feature b/tests/features/featureStore.feature index 1e7025702a..1c0ec54636 100644 --- a/tests/features/featureStore.feature +++ b/tests/features/featureStore.feature @@ -8,9 +8,9 @@ Feature: Feature Store Page Scenario: MLFS001 - Check all mandatory components on Feature Store tab Given open url And wait load page - And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard + And click on row root with value "fraud-demo2-admin" in "name" column in "Projects_Table" table on "Projects" wizard And wait load page - Then verify breadcrumbs "project" label should be equal "default" value + Then verify breadcrumbs "project" label should be equal "fraud-demo2-admin" value And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard And click on cell with value "Feature store" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard And hover "MLRun_Logo" component on "commonPagesHeader" wizard @@ -53,9 +53,9 @@ Feature: Feature Store Page Scenario: MLFS002 - Check all mandatory components on Features tab Given open url And wait load page - And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard + And click on row root with value "fraud-demo2-admin" in "name" column in "Projects_Table" table on "Projects" wizard And wait load page - Then verify breadcrumbs "project" label should be equal "default" value + Then verify breadcrumbs "project" label should be equal "fraud-demo2-admin" value And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard And click on cell with value "Feature store" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard And hover "MLRun_Logo" component on "commonPagesHeader" wizard @@ -101,9 +101,9 @@ Feature: Feature Store Page Scenario: MLFS003 - Check all mandatory components on Feature Vectors tab Given open url And wait load page - And click on row root with value "fsdemo-admin" in "name" column in "Projects_Table" table on "Projects" wizard + And click on row root with value "fraud-demo2-admin" in "name" column in "Projects_Table" table on "Projects" wizard And wait load page - Then verify breadcrumbs "project" label should be equal "fsdemo-admin" value + Then verify breadcrumbs "project" label should be equal "fraud-demo2-admin" value And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard And click on cell with value "Feature store" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard And hover "MLRun_Logo" component on "commonPagesHeader" wizard @@ -127,6 +127,8 @@ Feature: Feature Store Page Then verify "Clear_Button" element on "FilterBy_Popup" wizard is disabled Then click on "Table_FilterBy_Button" element on "Feature_Store_Feature_Sets_Tab" wizard Then verify "Table_Refresh_Button" element visibility on "Feature_Store_Features_Vectors_Tab" wizard + Then select "project" with "fsdemo-admin" value in breadcrumbs menu + And wait load page Then verify "Feature_Vectors_Table" element visibility on "Feature_Store_Features_Vectors_Tab" wizard @MLFS @@ -209,7 +211,6 @@ Feature: Feature Store Page @passive @inProgress @smoke - # Moved analyses tabs to Demo mode in `1.8.0` ML-9059 Scenario: MLFS005 - Check all mandatory components in Item infopane on Overview tab table on Feature Vectors tab Given open url And wait load page @@ -382,7 +383,6 @@ Feature: Feature Store Page @passive @inProgress @smoke - # Moved analyses tabs to Demo mode in `1.8.0` ML-9059 Scenario: MLFS011 - Check all mandatory components in Item infopane on Analysis tab table Given open url And wait load page @@ -398,7 +398,7 @@ Feature: Feature Store Page Then select "Analysis" tab in "Info_Pane_Tab_Selector" on "Feature_Sets_Info_Pane" wizard Then verify "Analysis" tab is active in "Info_Pane_Tab_Selector" on "Analysis_Info_Pane" wizard Then verify "Feature Sets" tab is active in "Feature_Store_Tab_Selector" on "Feature_Store_Feature_Sets_Tab" wizard - Then verify "Info_Pane_Tab_Selector" on "Analysis_Info_Pane" wizard should contains "Feature_Sets_Info_Pane"."Tab_List_Demo" + Then verify "Info_Pane_Tab_Selector" on "Analysis_Info_Pane" wizard should contains "Feature_Sets_Info_Pane"."Tab_List" Then verify "Info_Pane_Tab_Selector" element visibility on "Analysis_Info_Pane" wizard Then verify "Header" element visibility on "Analysis_Info_Pane" wizard Then verify "Updated" element visibility on "Analysis_Info_Pane" wizard @@ -574,7 +574,9 @@ Feature: Feature Store Page And select "tab" with "Feature store" value in breadcrumbs menu And wait load page And select "Feature Vectors" tab in "Feature_Store_Tab_Selector" on "Feature_Store_Feature_Sets_Tab" wizard + And wait load page Then click on "Table_FilterBy_Button" element on "Feature_Store_Features_Vectors_Tab" wizard + And wait load page When select "test-tag" option in "Table_Tree_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard Then click on "Apply_Button" element on "FilterBy_Popup" wizard And wait load page @@ -774,6 +776,7 @@ Feature: Feature Store Page Then verify "Feature_Set_Name_Input" on "New_Feature_Set" wizard should display options "Input_Hint"."Feature_Set_Name_Hint" When click on "Accordion_Header" element in "Data_Source_Accordion" on "New_Feature_Set" wizard Then verify "Feature_Set_Name_Input" options rules on "New_Feature_Set" wizard + And wait load page Then type value " " to "Version_Input" field on "New_Feature_Set" wizard Then verify "Version_Input" on "New_Feature_Set" wizard should display options "Input_Hint"."Feature_Set_Version_Hint" When click on "Accordion_Header" element in "Data_Source_Accordion" on "New_Feature_Set" wizard @@ -2299,6 +2302,7 @@ Feature: Feature Store Page @MLFS @smoke + #TODO: check the loader after select "Delete" option in action menu on "Feature_Store_Features_Vectors_Tab" wizard in "Feature_Vectors_Table" table Scenario: MLFS061 - Check Feature vector deletion Given open url And wait load page @@ -2312,7 +2316,6 @@ Feature: Feature Store Page And wait load page Then verify "Feature Vectors" tab is active in "Feature_Store_Tab_Selector" on "Feature_Store_Feature_Sets_Tab" wizard Then select "Delete" option in action menu on "Feature_Store_Features_Vectors_Tab" wizard in "Feature_Vectors_Table" table at row with "patient-deterioration" value in "name" column - And wait load page Then verify if "Confirm_Popup" popup dialog appears Then "Title" element on "Confirm_Popup" should contains "Delete feature vector?" value Then verify "Cross_Cancel_Button" element visibility on "Confirm_Popup" wizard @@ -2327,7 +2330,6 @@ Feature: Feature Store Page When click on "Cancel_Button" element on "Confirm_Popup" wizard And wait load page Then select "Delete" option in action menu on "Feature_Store_Features_Vectors_Tab" wizard in "Feature_Vectors_Table" table at row with "patient-deterioration" value in "name" column - And wait load page Then verify if "Confirm_Popup" popup dialog appears Then verify "Cross_Cancel_Button" element visibility on "Confirm_Popup" wizard When click on "Cross_Cancel_Button" element on "Confirm_Popup" wizard @@ -2340,13 +2342,11 @@ Feature: Feature Store Page And wait load page Then check "expand_btn" visibility in "Feature_Vectors_Table" on "Feature_Store_Features_Vectors_Tab" wizard with 0 offset Then select "Delete" option in action menu on "Feature_Store_Features_Vectors_Tab" wizard in "Feature_Vectors_Table" table at row with "patient-deterioration" value in "name" column - And wait load page Then verify if "Confirm_Popup" popup dialog appears When click on "Cancel_Button" element on "Confirm_Popup" wizard And wait load page Then click on cell with row index 2 in "expand_btn" column in "Feature_Vectors_Table" table on "Feature_Store_Features_Vectors_Tab" wizard Then select "Delete" option in action menu on "Feature_Store_Features_Vectors_Tab" wizard in "Feature_Vectors_Table" table at row with "latest" value in "name_expand_btn" column - And wait load page Then verify if "Confirm_Popup" popup dialog appears Then "Title" element on "Confirm_Popup" should contains "Delete feature vector?" value Then verify "Cross_Cancel_Button" element visibility on "Confirm_Popup" wizard @@ -2361,13 +2361,11 @@ Feature: Feature Store Page When click on "Cancel_Button" element on "Confirm_Popup" wizard And wait load page Then select "Delete" option in action menu on "Feature_Store_Features_Vectors_Tab" wizard in "Feature_Vectors_Table" table at row with "latest" value in "name_expand_btn" column - And wait load page When click on "Cancel_Button" element on "Confirm_Popup" wizard And wait load page When click on cell with row index 2 in "name" column in "Feature_Vectors_Table" table on "Feature_Store_Features_Vectors_Tab" wizard Then verify "Header" element visibility on "Feature_Vectors_Info_Pane" wizard Then select "Delete" option in action menu on "Feature_Vectors_Info_Pane" wizard - And wait load page Then verify if "Confirm_Popup" popup dialog appears Then "Title" element on "Confirm_Popup" should contains "Delete feature vector?" value Then verify "Cross_Cancel_Button" element visibility on "Confirm_Popup" wizard @@ -2384,13 +2382,11 @@ Feature: Feature Store Page When click on cell with row index 2 in "name" column in "Feature_Vectors_Table" table on "Feature_Store_Features_Vectors_Tab" wizard Then verify "Header" element visibility on "Feature_Vectors_Info_Pane" wizard Then select "Delete" option in action menu on "Feature_Vectors_Info_Pane" wizard - And wait load page When click on "Cancel_Button" element on "Confirm_Popup" wizard And wait load page When click on cell with row index 2 in "name" column in "Feature_Vectors_Table" table on "Feature_Store_Features_Vectors_Tab" wizard Then verify "Header" element visibility on "Feature_Vectors_Info_Pane" wizard Then select "Delete" option in action menu on "Feature_Vectors_Info_Pane" wizard - And wait load page Then verify if "Confirm_Popup" popup dialog appears When click on "Delete_Button" element on "Confirm_Popup" wizard And wait load page @@ -2403,7 +2399,6 @@ Feature: Feature Store Page Then verify that 3 row elements are displayed in "Feature_Vectors_Table" on "Feature_Store_Features_Vectors_Tab" wizard Then click on cell with row index 1 in "expand_btn" column in "Feature_Vectors_Table" table on "Feature_Store_Features_Vectors_Tab" wizard Then select "Delete" option in action menu on "Feature_Store_Features_Vectors_Tab" wizard in "Feature_Vectors_Table" table at row with "7" value in "name_expand_btn" column - And wait load page Then verify if "Confirm_Popup" popup dialog appears When click on "Delete_Button" element on "Confirm_Popup" wizard And wait load page @@ -2414,7 +2409,6 @@ Feature: Feature Store Page Then click on "Notification_Pop_Up_Cross_Close_Button" element on "Notification_Popup" wizard Then verify that 2 row elements are displayed in "Feature_Vectors_Table" on "Feature_Store_Features_Vectors_Tab" wizard Then select "Delete" option in action menu on "Feature_Store_Features_Vectors_Tab" wizard in "Feature_Vectors_Table" table at row with "erann-fv" value in "name" column - And wait load page Then verify if "Confirm_Popup" popup dialog appears When click on "Delete_Button" element on "Confirm_Popup" wizard And wait load page @@ -2428,7 +2422,6 @@ Feature: Feature Store Page Then click on "Clear_Button" element on "FilterBy_Popup" wizard And wait load page Then select "Delete" option in action menu on "Feature_Store_Features_Vectors_Tab" wizard in "Feature_Vectors_Table" table at row with "patient-deterioration" value in "name" column - And wait load page Then verify if "Confirm_Popup" popup dialog appears When click on "Delete_Button" element on "Confirm_Popup" wizard And wait load page diff --git a/tests/features/jobsAndWorkflows.feature b/tests/features/jobsAndWorkflows.feature index 30ead4cb8a..78fd21cbd7 100644 --- a/tests/features/jobsAndWorkflows.feature +++ b/tests/features/jobsAndWorkflows.feature @@ -171,6 +171,61 @@ Feature: Jobs and workflows Then wait for 3 seconds Then verify "Schedule_Monitor_Table" element visibility on "Schedule_Monitor_Tab" wizard + @MLJW + @passive + @smoke + Scenario: MLJW092 - Check filter by Types options on Scheduled tab + Given open url + And wait load page + And click on row root with value "cat-vs-dog-classification" in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + When click on "Scheduled_Stats_Counter" element in "Scheduled_Stats_Container" on "Project" wizard + And wait load page + Then verify "Schedule" tab is active in "Jobs_Tab_Selector" on "Jobs_Monitor_Tab" wizard + Then verify "Table_Name_Filter_Input" element visibility on "Schedule_Monitor_Tab" wizard + Then verify "Date_Picker_Filter_Dropdown" element visibility on "Schedule_Monitor_Tab" wizard + Then verify "Date_Picker_Filter_Dropdown" dropdown on "Schedule_Monitor_Tab" wizard selected option value "Next 24 hours" + Then verify "Table_FilterBy_Button" element visibility on "Schedule_Monitor_Tab" wizard + Then click on "Table_FilterBy_Button" element on "Schedule_Monitor_Tab" wizard + Then verify "Type_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" + When select "Databricks" option in "Type_Filter_Dropdown" filter dropdown on "FilterBy_Popup" wizard + Then click on "Title" element on "FilterBy_Popup" wizard + Then verify "Type_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "Databricks" + When select "Dask" option in "Type_Filter_Dropdown" filter dropdown on "FilterBy_Popup" wizard + Then click on "Title" element on "FilterBy_Popup" wizard + Then verify "Type_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "Dask, Databricks" + When select "Horovod" option in "Type_Filter_Dropdown" filter dropdown on "FilterBy_Popup" wizard + Then click on "Title" element on "FilterBy_Popup" wizard + Then verify "Type_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "3 items selected" + When select "Spark" option in "Type_Filter_Dropdown" filter dropdown on "FilterBy_Popup" wizard + Then click on "Title" element on "FilterBy_Popup" wizard + Then verify "Type_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "4 items selected" + When select "Workflow" option in "Type_Filter_Dropdown" filter dropdown on "FilterBy_Popup" wizard + Then click on "Title" element on "FilterBy_Popup" wizard + Then verify "Type_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "5 items selected" + Then click on "Apply_Button" element on "FilterBy_Popup" wizard + And wait load page + Then verify "Schedule_Monitor_Table" element visibility on "Schedule_Monitor_Tab" wizard + Then click on "Table_FilterBy_Button" element on "Schedule_Monitor_Tab" wizard + Then verify "Type_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "5 items selected" + When select "Job" option in "Type_Filter_Dropdown" filter dropdown on "FilterBy_Popup" wizard + Then click on "Title" element on "FilterBy_Popup" wizard + Then verify "Type_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" + Then click on "Apply_Button" element on "FilterBy_Popup" wizard + And wait load page + Then verify "Schedule_Monitor_Table" element visibility on "Schedule_Monitor_Tab" wizard + Then click on "Table_FilterBy_Button" element on "Schedule_Monitor_Tab" wizard + Then verify "Type_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" + When select "Spark" option in "Type_Filter_Dropdown" filter dropdown on "FilterBy_Popup" wizard + Then click on "Title" element on "FilterBy_Popup" wizard + When select "Horovod" option in "Type_Filter_Dropdown" filter dropdown on "FilterBy_Popup" wizard + Then click on "Title" element on "FilterBy_Popup" wizard + Then verify "Type_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "Spark, Horovod" + Then click on "Apply_Button" element on "FilterBy_Popup" wizard + And wait load page + And verify "No_Data_Message" element visibility on "commonPagesHeader" wizard + Then "No_Data_Message" component on "commonPagesHeader" should be equal "No_Data_Message"."Common_Message_Scheduled_Type" + @MLJW @passive @smoke @@ -209,6 +264,7 @@ Feature: Jobs and workflows Then verify "Jobs_Monitor_Table" element visibility on "Jobs_Monitor_Tab" wizard When pick up "Custom range" from "10/01/2021 00:00" to "11/30/2021 00:00" in "Date_Time_Picker" via "Date_Picker_Filter_Dropdown" on "Jobs_Monitor_Tab" wizard And wait load page + And wait load page Then verify from "10/01/2021 00:00" to "11/30/2021 00:00" filter band in "Custom_Range_Filter_Dropdown" filter dropdown on "Jobs_Monitor_Tab" wizard And wait load page Then verify "Jobs_Monitor_Table" element visibility on "Jobs_Monitor_Tab" wizard @@ -226,13 +282,18 @@ Feature: Jobs and workflows And hover "MLRun_Logo" component on "commonPagesHeader" wizard And wait load page When pick up "Custom range" from "03/31/2014 10:30" to "03/21/2015 19:15" in "Date_Time_Picker" via "Date_Picker_Filter_Dropdown" on "Jobs_Monitor_Tab" wizard + And wait load page Then verify from "03/31/2014 10:30" to "03/21/2015 19:15" filter band in "Custom_Range_Filter_Dropdown" filter dropdown on "Jobs_Monitor_Tab" wizard When pick up "Custom range" from "03/31/2044 10:30" to "03/21/2015 19:15" in "Date_Time_Picker" via "Date_Picker_Filter_Dropdown" on "Jobs_Monitor_Tab" wizard + And wait load page Then verify error message in "Date_Time_Picker" on "Jobs_Monitor_Tab" wizard with value "Date_Time_Picker"."Error_Message" Then click on "Table_Refresh_Button" element on "Jobs_Monitor_Tab" wizard When pick up "Custom range" from "03/31/2030 10:30" to "03/31/2030 10:31" in "Date_Time_Picker" via "Date_Picker_Filter_Dropdown" on "Jobs_Monitor_Tab" wizard + And wait load page Then verify from "03/31/2030 10:30" to "03/31/2030 10:31" filter band in "Custom_Range_Filter_Dropdown" filter dropdown on "Jobs_Monitor_Tab" wizard + And wait load page When pick up "Custom range" from "03/31/2025 10:31" to "03/21/2025 10:30" in "Date_Time_Picker" via "Date_Picker_Filter_Dropdown" on "Jobs_Monitor_Tab" wizard + And wait load page Then verify error message in "Date_Time_Picker" on "Jobs_Monitor_Tab" wizard with value "Date_Time_Picker"."Error_Message" @MLJW @@ -368,6 +429,7 @@ Feature: Jobs and workflows And hover "MLRun_Logo" component on "commonPagesHeader" wizard And wait load page When pick up "Custom range" from "09/03/2021 00:00" to "09/04/2021 00:00" in "Date_Time_Picker" via "Date_Picker_Filter_Dropdown" on "Jobs_Monitor_Tab" wizard + And wait load page Then verify from "09/03/2021 00:00" to "09/04/2021 00:00" filter band in "Custom_Range_Filter_Dropdown" filter dropdown on "Jobs_Monitor_Tab" wizard And wait load page Then click on "Table_FilterBy_Button" element on "Jobs_Monitor_Tab" wizard @@ -442,6 +504,7 @@ Feature: Jobs and workflows And wait load page Then verify from "11/07/2021 17:00" to "11/08/2021 17:00" filter band in "Custom_Range_Filter_Dropdown" filter dropdown on "Jobs_Monitor_Tab" wizard And wait load page + And wait load page Then value in "datetime" column in "Jobs_Monitor_Table" on "Jobs_Monitor_Tab" wizard should be from "11/07/2021 18:00" to "11/08/2021 18:00" @MLJW @@ -461,6 +524,7 @@ Feature: Jobs and workflows When click on cell with row index 1 in "name" column in "Jobs_Monitor_Table" table on "Jobs_Monitor_Tab" wizard And wait load page When pick up "Custom range" from "01/01/2021 00:00" to "01/01/2023 00:00" in "Date_Time_Picker" via "Date_Picker_Filter_Dropdown" on "Jobs_Monitor_Tab" wizard + And wait load page Then verify from "01/01/2021 00:00" to "01/01/2023 00:00" filter band in "Custom_Range_Filter_Dropdown" filter dropdown on "Jobs_Monitor_Tab" wizard And wait load page When click on cell with row index 1 in "name" column in "Jobs_Monitor_Table" table on "Jobs_Monitor_Tab" wizard @@ -613,6 +677,7 @@ Feature: Jobs and workflows @MLJW @passive @smoke + #TODO: add data for verifying iteration filtering of artifacts on the Artifacts tab of the detail run Scenario: MLJW065 - Check all mandatory components in Item infopane on Artifacts tab on Jobs Monitor Page Given open url And wait load page @@ -621,6 +686,7 @@ Feature: Jobs and workflows And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard And click on cell with value "Jobs and workflows" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard And wait load page + And wait load page Then verify "Monitor Jobs" tab is active in "Jobs_Tab_Selector" on "Jobs_Monitor_Tab" wizard When select "Any time" option in "Date_Picker_Filter_Dropdown" filter dropdown on "Jobs_Monitor_Tab" wizard Then click on "Table_FilterBy_Button" element on "Jobs_Monitor_Tab" wizard @@ -628,7 +694,7 @@ Feature: Jobs and workflows Then click on "Title" element on "FilterBy_Popup" wizard Then click on "Apply_Button" element on "FilterBy_Popup" wizard And wait load page - When click on cell with value "trainer-train" in "name" column in "Jobs_Monitor_Table" table on "Jobs_Monitor_Tab" wizard + When click on cell with value "data_clean" in "name" column in "Jobs_Monitor_Table" table on "Jobs_Monitor_Tab" wizard And wait load page When click on cell with row index 1 in "name" column in "Jobs_Monitor_Table" table on "Jobs_Monitor_Tab" wizard And wait load page @@ -640,21 +706,46 @@ Feature: Jobs and workflows Then click on cell with row index 1 in "name" column in "Artifacts_Table" table on "Artifacts_Info_Pane" wizard Then click on "Artifact_Preview_Button" element on "Artifacts_Info_Pane" wizard And wait load page - Then verify "Preview_Row" element visibility on "Artifact_Preview_Popup" wizard - Then verify "Cross_Cancel_Button" element visibility on "Artifact_Preview_Popup" wizard - Then click on "Cross_Cancel_Button" element on "Artifact_Preview_Popup" wizard + Then verify "Preview_Table" element visibility on "Preview_Popup" wizard + Then verify visibility of header column "name" in "Preview_Table" table on "Preview_Popup" wizard + Then check "Name" header value in "name" column in "Preview_Table" table on "Preview_Popup" wizard + Then verify visibility of header column "path" in "Preview_Table" table on "Preview_Popup" wizard + Then check "Path" header value in "path" column in "Preview_Table" table on "Preview_Popup" wizard + Then verify visibility of header column "size" in "Preview_Table" table on "Preview_Popup" wizard + Then check "Size" header value in "size" column in "Preview_Table" table on "Preview_Popup" wizard + Then verify visibility of header column "updated" in "Preview_Table" table on "Preview_Popup" wizard + Then check "Updated" header value in "updated" column in "Preview_Table" table on "Preview_Popup" wizard + Then value in "name" column with "text" in "Preview_Table" on "Preview_Popup" wizard should contains "data_clean" + Then verify "Cross_Cancel_Button" element visibility on "Preview_Popup" wizard + Then verify "Download_Button" element visibility on "Preview_Popup" wizard + Then click on "Download_Button" element on "Preview_Popup" wizard + And wait load page + And wait load page + Then verify "Download_Pop_Up" element visibility on "Downloads_Popup" wizard + And wait load page + Then verify "Download_Pop_Up_Cross_Cancel_Button" element visibility on "Downloads_Popup" wizard + And wait load page + Then verify "Header_Download_Pop_Up" element visibility on "Downloads_Popup" wizard + Then "Header_Download_Pop_Up" element on "Downloads_Popup" should contains "Downloads" value + Then click on "Download_Pop_Up_Cross_Cancel_Button" element on "Downloads_Popup" wizard + Then click on "Cross_Cancel_Button" element on "Preview_Popup" wizard + Then click on "Arrow_Back" element on "Jobs_Monitor_Tab_Info_Pane" wizard + And wait load page + When click on cell with value "trainer-train" in "name" column in "Jobs_Monitor_Table" table on "Jobs_Monitor_Tab" wizard + And wait load page + When click on cell with row index 1 in "name" column in "Jobs_Monitor_Table" table on "Jobs_Monitor_Tab" wizard + And wait load page + And select "Artifacts" tab in "Info_Pane_Tab_Selector" on "Jobs_Monitor_Tab_Info_Pane" wizard And wait load page + And verify "No_Data_Message" element visibility on "commonPagesHeader" wizard + Then "No_Data_Message" component on "commonPagesHeader" should contains "No_Data_Message"."No_Data" Then verify "Iterations_Dropdown" element visibility on "Artifacts_Info_Pane" wizard Then select "1" option in "Iterations_Dropdown" dropdown on "Artifacts_Info_Pane" wizard And wait load page - Then verify "Artifacts_Table" element visibility on "Artifacts_Info_Pane" wizard - Then click on cell with row index 1 in "name" column in "Artifacts_Table" table on "Artifacts_Info_Pane" wizard - Then click on "Artifact_Preview_Button" element on "Artifacts_Info_Pane" wizard - Then verify "Preview_Row" element visibility on "Artifact_Preview_Popup" wizard - Then click on "Cross_Cancel_Button" element on "Artifact_Preview_Popup" wizard - Then select "2" option in "Iterations_Dropdown" dropdown on "Artifacts_Info_Pane" wizard + Then select "5" option in "Iterations_Dropdown" dropdown on "Artifacts_Info_Pane" wizard And wait load page - Then verify "Artifacts_Table" element visibility on "Artifacts_Info_Pane" wizard + And verify "No_Data_Message" element visibility on "commonPagesHeader" wizard + Then "No_Data_Message" component on "commonPagesHeader" should contains "No_Data_Message"."No_Data" @MLJM @smoke @@ -666,6 +757,7 @@ Feature: Jobs and workflows And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard And click on cell with value "Jobs and workflows" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard And wait load page + And wait load page Then verify "Monitor Jobs" tab is active in "Jobs_Tab_Selector" on "Jobs_Monitor_Tab" wizard Then verify "BE_Pagination_Navigate_Prev" element visibility on "Pagination_Info_Pane" wizard Then verify "BE_Pagination_Navigate_Prev" element on "Pagination_Info_Pane" wizard is disabled @@ -743,7 +835,7 @@ Feature: Jobs and workflows Then verify "Title" element visibility on "Modal_Transition_Popup" wizard Then "Title" element on "Modal_Transition_Popup" should contains "aggregate" value Then verify "Data_Status" element visibility on "Modal_Transition_Popup" wizard - Then "Data_Status" element on "Modal_Transition_Popup" should contains "Nov 25, 2021, 05:20:00 PM" value + Then "Data_Status" element on "Modal_Transition_Popup" should contains "Nov 25, 2021, 03:20:00 PM" value Then verify "State_Icon" element visibility on "Modal_Transition_Popup" wizard Then verify "State_Icon" element on "Modal_Transition_Popup" wizard should display hover tooltip "ML_Function_Info_Pane"."Initialized_State" Then verify "Refresh_Button" element visibility on "Modal_Transition_Popup" wizard @@ -954,8 +1046,94 @@ Feature: Jobs and workflows Then verify "Workflows_Monitor_Table" element visibility on "Workflows_Monitor_Tab" wizard When click on cell with row index 1 in "name" column in "Workflows_Monitor_Table" table on "Workflows_Monitor_Tab" wizard And wait load page + Then verify "Terminate_Button" element visibility on "Workflows_Monitor_Tab" wizard + Then "Terminate_Button" element on "Workflows_Monitor_Tab" should contains "Terminate" value + Then verify "Terminate_Button" element on "Workflows_Monitor_Tab" wizard is disabled + Then verify "Toggle_View_Button" element visibility on "Workflows_Monitor_Tab" wizard Then click on "Toggle_View_Button" element on "Workflows_Monitor_Tab" wizard + And wait load page + Then verify "Workflow_List_View_Table" element visibility on "Workflows_Monitor_Tab" wizard + Then verify "Terminate_Button" element visibility on "Workflows_Monitor_Tab" wizard + Then "Terminate_Button" element on "Workflows_Monitor_Tab" should contains "Terminate" value + Then verify "Terminate_Button" element on "Workflows_Monitor_Tab" wizard is disabled + When click on cell with row index 1 in "name" column in "Workflow_List_View_Table" table on "Workflows_Monitor_Tab" wizard + And wait load page + Then verify "Header" element visibility on "Jobs_Monitor_Tab_Info_Pane" wizard + Then verify "Updated" element visibility on "Jobs_Monitor_Tab_Info_Pane" wizard + Then verify "Cross_Close_Button" element visibility on "Jobs_Monitor_Tab_Info_Pane" wizard + Then verify "Info_Pane_Tab_Selector" element visibility on "Jobs_Monitor_Tab_Info_Pane" wizard + Then verify "Info_Pane_Tab_Selector" on "Jobs_Monitor_Tab_Info_Pane" wizard should contains "Jobs_Monitor_Tab_Info_Pane"."Tab_List" + Then verify "Overview" tab is active in "Info_Pane_Tab_Selector" on "Jobs_Monitor_Tab_Info_Pane" wizard + Then verify "Terminate_Button" element visibility on "Workflows_Monitor_Tab" wizard + Then "Terminate_Button" element on "Workflows_Monitor_Tab" should contains "Terminate" value + Then verify "Terminate_Button" element on "Workflows_Monitor_Tab" wizard is disabled + Then select "project" with "stocks-admin" value in breadcrumbs menu + And wait load page + Then verify breadcrumbs "project" label should be equal "stocks-admin" value + When click on cell with row index 1 in "name" column in "Workflows_Monitor_Table" table on "Workflows_Monitor_Tab" wizard + And wait load page + Then verify "Terminate_Button" element visibility on "Workflows_Monitor_Tab" wizard + Then "Terminate_Button" element on "Workflows_Monitor_Tab" should contains "Terminate" value + Then verify "Terminate_Button" element on "Workflows_Monitor_Tab" wizard is enabled + Then click on "Terminate_Button" element on "Workflows_Monitor_Tab" wizard + And wait load page + Then verify if "Confirm_Popup" popup dialog appears + Then "Title" element on "Confirm_Popup" should contains "Terminate workflow" value + Then verify "Cross_Cancel_Button" element visibility on "Confirm_Popup" wizard + Then verify "Confirm_Dialog_Message" element visibility on "Confirm_Popup" wizard + Then "Confirm_Dialog_Message" component on "Confirm_Popup" should be equal "Jobs_And_Workflows"."Terminate_Workflow_Message" + Then verify "Cancel_Button" element visibility on "Confirm_Popup" wizard + Then "Cancel_Button" element on "Confirm_Popup" should contains "Cancel" value + Then verify "Delete_Button" element visibility on "Confirm_Popup" wizard + Then "Delete_Button" element on "Confirm_Popup" should contains "Terminate" value + When click on "Cancel_Button" element on "Confirm_Popup" wizard + Then click on "Terminate_Button" element on "Workflows_Monitor_Tab" wizard + And wait load page + Then verify if "Confirm_Popup" popup dialog appears + Then verify "Cross_Cancel_Button" element visibility on "Confirm_Popup" wizard + When click on "Cross_Cancel_Button" element on "Confirm_Popup" wizard + And wait load page + When click on cell with row index 1 in "name" column in "Workflow_List_View_Table" table on "Workflows_Monitor_Tab" wizard + And wait load page + Then verify "Header" element visibility on "Jobs_Monitor_Tab_Info_Pane" wizard + Then verify "Updated" element visibility on "Jobs_Monitor_Tab_Info_Pane" wizard + Then verify "Cross_Close_Button" element visibility on "Jobs_Monitor_Tab_Info_Pane" wizard + Then verify "Info_Pane_Tab_Selector" element visibility on "Jobs_Monitor_Tab_Info_Pane" wizard + Then verify "Info_Pane_Tab_Selector" on "Jobs_Monitor_Tab_Info_Pane" wizard should contains "ML_Function_Info_Pane"."Tab_List" + Then verify "Overview" tab is active in "Info_Pane_Tab_Selector" on "Jobs_Monitor_Tab_Info_Pane" wizard + Then click on "Terminate_Button" element on "Workflows_Monitor_Tab" wizard + And wait load page + Then verify if "Confirm_Popup" popup dialog appears + Then "Title" element on "Confirm_Popup" should contains "Terminate workflow" value + Then verify "Cross_Cancel_Button" element visibility on "Confirm_Popup" wizard + Then verify "Confirm_Dialog_Message" element visibility on "Confirm_Popup" wizard + Then "Confirm_Dialog_Message" component on "Confirm_Popup" should be equal "Jobs_And_Workflows"."Terminate_Workflow_Message" + Then verify "Cancel_Button" element visibility on "Confirm_Popup" wizard + Then "Cancel_Button" element on "Confirm_Popup" should contains "Cancel" value + Then verify "Delete_Button" element visibility on "Confirm_Popup" wizard + Then "Delete_Button" element on "Confirm_Popup" should contains "Terminate" value + When click on "Cancel_Button" element on "Confirm_Popup" wizard + And wait load page + Then verify "Terminate_Button" element on "Workflows_Monitor_Tab" wizard is enabled + Then click on "Terminate_Button" element on "Workflows_Monitor_Tab" wizard + And wait load page + Then verify if "Confirm_Popup" popup dialog appears + Then verify "Delete_Button" element visibility on "Confirm_Popup" wizard + When click on "Delete_Button" element on "Confirm_Popup" wizard + And wait load page + Then verify if "Notification_Popup" popup dialog appears + Then verify "Notification_Pop_Up" element visibility on "Notification_Popup" wizard + Then "Notification_Pop_Up" component on "Notification_Popup" should contains "Jobs_And_Workflows"."Workflows_Trigger_Termination_Message" + Then verify "Notification_Pop_Up_Cross_Close_Button" element visibility on "Notification_Popup" wizard + Then click on "Notification_Pop_Up_Cross_Close_Button" element on "Notification_Popup" wizard + And wait load page + Then verify "Terminate_Button" element on "Workflows_Monitor_Tab" wizard is disabled + Then click on "Cross_Close_Button" element on "Jobs_Monitor_Tab_Info_Pane" wizard + And wait load page Then verify "Workflow_List_View_Table" element visibility on "Workflows_Monitor_Tab" wizard + Then verify "Terminate_Button" element visibility on "Workflows_Monitor_Tab" wizard + Then "Terminate_Button" element on "Workflows_Monitor_Tab" should contains "Terminate" value + Then verify "Terminate_Button" element on "Workflows_Monitor_Tab" wizard is disabled @MLJW @passive @@ -1175,8 +1353,29 @@ Feature: Jobs and workflows Then click on cell with row index 1 in "name" column in "Artifacts_Table" table on "Artifacts_Info_Pane" wizard Then click on "Artifact_Preview_Button" element on "Artifacts_Info_Pane" wizard And wait load page - Then verify "Preview_Row" element visibility on "Artifact_Preview_Popup" wizard - Then verify "Cross_Cancel_Button" element visibility on "Artifact_Preview_Popup" wizard + Then verify "Preview_Table" element visibility on "Preview_Popup" wizard + Then verify visibility of header column "name" in "Preview_Table" table on "Preview_Popup" wizard + Then check "Name" header value in "name" column in "Preview_Table" table on "Preview_Popup" wizard + Then verify visibility of header column "path" in "Preview_Table" table on "Preview_Popup" wizard + Then check "Path" header value in "path" column in "Preview_Table" table on "Preview_Popup" wizard + Then verify visibility of header column "size" in "Preview_Table" table on "Preview_Popup" wizard + Then check "Size" header value in "size" column in "Preview_Table" table on "Preview_Popup" wizard + Then verify visibility of header column "updated" in "Preview_Table" table on "Preview_Popup" wizard + Then check "Updated" header value in "updated" column in "Preview_Table" table on "Preview_Popup" wizard + Then value in "name" column with "text" in "Preview_Table" on "Preview_Popup" wizard should contains "data_clean" + Then verify "Cross_Cancel_Button" element visibility on "Preview_Popup" wizard + Then verify "Download_Button" element visibility on "Preview_Popup" wizard + Then click on "Download_Button" element on "Preview_Popup" wizard + And wait load page + And wait load page + Then verify "Download_Pop_Up" element visibility on "Downloads_Popup" wizard + And wait load page + Then verify "Download_Pop_Up_Cross_Cancel_Button" element visibility on "Downloads_Popup" wizard + And wait load page + Then verify "Header_Download_Pop_Up" element visibility on "Downloads_Popup" wizard + Then "Header_Download_Pop_Up" element on "Downloads_Popup" should contains "Downloads" value + Then click on "Download_Pop_Up_Cross_Cancel_Button" element on "Downloads_Popup" wizard + Then click on "Cross_Cancel_Button" element on "Preview_Popup" wizard @MLJW @passive @@ -1192,6 +1391,8 @@ Feature: Jobs and workflows And wait load page Then verify "Monitor Jobs" tab is active in "Jobs_Tab_Selector" on "Jobs_Monitor_Tab" wizard When pick up "Custom range" from "09/01/2021 18:00" to "09/03/2021 18:00" in "Date_Time_Picker" via "Date_Picker_Filter_Dropdown" on "Jobs_Monitor_Tab" wizard + And wait load page + And wait load page Then click on "Table_FilterBy_Button" element on "Jobs_Monitor_Tab" wizard Then select "Error" option in "Status_Filter_Dropdown" filter dropdown on "FilterBy_Popup" wizard Then click on "Title" element on "FilterBy_Popup" wizard @@ -1207,6 +1408,7 @@ Feature: Jobs and workflows And wait load page Then verify options in action menu on "Jobs_Monitor_Tab" wizard in "Jobs_Monitor_Table" table with "Running" value in "status" column should contains "Jobs_And_Workflows"."Running_Job_Action_Menu_Options" When pick up "Custom range" from "08/28/2021 18:00" to "09/01/2021 18:00" in "Date_Time_Picker" via "Date_Picker_Filter_Dropdown" on "Jobs_Monitor_Tab" wizard + And wait load page Then click on "Table_FilterBy_Button" element on "Jobs_Monitor_Tab" wizard Then select "Running" option in "Status_Filter_Dropdown" filter dropdown on "FilterBy_Popup" wizard Then click on "Title" element on "FilterBy_Popup" wizard @@ -1241,6 +1443,38 @@ Feature: Jobs and workflows And wait load page Then verify "Monitor Workflows" tab is active in "Jobs_Tab_Selector" on "Jobs_Monitor_Tab" wizard Then verify options in action menu on "Workflows_Monitor_Tab" wizard in "Workflows_Monitor_Table" table with "Completed" value in "status" column should contains "Jobs_And_Workflows"."Workflows_Action_Menu_Options" + Then check that "Terminate" option in action menu on "Workflows_Monitor_Tab" wizard is disabled + Then select "project" with "stocks-admin" value in breadcrumbs menu + And wait load page + Then verify breadcrumbs "project" label should be equal "stocks-admin" value + Then verify options in action menu on "Workflows_Monitor_Tab" wizard in "Workflows_Monitor_Table" table with "Running" value in "status" column should contains "Jobs_And_Workflows"."Workflows_Running_Action_Menu_Options" + Then check that "Terminate" option in action menu on "Workflows_Monitor_Tab" wizard is enabled + Then select "Terminate" option in action menu on "Workflows_Monitor_Tab" wizard in "Workflows_Monitor_Table" table at row with "main 2021-08-30 05-36-35" value in "name" column + Then verify if "Confirm_Popup" popup dialog appears + Then "Title" element on "Confirm_Popup" should contains "Terminate workflow" value + Then verify "Cross_Cancel_Button" element visibility on "Confirm_Popup" wizard + Then verify "Confirm_Dialog_Message" element visibility on "Confirm_Popup" wizard + Then "Confirm_Dialog_Message" component on "Confirm_Popup" should be equal "Jobs_And_Workflows"."Terminate_Workflow_Message" + Then verify "Cancel_Button" element visibility on "Confirm_Popup" wizard + Then "Cancel_Button" element on "Confirm_Popup" should contains "Cancel" value + Then verify "Delete_Button" element visibility on "Confirm_Popup" wizard + Then "Delete_Button" element on "Confirm_Popup" should contains "Terminate" value + When click on "Cancel_Button" element on "Confirm_Popup" wizard + Then select "Terminate" option in action menu on "Workflows_Monitor_Tab" wizard in "Workflows_Monitor_Table" table at row with "main 2021-08-30 05-36-35" value in "name" column + Then verify if "Confirm_Popup" popup dialog appears + Then verify "Cross_Cancel_Button" element visibility on "Confirm_Popup" wizard + When click on "Cross_Cancel_Button" element on "Confirm_Popup" wizard + Then select "Terminate" option in action menu on "Workflows_Monitor_Tab" wizard in "Workflows_Monitor_Table" table at row with "main 2021-08-30 05-36-35" value in "name" column + Then verify if "Confirm_Popup" popup dialog appears + Then verify "Delete_Button" element visibility on "Confirm_Popup" wizard + When click on "Delete_Button" element on "Confirm_Popup" wizard + And wait load page + And wait load page + Then verify if "Notification_Popup" popup dialog appears + Then verify "Notification_Pop_Up" element visibility on "Notification_Popup" wizard + Then "Notification_Pop_Up" component on "Notification_Popup" should contains "Jobs_And_Workflows"."Workflows_Trigger_Termination_Message" + Then verify "Notification_Pop_Up_Cross_Close_Button" element visibility on "Notification_Popup" wizard + Then click on "Notification_Pop_Up_Cross_Close_Button" element on "Notification_Popup" wizard @MLJW @passive @@ -1382,7 +1616,7 @@ Feature: Jobs and workflows Then "Notification_Pop_Up" element on "Notification_Popup" should contains "The batch run was started" value Then verify "Notification_Pop_Up_Cross_Close_Button" element visibility on "Notification_Popup" wizard Then click on "Notification_Pop_Up_Cross_Close_Button" element on "Notification_Popup" wizard - When click on cell with value "test-m_ingest" in "name" column in "Jobs_And_Workflows" table on "Project" wizard + When click on cell with value "test-m_ingest" in "name" column in "Runs_Statistic_Table" table on "Project" wizard And wait load page Then verify "Overview" tab is active in "Info_Pane_Tab_Selector" on "Jobs_Monitor_Tab_Info_Pane" wizard When click on "link" value where option is "Function:" in "Overview_Headers" on "Jobs_Monitor_Tab_Info_Pane" wizard @@ -1454,7 +1688,7 @@ Feature: Jobs and workflows And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard Then click on "Project_Monitoring_Button" element on "commonPagesHeader" wizard And hover "MLRun_Logo" component on "commonPagesHeader" wizard - When click on cell with value "test-m_ingest" in "name" column in "Jobs_And_Workflows" table on "Project" wizard + When click on cell with value "test-m_ingest" in "name" column in "Runs_Statistic_Table" table on "Project" wizard And wait load page When click on "link" value where option is "Function:" in "Overview_Headers" on "Jobs_Monitor_Tab_Info_Pane" wizard And wait load page @@ -1474,6 +1708,7 @@ Feature: Jobs and workflows And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard And click on cell with value "Jobs and workflows" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard And wait load page + And wait load page And select "Schedule" tab in "Jobs_Tab_Selector" on "Jobs_Monitor_Tab" wizard And wait load page Then select "Run now" option in action menu on "Schedule_Monitor_Tab" wizard in "Schedule_Monitor_Table" table at row with "erann-test" value in "name" column @@ -1548,6 +1783,7 @@ Feature: Jobs and workflows And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard And click on cell with value "Jobs and workflows" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard And wait load page + And wait load page And select "Schedule" tab in "Jobs_Tab_Selector" on "Jobs_Monitor_Tab" wizard And wait load page Then click on cell with row index 2 in "name" column in "Schedule_Monitor_Table" table on "Schedule_Monitor_Tab" wizard @@ -1642,7 +1878,7 @@ Feature: Jobs and workflows And wait load page Then verify redirection from "projects/default/jobs/monitor-jobs/aggregate-test/864f4da42773494eb94dce1c8834feb6/resultsINVALID?dates=anyTime&savedParams=P2JlUGFnZT0xJmZlUGFnZT0xJmRhdGVzPWFueVRpbWU%3D&bePage=1&fePage=1" to "projects/default/jobs/monitor-jobs/aggregate-test/864f4da42773494eb94dce1c8834feb6/overview?dates=anyTime&savedParams=P2JlUGFnZT0xJmZlUGFnZT0xJmRhdGVzPWFueVRpbWU%3D&bePage=1&fePage=1" And wait load page - Then verify redirection from "projects/default/jobs/monitor-jobs/aggregate-test/INVALID/overview?dates=anyTime&savedParams=P2JlUGFnZT0xJmZlUGFnZT0xJmRhdGVzPWFueVRpbWU%3D&bePage=1&fePage=1" to "projects/default/jobs/monitor-jobs/aggregate-test/INVALID/overview?dates=anyTime&savedParams=P2JlUGFnZT0xJmZlUGFnZT0xJmRhdGVzPWFueVRpbWU%3D&bePage=1&fePage=1" + Then verify redirection from "projects/default/jobs/monitor-jobs/aggregate-test/INVALID/overview?dates=anyTime&savedParams=P2JlUGFnZT0xJmZlUGFnZT0xJmRhdGVzPWFueVRpbWU%3D&bePage=1&fePage=1" to "projects/default/jobs/monitor-jobs/aggregate-test?dates=anyTime&savedParams=P2JlUGFnZT0xJmZlUGFnZT0xJmRhdGVzPWFueVRpbWU%3D&bePage=1&fePage=1" And wait load page Then verify if "Notification_Popup" popup dialog appears Then verify "Notification_Pop_Up" element visibility on "Notification_Popup" wizard @@ -2116,6 +2352,7 @@ Feature: Jobs and workflows Then select "Hub" tab in "Function_Selection_Tabs" on "Modal_Wizard_Form" wizard And wait load page And click on row root with value "auto-trainer" in "name" column in "Functions_Table" table on "Modal_Wizard_Form" wizard + And wait load page Then "Function_Title" element on "Modal_Wizard_Form" should contains "auto-trainer" value Then verify "Next_Button" element on "Modal_Wizard_Form" wizard is enabled And click on "Step_4_Button" element on "commonPagesHeader" wizard @@ -2440,7 +2677,7 @@ Feature: Jobs and workflows | Secret | | | | yes | Then verify "Volume_Paths_Table_Volume_Name_Input" element in "Resources_Accordion" on "Modal_Wizard_Form" wizard should display hover warning "Input_Hint"."Input_Field_Require" Then verify "Volume_Paths_Table_Path_Input" element in "Resources_Accordion" on "Modal_Wizard_Form" wizard should display hover warning "Input_Hint"."Input_Field_Require" - Then verify "Volume_Paths_Table_Secret_Name_Input" element in "Resources_Accordion" on "Modal_Wizard_Form" wizard should display hover warning "Input_Hint"."Input_Field_Require" + Then verify "Volume_Paths_Table_Secret_Name_Input" in "Resources_Accordion" on "Modal_Wizard_Form" wizard should display options "Input_Hint"."Secret_Name_Rule_Options" Then verify "Volume_Paths_Table_Path_Input" element in "Resources_Accordion" on "Modal_Wizard_Form" wizard should display hint "Input_Hint"."Mount_Path_Hint" When click on "Delete_New_Row_Button" element in "Resources_Accordion" on "Modal_Wizard_Form" wizard When add new volume rows to "Volume_Paths_Table" table in "Resources_Accordion" on "Modal_Wizard_Form" wizard using nontable inputs @@ -2790,6 +3027,7 @@ Feature: Jobs and workflows And wait load page Then value in "status" column with "tooltip" in "Jobs_Monitor_Table" on "Jobs_Monitor_Tab" wizard should contains "Aborting" Then wait for 10 seconds + Then click on "Table_Refresh_Button" element on "Jobs_Monitor_Tab" wizard Then verify "Notification_Pop_Up" element visibility on "Notification_Popup" wizard And wait load page Then "Notification_Pop_Up" element on "Notification_Popup" should contains "Job erann-test (...e19ea57) was aborted" value @@ -2804,8 +3042,7 @@ Feature: Jobs and workflows @MLJW @passive @smoke - # retry action is using KFP API and so this can’t be implemented in the mock - https://iguazio.atlassian.net/browse/ML-9124 - #TODO: need to add check Retry option for error and running status + #TODO: need to add check Retry option for error and running status, add check for retryed job visibility Scenario: MLJW087 - Check Retry option in action menu on Workflows Monitor tab Given open url And wait load page @@ -2823,9 +3060,7 @@ Feature: Jobs and workflows And wait load page Then verify if "Notification_Popup" popup dialog appears Then verify "Notification_Pop_Up" element visibility on "Notification_Popup" wizard - Then "Notification_Pop_Up" component on "Notification_Popup" should contains "Jobs_And_Workflows"."Workflows_Unsuccessful_Run_Message" - Then verify "Retry_Button" element visibility on "Notification_Popup" wizard - Then "Retry_Button" element on "Notification_Popup" should contains "RETRY" value + Then "Notification_Pop_Up" component on "Notification_Popup" should contains "Jobs_And_Workflows"."Workflows_Successful_Run_Message" Then verify "Notification_Pop_Up_Cross_Close_Button" element visibility on "Notification_Popup" wizard Then click on "Notification_Pop_Up_Cross_Close_Button" element on "Notification_Popup" wizard diff --git a/tests/features/jobsMonitoring.feature b/tests/features/jobsMonitoring.feature index d6d63ea0ae..91a5c912db 100644 --- a/tests/features/jobsMonitoring.feature +++ b/tests/features/jobsMonitoring.feature @@ -10,7 +10,7 @@ Feature: Jobs Monitoring Page Then verify "Monitoring_Container" element visibility in "Projects_Monitoring_Container" on "Projects" wizard When click on "Total_Counter_Number" element in "Monitoring_Jobs_Box" on "Projects" wizard And wait load page - Then verify redirection to "projects/*/jobs-monitoring/jobs?state=all&bePage=1&fePage=1" + Then verify redirection to "projects/*/jobs-monitoring/jobs?state=all&dates=past24hours&bePage=1&fePage=1" Then verify breadcrumbs "cross" label should be equal "Jobs monitoring" value Then verify breadcrumbs "projectsPage" label should be equal "Projects" value Then verify "Cross_Jobs_Tab_Selector" on "Jobs_Monitoring_Jobs_Tab" wizard should contains "Jobs_Monitoring"."Tab_List" @@ -33,7 +33,8 @@ Feature: Jobs Monitoring Page Then "Auto_Refresh_Checkbox" element should be unchecked on "Jobs_Monitoring_Jobs_Tab" wizard Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Jobs_Tab" wizard Then "Title" element on "FilterBy_Popup" should contains "Filter by" value - Then verify "Table_Project_Filter_Input" element visibility on "FilterBy_Popup" wizard + Then verify "Project_Name_Filter_Dropdown" element visibility on "FilterBy_Popup" wizard + Then verify "Project_Name_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" Then verify "Status_Filter_Dropdown" element visibility on "FilterBy_Popup" wizard Then verify "Status_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" Then verify "Status_Filter_Dropdown" dropdown element on "FilterBy_Popup" wizard should contains "Dropdown_Options"."Jobs_Status_Filter_Options" @@ -57,7 +58,7 @@ Feature: Jobs Monitoring Page Then verify "Jobs" tab is active in "Cross_Jobs_Tab_Selector" on "Jobs_Monitoring_Jobs_Tab" wizard Then verify "Date_Picker_Filter_Dropdown" dropdown on "Jobs_Monitoring_Workflows_Tab" wizard selected option value "Any time" Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Jobs_Tab" wizard - Then verify "Status_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "3 items selected" + Then verify "Status_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "4 items selected" Then verify "Type_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" And wait load page Then click on "Status_Filter_Element" element on "FilterBy_Popup" wizard @@ -65,6 +66,7 @@ Feature: Jobs Monitoring Page Then "Status_Aborting_Checkbox" element should be checked on "FilterBy_Popup" wizard Then "Status_Jobs_Running_Checkbox" element should be checked on "FilterBy_Popup" wizard Then "Status_Pending_Checkbox" element should be checked on "FilterBy_Popup" wizard + Then "Status_Pending_retry_Checkbox" element should be checked on "FilterBy_Popup" wizard Then verify "Jobs_Table" element visibility on "Jobs_Monitoring_Jobs_Tab" wizard Then click on breadcrumbs "projectsPage" label on "commonPagesHeader" wizard And wait load page @@ -106,14 +108,14 @@ Feature: Jobs Monitoring Page Then "Status_Jobs_Completed_Checkbox" element should be checked on "FilterBy_Popup" wizard Then verify "Jobs_Table" element visibility on "Jobs_Monitoring_Jobs_Tab" wizard And select "crossTab" with "Jobs monitoring" value in breadcrumbs menu - Then verify redirection to "projects/*/jobs-monitoring/jobs?state=completed&bePage=1&fePage=1" + Then verify redirection to "projects/*/jobs-monitoring/jobs?state=completed&dates=past24hours&bePage=1&fePage=1" Then click on breadcrumbs "projectsPage" label on "commonPagesHeader" wizard And wait load page When click on "Total_Counter_Number" element in "Monitoring_Jobs_Box" on "Projects" wizard And wait load page Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Jobs_Tab" wizard - Then verify "Table_Project_Filter_Input" element visibility on "FilterBy_Popup" wizard - Then type value "test" to "Table_Project_Filter_Input" field on "FilterBy_Popup" wizard + Then verify "Project_Name_Filter_Dropdown" element visibility on "FilterBy_Popup" wizard + When select "churn-project-admin" option in "Project_Name_Filter_Dropdown" filter dropdown on "FilterBy_Popup" wizard And wait load page Then click on "Apply_Button" element on "FilterBy_Popup" wizard And wait load page @@ -126,7 +128,7 @@ Feature: Jobs Monitoring Page And wait load page When click on "Total_Counter_Number" element in "Monitoring_Jobs_Box" on "Projects" wizard And wait load page - Then verify redirection to "projects/*/jobs-monitoring/jobs?state=all&bePage=1&fePage=1" + Then verify redirection to "projects/*/jobs-monitoring/jobs?state=all&dates=past24hours&bePage=1&fePage=1" Then verify "Date_Picker_Filter_Dropdown" element visibility on "Jobs_Monitoring_Jobs_Tab" wizard When select "Any time" option in "Date_Picker_Filter_Dropdown" filter dropdown on "Jobs_Monitoring_Jobs_Tab" wizard And wait load page @@ -137,10 +139,13 @@ Feature: Jobs Monitoring Page And wait load page Then value in "name" column with "text" in "Jobs_Table" on "Jobs_Monitoring_Jobs_Tab" wizard should contains "test" And select "Scheduled" tab in "Cross_Jobs_Tab_Selector" on "Jobs_Monitoring_Scheduled_Tab" wizard + And wait load page And select "Jobs" tab in "Cross_Jobs_Tab_Selector" on "Jobs_Monitoring_Jobs_Tab" wizard + And wait load page Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Jobs_Tab" wizard - Then verify "Table_Project_Filter_Input" element visibility on "FilterBy_Popup" wizard - Then type value "cat-vs-dog-classification" to "Table_Project_Filter_Input" field on "FilterBy_Popup" wizard + Then verify "Project_Name_Filter_Dropdown" element visibility on "FilterBy_Popup" wizard + Then verify "Project_Name_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" + When select "cat-vs-dog-classification" option in "Project_Name_Filter_Dropdown" filter dropdown on "FilterBy_Popup" wizard Then click on "Apply_Button" element on "FilterBy_Popup" wizard And wait load page Then value in "project_name" column with "text" in "Jobs_Table" on "Jobs_Monitoring_Jobs_Tab" wizard should contains "cat-vs-dog-classification" @@ -186,7 +191,7 @@ Feature: Jobs Monitoring Page And wait load page When click on "Total_Counter_Number" element in "Monitoring_Jobs_Box" on "Projects" wizard And wait load page - Then verify redirection to "projects/*/jobs-monitoring/jobs?state=all&bePage=1&fePage=1" + Then verify redirection to "projects/*/jobs-monitoring/jobs?state=all&dates=past24hours&bePage=1&fePage=1" Then verify "BE_Pagination_Navigate_Prev" element visibility on "Pagination_Info_Pane" wizard Then verify "BE_Pagination_Navigate_Prev" element on "Pagination_Info_Pane" wizard is disabled Then verify "BE_Pagination_Navigate_Next" element visibility on "Pagination_Info_Pane" wizard @@ -249,7 +254,7 @@ Feature: Jobs Monitoring Page And wait load page When click on "Total_Counter_Number" element in "Monitoring_Jobs_Box" on "Projects" wizard And wait load page - Then verify redirection to "projects/*/jobs-monitoring/jobs?state=all&bePage=1&fePage=1" + Then verify redirection to "projects/*/jobs-monitoring/jobs?state=all&dates=past24hours&bePage=1&fePage=1" Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Jobs_Tab" wizard Then verify "Status_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" Then verify "Type_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" @@ -294,6 +299,13 @@ Feature: Jobs Monitoring Page And wait load page Then verify "Jobs_Table" element visibility on "Jobs_Monitoring_Jobs_Tab" wizard Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Jobs_Tab" wizard + Then verify "Status_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "6 items selected" + When select "Pending retry" option in "Status_Filter_Dropdown" filter dropdown on "FilterBy_Popup" wizard + Then click on "Title" element on "FilterBy_Popup" wizard + Then click on "Apply_Button" element on "FilterBy_Popup" wizard + And wait load page + Then verify "Jobs_Table" element visibility on "Jobs_Monitoring_Jobs_Tab" wizard + Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Jobs_Tab" wizard Then verify "Status_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Jobs_Tab" wizard Then select "View YAML" option in action menu on "Jobs_Monitoring_Jobs_Tab" wizard in "Jobs_Table" table at row with "test" value in "name" column @@ -308,7 +320,7 @@ Feature: Jobs Monitoring Page And wait load page When click on "Total_Counter_Number" element in "Monitoring_Jobs_Box" on "Projects" wizard And wait load page - Then verify redirection to "projects/*/jobs-monitoring/jobs?state=all&bePage=1&fePage=1" + Then verify redirection to "projects/*/jobs-monitoring/jobs?state=all&dates=past24hours&bePage=1&fePage=1" Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Jobs_Tab" wizard Then verify "Status_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" Then verify "Type_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" @@ -373,7 +385,7 @@ Feature: Jobs Monitoring Page And wait load page When click on "Total_Counter_Number" element in "Monitoring_Jobs_Box" on "Projects" wizard And wait load page - Then verify redirection to "projects/*/jobs-monitoring/jobs?state=all&bePage=1&fePage=1" + Then verify redirection to "projects/*/jobs-monitoring/jobs?state=all&dates=past24hours&bePage=1&fePage=1" Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Jobs_Tab" wizard Then verify "Status_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" Then verify "Type_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" @@ -509,6 +521,26 @@ Feature: Jobs Monitoring Page And wait load page Then verify "Notification_Pop_Up_Cross_Close_Button" element visibility on "Notification_Popup" wizard Then click on "Notification_Pop_Up_Cross_Close_Button" element on "Notification_Popup" wizard + Then select "Delete all runs" option in action menu on "Jobs_Monitoring_Jobs_Tab" wizard in "Jobs_Table" table at row with "fesf" value in "name" column + And wait load page + Then verify if "Confirm_Popup" popup dialog appears + Then "Confirm_Dialog_Message" component on "Confirm_Popup" should be equal "Jobs_And_Workflows"."Delete_All_Runs_Message" + Then "Title" element on "Confirm_Popup" should contains "Delete job?" value + Then verify "Cross_Cancel_Button" element visibility on "Confirm_Popup" wizard + Then verify "Cancel_Button" element visibility on "Confirm_Popup" wizard + Then "Cancel_Button" element on "Confirm_Popup" should contains "Cancel" value + Then verify "Cancel_Button" element on "Confirm_Popup" wizard is enabled + Then verify "Delete_Button" element visibility on "Confirm_Popup" wizard + Then "Delete_Button" element on "Confirm_Popup" should contains "Delete" value + When click on "Delete_Button" element on "Confirm_Popup" wizard + And wait load page + And wait load page + Then verify "Notification_Pop_Up" element visibility on "Notification_Popup" wizard + And wait load page + Then "Notification_Pop_Up" element on "Notification_Popup" should contains "Job is successfully deleted" value + And wait load page + Then verify "Notification_Pop_Up_Cross_Close_Button" element visibility on "Notification_Popup" wizard + Then click on "Notification_Pop_Up_Cross_Close_Button" element on "Notification_Popup" wizard And verify "No_Data_Message" element visibility on "commonPagesHeader" wizard Then "No_Data_Message" component on "commonPagesHeader" should be equal "No_Data_Message"."Common_Message_Monitor_Jobs_Name" @@ -522,7 +554,7 @@ Feature: Jobs Monitoring Page Then verify "Total_Counter_Number" element visibility in "Monitoring_Workflows_Box" on "Projects" wizard When click on "Total_Counter_Number" element in "Monitoring_Workflows_Box" on "Projects" wizard And wait load page - Then verify redirection to "projects/*/jobs-monitoring/workflows?state=all" + Then verify redirection to "projects/*/jobs-monitoring/workflows?state=all&dates=past24hours" Then verify breadcrumbs "cross" label should be equal "Jobs monitoring" value Then verify breadcrumbs "projectsPage" label should be equal "Projects" value Then verify "Cross_Jobs_Tab_Selector" on "Jobs_Monitoring_Workflows_Tab" wizard should contains "Jobs_Monitoring"."Tab_List" @@ -539,7 +571,8 @@ Feature: Jobs Monitoring Page Then verify "Workflows_Table" element visibility on "Jobs_Monitoring_Workflows_Tab" wizard Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Workflows_Tab" wizard Then "Title" element on "FilterBy_Popup" should contains "Filter by" value - Then verify "Table_Project_Filter_Input" element visibility on "FilterBy_Popup" wizard + Then verify "Project_Name_Filter_Dropdown" element visibility on "FilterBy_Popup" wizard + Then verify "Project_Name_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" Then verify "Status_Filter_Dropdown" element visibility on "FilterBy_Popup" wizard Then verify "Status_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" Then verify "Status_Filter_Dropdown" dropdown element on "FilterBy_Popup" wizard should contains "Dropdown_Options"."Workflows_Status_Filter_Options" @@ -553,13 +586,13 @@ Feature: Jobs Monitoring Page Then verify "Apply_Button" element on "FilterBy_Popup" wizard is disabled Then navigate back And wait load page - Then verify "Counter_Running_Status_Number" element visibility in "Monitoring_Workflows_Box" on "Projects" wizard - When click on "Counter_Running_Status_Number" element in "Monitoring_Workflows_Box" on "Projects" wizard + Then verify "Counter_In_Process_Status_Number" element visibility in "Monitoring_Workflows_Box" on "Projects" wizard + When click on "Counter_In_Process_Status_Number" element in "Monitoring_Workflows_Box" on "Projects" wizard And wait load page Then verify "Workflows" tab is active in "Cross_Jobs_Tab_Selector" on "Jobs_Monitoring_Workflows_Tab" wizard Then verify "Date_Picker_Filter_Dropdown" dropdown on "Jobs_Monitoring_Workflows_Tab" wizard selected option value "Any time" Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Workflows_Tab" wizard - Then verify "Status_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "Running" + Then verify "Status_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "Running, Terminating" Then click on "Status_Filter_Element" element on "FilterBy_Popup" wizard Then "Status_All_Checkbox" element should be unchecked on "FilterBy_Popup" wizard Then "Status_Workflows_Running_Checkbox" element should be checked on "FilterBy_Popup" wizard @@ -603,8 +636,8 @@ Feature: Jobs Monitoring Page When click on "Total_Counter_Number" element in "Monitoring_Workflows_Box" on "Projects" wizard And wait load page Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Workflows_Tab" wizard - Then verify "Table_Project_Filter_Input" element visibility on "FilterBy_Popup" wizard - Then type value "test" to "Table_Project_Filter_Input" field on "FilterBy_Popup" wizard + Then verify "Project_Name_Filter_Dropdown" element visibility on "FilterBy_Popup" wizard + When select "auto-generated-data" option in "Project_Name_Filter_Dropdown" filter dropdown on "FilterBy_Popup" wizard And wait load page Then click on "Apply_Button" element on "FilterBy_Popup" wizard And wait load page @@ -622,7 +655,7 @@ Feature: Jobs Monitoring Page And wait load page When click on "Total_Counter_Number" element in "Monitoring_Workflows_Box" on "Projects" wizard And wait load page - Then verify redirection to "projects/*/jobs-monitoring/workflows?state=all" + Then verify redirection to "projects/*/jobs-monitoring/workflows?state=all&dates=past24hours" Then verify "Date_Picker_Filter_Dropdown" element visibility on "Jobs_Monitoring_Workflows_Tab" wizard When select "Any time" option in "Date_Picker_Filter_Dropdown" filter dropdown on "Jobs_Monitoring_Workflows_Tab" wizard And wait load page @@ -641,8 +674,9 @@ Feature: Jobs Monitoring Page And select "Scheduled" tab in "Cross_Jobs_Tab_Selector" on "Jobs_Monitoring_Scheduled_Tab" wizard And select "Workflows" tab in "Cross_Jobs_Tab_Selector" on "Jobs_Monitoring_Workflows_Tab" wizard Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Workflows_Tab" wizard - Then verify "Table_Project_Filter_Input" element visibility on "FilterBy_Popup" wizard - Then type value "cat-vs-dog-classification" to "Table_Project_Filter_Input" field on "FilterBy_Popup" wizard + Then verify "Project_Name_Filter_Dropdown" element visibility on "FilterBy_Popup" wizard + Then verify "Project_Name_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" + When select "cat-vs-dog-classification" option in "Project_Name_Filter_Dropdown" filter dropdown on "FilterBy_Popup" wizard Then click on "Apply_Button" element on "FilterBy_Popup" wizard And wait load page Then value in "project_name" column with "text" in "Workflows_Table" on "Jobs_Monitoring_Workflows_Tab" wizard should contains "cat-vs-dog-classification" @@ -677,8 +711,248 @@ Feature: Jobs Monitoring Page Then verify "Workflows_Table" element visibility on "Jobs_Monitoring_Workflows_Tab" wizard Then verify that 3 row elements are displayed in "Workflows_Table" on "Jobs_Monitoring_Workflows_Tab" wizard When pick up "Custom range" from "09/03/2024 00:00" to "09/04/2024 00:00" in "Date_Time_Picker" via "Date_Picker_Filter_Dropdown" on "Jobs_Monitoring_Workflows_Tab" wizard + And wait load page Then verify from "09/03/2024 00:00" to "09/04/2024 00:00" filter band in "Custom_Range_Filter_Dropdown" filter dropdown on "Jobs_Monitoring_Workflows_Tab" wizard And wait load page + + @MLJM + @smoke + Scenario: MLJM015 - Check the Terminate functionality on Workflows tab of Jobs monitoring page with running status on main table list + Given open url + And wait load page + When click on "Total_Counter_Number" element in "Monitoring_Workflows_Box" on "Projects" wizard + And wait load page + Then verify redirection to "projects/*/jobs-monitoring/workflows?state=all&dates=past24hours" + Then verify "Date_Picker_Filter_Dropdown" element visibility on "Jobs_Monitoring_Workflows_Tab" wizard + When select "Any time" option in "Date_Picker_Filter_Dropdown" filter dropdown on "Jobs_Monitoring_Workflows_Tab" wizard + And wait load page + Then verify "Date_Picker_Filter_Dropdown" dropdown on "Jobs_Monitoring_Workflows_Tab" wizard selected option value "Any time" + Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Workflows_Tab" wizard + Then verify "Project_Name_Filter_Dropdown" element visibility on "FilterBy_Popup" wizard + Then verify "Project_Name_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" + When select "stocks-admin" option in "Project_Name_Filter_Dropdown" filter dropdown on "FilterBy_Popup" wizard + Then click on "Apply_Button" element on "FilterBy_Popup" wizard + And wait load page + Then verify options in action menu on "Jobs_Monitoring_Workflows_Tab" wizard in "Workflows_Table" table with "Running" value in "status" column should contains "Jobs_And_Workflows"."Workflows_Running_Action_Menu_Options" + Then check that "Terminate" option in action menu on "Jobs_Monitoring_Workflows_Tab" wizard is enabled + And wait load page + Then select "Terminate" option in action menu on "Jobs_Monitoring_Workflows_Tab" wizard in "Workflows_Table" table at row with "main 2021-08-30 05-36-35" value in "name" column + Then verify if "Confirm_Popup" popup dialog appears + Then "Title" element on "Confirm_Popup" should contains "Terminate workflow" value + Then verify "Cross_Cancel_Button" element visibility on "Confirm_Popup" wizard + Then verify "Confirm_Dialog_Message" element visibility on "Confirm_Popup" wizard + Then "Confirm_Dialog_Message" component on "Confirm_Popup" should be equal "Jobs_And_Workflows"."Terminate_Workflow_Message" + Then verify "Cancel_Button" element visibility on "Confirm_Popup" wizard + Then "Cancel_Button" element on "Confirm_Popup" should contains "Cancel" value + Then verify "Delete_Button" element visibility on "Confirm_Popup" wizard + Then "Delete_Button" element on "Confirm_Popup" should contains "Terminate" value + When click on "Cancel_Button" element on "Confirm_Popup" wizard + Then select "Terminate" option in action menu on "Jobs_Monitoring_Workflows_Tab" wizard in "Workflows_Table" table at row with "main 2021-08-30 05-36-35" value in "name" column + Then verify if "Confirm_Popup" popup dialog appears + Then verify "Cross_Cancel_Button" element visibility on "Confirm_Popup" wizard + When click on "Cross_Cancel_Button" element on "Confirm_Popup" wizard + Then select "Terminate" option in action menu on "Jobs_Monitoring_Workflows_Tab" wizard in "Workflows_Table" table at row with "main 2021-08-30 05-36-35" value in "name" column + Then verify if "Confirm_Popup" popup dialog appears + Then verify "Delete_Button" element visibility on "Confirm_Popup" wizard + When click on "Cancel_Button" element on "Confirm_Popup" wizard + Then verify that in action menu on "Jobs_Monitoring_Workflows_Tab" wizard in "Workflows_Table" table with "main 2021-08-30 05-36-35" value in "name" column "Terminate" option is enabled + And wait load page + + @MLJM + @smoke + Scenario: MLJM018 - Check the Terminate functionality on Workflows tab of Jobs monitoring page with running status on workflow runs graph view + Given open url + And wait load page + When click on "Total_Counter_Number" element in "Monitoring_Workflows_Box" on "Projects" wizard + And wait load page + Then verify redirection to "projects/*/jobs-monitoring/workflows?state=all&dates=past24hours" + Then verify "Date_Picker_Filter_Dropdown" element visibility on "Jobs_Monitoring_Workflows_Tab" wizard + When select "Any time" option in "Date_Picker_Filter_Dropdown" filter dropdown on "Jobs_Monitoring_Workflows_Tab" wizard + And wait load page + Then verify "Date_Picker_Filter_Dropdown" dropdown on "Jobs_Monitoring_Workflows_Tab" wizard selected option value "Any time" + Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Workflows_Tab" wizard + Then verify "Project_Name_Filter_Dropdown" element visibility on "FilterBy_Popup" wizard + Then verify "Project_Name_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" + When select "stocks-admin" option in "Project_Name_Filter_Dropdown" filter dropdown on "FilterBy_Popup" wizard + Then click on "Apply_Button" element on "FilterBy_Popup" wizard + And wait load page + Then verify options in action menu on "Jobs_Monitoring_Workflows_Tab" wizard in "Workflows_Table" table with "Running" value in "status" column should contains "Jobs_And_Workflows"."Workflows_Running_Action_Menu_Options" + Then check that "Terminate" option in action menu on "Jobs_Monitoring_Workflows_Tab" wizard is enabled + And wait load page + When click on cell with row index 1 in "name" column in "Workflows_Table" table on "Jobs_Monitoring_Workflows_Tab" wizard + And wait load page + Then verify "Terminate_Button" element visibility on "Jobs_Monitoring_Workflows_Tab" wizard + Then "Terminate_Button" element on "Jobs_Monitoring_Workflows_Tab" should contains "Terminate" value + Then verify "Terminate_Button" element on "Jobs_Monitoring_Workflows_Tab" wizard is enabled + Then click on "Terminate_Button" element on "Jobs_Monitoring_Workflows_Tab" wizard + Then verify if "Confirm_Popup" popup dialog appears + Then verify "Cancel_Button" element visibility on "Confirm_Popup" wizard + When click on "Cancel_Button" element on "Confirm_Popup" wizard + Then click on "Terminate_Button" element on "Jobs_Monitoring_Workflows_Tab" wizard + Then verify if "Confirm_Popup" popup dialog appears + Then verify "Cross_Cancel_Button" element visibility on "Confirm_Popup" wizard + When click on "Cross_Cancel_Button" element on "Confirm_Popup" wizard + Then click on "Terminate_Button" element on "Jobs_Monitoring_Workflows_Tab" wizard + Then verify if "Confirm_Popup" popup dialog appears + Then verify "Delete_Button" element visibility on "Confirm_Popup" wizard + When click on "Cancel_Button" element on "Confirm_Popup" wizard + Then verify "Terminate_Button" element on "Jobs_Monitoring_Workflows_Tab" wizard is enabled + + @MLJM + @smoke + Scenario: MLJM019 - Check the Terminate functionality on Workflows tab of Jobs monitoring page with running status on workflow runs list view + Given open url + And wait load page + When click on "Total_Counter_Number" element in "Monitoring_Workflows_Box" on "Projects" wizard + And wait load page + Then verify redirection to "projects/*/jobs-monitoring/workflows?state=all&dates=past24hours" + Then verify "Date_Picker_Filter_Dropdown" element visibility on "Jobs_Monitoring_Workflows_Tab" wizard + When select "Any time" option in "Date_Picker_Filter_Dropdown" filter dropdown on "Jobs_Monitoring_Workflows_Tab" wizard + And wait load page + Then verify "Date_Picker_Filter_Dropdown" dropdown on "Jobs_Monitoring_Workflows_Tab" wizard selected option value "Any time" + Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Workflows_Tab" wizard + Then verify "Project_Name_Filter_Dropdown" element visibility on "FilterBy_Popup" wizard + Then verify "Project_Name_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" + When select "stocks-admin" option in "Project_Name_Filter_Dropdown" filter dropdown on "FilterBy_Popup" wizard + Then click on "Apply_Button" element on "FilterBy_Popup" wizard + And wait load page + Then verify options in action menu on "Jobs_Monitoring_Workflows_Tab" wizard in "Workflows_Table" table with "Running" value in "status" column should contains "Jobs_And_Workflows"."Workflows_Running_Action_Menu_Options" + Then check that "Terminate" option in action menu on "Jobs_Monitoring_Workflows_Tab" wizard is enabled + And wait load page + When click on cell with row index 1 in "name" column in "Workflows_Table" table on "Jobs_Monitoring_Workflows_Tab" wizard + And wait load page + Then verify "Terminate_Button" element visibility on "Jobs_Monitoring_Workflows_Tab" wizard + Then "Terminate_Button" element on "Jobs_Monitoring_Workflows_Tab" should contains "Terminate" value + Then verify "Terminate_Button" element on "Jobs_Monitoring_Workflows_Tab" wizard is enabled + Then verify "Toggle_View_Button" element visibility on "Jobs_Monitoring_Workflows_Tab" wizard + Then click on "Toggle_View_Button" element on "Jobs_Monitoring_Workflows_Tab" wizard + And wait load page + Then verify "Workflow_List_View_Table" element visibility on "Jobs_Monitoring_Workflows_Tab" wizard + Then verify "Terminate_Button" element visibility on "Jobs_Monitoring_Workflows_Tab" wizard + Then "Terminate_Button" element on "Jobs_Monitoring_Workflows_Tab" should contains "Terminate" value + Then verify "Terminate_Button" element on "Jobs_Monitoring_Workflows_Tab" wizard is enabled + Then click on "Terminate_Button" element on "Jobs_Monitoring_Workflows_Tab" wizard + Then verify if "Confirm_Popup" popup dialog appears + Then verify "Cancel_Button" element visibility on "Confirm_Popup" wizard + When click on "Cancel_Button" element on "Confirm_Popup" wizard + Then click on "Terminate_Button" element on "Jobs_Monitoring_Workflows_Tab" wizard + Then verify if "Confirm_Popup" popup dialog appears + Then verify "Cross_Cancel_Button" element visibility on "Confirm_Popup" wizard + When click on "Cross_Cancel_Button" element on "Confirm_Popup" wizard + Then click on "Terminate_Button" element on "Jobs_Monitoring_Workflows_Tab" wizard + Then verify if "Confirm_Popup" popup dialog appears + Then verify "Delete_Button" element visibility on "Confirm_Popup" wizard + When click on "Cancel_Button" element on "Confirm_Popup" wizard + Then verify "Terminate_Button" element on "Jobs_Monitoring_Workflows_Tab" wizard is enabled + + @MLJM + @smoke + Scenario: MLJM020 - Check the Terminate functionality on Workflows tab of Jobs monitoring page with running status with run detail pane + Given open url + And wait load page + When click on "Total_Counter_Number" element in "Monitoring_Workflows_Box" on "Projects" wizard + And wait load page + Then verify redirection to "projects/*/jobs-monitoring/workflows?state=all&dates=past24hours" + Then verify "Date_Picker_Filter_Dropdown" element visibility on "Jobs_Monitoring_Workflows_Tab" wizard + When select "Any time" option in "Date_Picker_Filter_Dropdown" filter dropdown on "Jobs_Monitoring_Workflows_Tab" wizard + And wait load page + Then verify "Date_Picker_Filter_Dropdown" dropdown on "Jobs_Monitoring_Workflows_Tab" wizard selected option value "Any time" + Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Workflows_Tab" wizard + Then verify "Project_Name_Filter_Dropdown" element visibility on "FilterBy_Popup" wizard + Then verify "Project_Name_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" + When select "stocks-admin" option in "Project_Name_Filter_Dropdown" filter dropdown on "FilterBy_Popup" wizard + Then click on "Apply_Button" element on "FilterBy_Popup" wizard + And wait load page + Then verify options in action menu on "Jobs_Monitoring_Workflows_Tab" wizard in "Workflows_Table" table with "Running" value in "status" column should contains "Jobs_And_Workflows"."Workflows_Running_Action_Menu_Options" + Then check that "Terminate" option in action menu on "Jobs_Monitoring_Workflows_Tab" wizard is enabled + And wait load page + When click on cell with row index 1 in "name" column in "Workflows_Table" table on "Jobs_Monitoring_Workflows_Tab" wizard + And wait load page + Then click on "Toggle_View_Button" element on "Jobs_Monitoring_Workflows_Tab" wizard + And wait load page + Then verify "Workflow_List_View_Table" element visibility on "Jobs_Monitoring_Workflows_Tab" wizard + When click on cell with row index 1 in "name" column in "Workflow_List_View_Table" table on "Jobs_Monitoring_Workflows_Tab" wizard + And wait load page + Then verify "Header" element visibility on "Jobs_Monitor_Tab_Info_Pane" wizard + Then verify "Updated" element visibility on "Jobs_Monitor_Tab_Info_Pane" wizard + Then verify "Cross_Close_Button" element visibility on "Jobs_Monitor_Tab_Info_Pane" wizard + Then verify "Info_Pane_Tab_Selector" element visibility on "Jobs_Monitor_Tab_Info_Pane" wizard + Then verify "Info_Pane_Tab_Selector" on "Jobs_Monitor_Tab_Info_Pane" wizard should contains "ML_Function_Info_Pane"."Tab_List" + Then verify "Overview" tab is active in "Info_Pane_Tab_Selector" on "Jobs_Monitor_Tab_Info_Pane" wizard + Then verify "Terminate_Button" element visibility on "Jobs_Monitoring_Workflows_Tab" wizard + Then "Terminate_Button" element on "Jobs_Monitoring_Workflows_Tab" should contains "Terminate" value + Then verify "Terminate_Button" element on "Jobs_Monitoring_Workflows_Tab" wizard is enabled + Then click on "Terminate_Button" element on "Jobs_Monitoring_Workflows_Tab" wizard + Then verify if "Confirm_Popup" popup dialog appears + Then verify "Cancel_Button" element visibility on "Confirm_Popup" wizard + When click on "Cancel_Button" element on "Confirm_Popup" wizard + Then click on "Terminate_Button" element on "Jobs_Monitoring_Workflows_Tab" wizard + Then verify if "Confirm_Popup" popup dialog appears + Then verify "Cross_Cancel_Button" element visibility on "Confirm_Popup" wizard + When click on "Cross_Cancel_Button" element on "Confirm_Popup" wizard + Then click on "Terminate_Button" element on "Jobs_Monitoring_Workflows_Tab" wizard + Then verify if "Confirm_Popup" popup dialog appears + Then verify "Delete_Button" element visibility on "Confirm_Popup" wizard + When click on "Delete_Button" element on "Confirm_Popup" wizard + And wait load page + Then verify if "Notification_Popup" popup dialog appears + Then verify "Notification_Pop_Up" element visibility on "Notification_Popup" wizard + Then "Notification_Pop_Up" component on "Notification_Popup" should contains "Jobs_And_Workflows"."Workflows_Trigger_Termination_Message" + Then verify "Notification_Pop_Up_Cross_Close_Button" element visibility on "Notification_Popup" wizard + Then click on "Notification_Pop_Up_Cross_Close_Button" element on "Notification_Popup" wizard + Then verify "Terminate_Button" element on "Jobs_Monitoring_Workflows_Tab" wizard is disabled + Then click on "Cross_Close_Button" element on "Jobs_Monitor_Tab_Info_Pane" wizard + And wait load page + Then verify "Terminate_Button" element on "Jobs_Monitoring_Workflows_Tab" wizard is disabled + Then click on "Arrow_Back" element on "Workflows_Monitor_Tab_Info_Pane" wizard + And wait load page + Then verify that in action menu on "Jobs_Monitoring_Workflows_Tab" wizard in "Workflows_Table" table with "main 2021-08-30 05-36-35" value in "name" column "Terminate" option is disabled + And wait load page + + @MLJM + @smoke + Scenario: MLJM016 - Check the Terminate functionality on Workflows tab of Jobs monitoring page with compleated status + Given open url + And wait load page + When click on "Total_Counter_Number" element in "Monitoring_Workflows_Box" on "Projects" wizard + And wait load page + Then verify redirection to "projects/*/jobs-monitoring/workflows?state=all&dates=past24hours" + Then verify "Date_Picker_Filter_Dropdown" element visibility on "Jobs_Monitoring_Workflows_Tab" wizard + When select "Any time" option in "Date_Picker_Filter_Dropdown" filter dropdown on "Jobs_Monitoring_Workflows_Tab" wizard + And wait load page + Then verify "Date_Picker_Filter_Dropdown" dropdown on "Jobs_Monitoring_Workflows_Tab" wizard selected option value "Any time" + Then verify "Workflows" tab is active in "Cross_Jobs_Tab_Selector" on "Jobs_Monitoring_Workflows_Tab" wizard + Then verify options in action menu on "Jobs_Monitoring_Workflows_Tab" wizard in "Workflows_Table" table with "Completed" value in "status" column should contains "Jobs_And_Workflows"."Workflows_Action_Menu_Options" + Then check that "Terminate" option in action menu on "Jobs_Monitoring_Workflows_Tab" wizard is disabled + Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Workflows_Tab" wizard + Then verify "Project_Name_Filter_Dropdown" element visibility on "FilterBy_Popup" wizard + Then verify "Project_Name_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" + When select "cat-vs-dog-classification" option in "Project_Name_Filter_Dropdown" filter dropdown on "FilterBy_Popup" wizard + Then click on "Apply_Button" element on "FilterBy_Popup" wizard + And wait load page + When click on cell with row index 1 in "name" column in "Workflows_Table" table on "Jobs_Monitoring_Workflows_Tab" wizard + And wait load page + Then verify "Terminate_Button" element visibility on "Jobs_Monitoring_Workflows_Tab" wizard + Then "Terminate_Button" element on "Jobs_Monitoring_Workflows_Tab" should contains "Terminate" value + Then verify "Terminate_Button" element on "Jobs_Monitoring_Workflows_Tab" wizard is disabled + Then verify "Toggle_View_Button" element visibility on "Jobs_Monitoring_Workflows_Tab" wizard + Then click on "Toggle_View_Button" element on "Jobs_Monitoring_Workflows_Tab" wizard + And wait load page + Then verify "Workflow_List_View_Table" element visibility on "Jobs_Monitoring_Workflows_Tab" wizard + Then verify "Terminate_Button" element visibility on "Jobs_Monitoring_Workflows_Tab" wizard + Then "Terminate_Button" element on "Jobs_Monitoring_Workflows_Tab" should contains "Terminate" value + Then verify "Terminate_Button" element on "Jobs_Monitoring_Workflows_Tab" wizard is disabled + When click on cell with row index 1 in "name" column in "Workflows_Table" table on "Jobs_Monitoring_Workflows_Tab" wizard + And wait load page + Then verify "Header" element visibility on "Jobs_Monitor_Tab_Info_Pane" wizard + Then verify "Updated" element visibility on "Jobs_Monitor_Tab_Info_Pane" wizard + Then verify "Cross_Close_Button" element visibility on "Jobs_Monitor_Tab_Info_Pane" wizard + Then verify "Info_Pane_Tab_Selector" element visibility on "Jobs_Monitor_Tab_Info_Pane" wizard + Then verify "Info_Pane_Tab_Selector" on "Jobs_Monitor_Tab_Info_Pane" wizard should contains "Jobs_Monitor_Tab_Info_Pane"."Tab_List" + Then verify "Overview" tab is active in "Info_Pane_Tab_Selector" on "Jobs_Monitor_Tab_Info_Pane" wizard + Then verify "Terminate_Button" element visibility on "Workflows_Monitor_Tab" wizard + Then "Terminate_Button" element on "Jobs_Monitoring_Workflows_Tab" should contains "Terminate" value + Then verify "Terminate_Button" element on "Jobs_Monitoring_Workflows_Tab" wizard is disabled @MLJM @smoke @@ -687,7 +961,7 @@ Feature: Jobs Monitoring Page And wait load page When click on "Total_Counter_Number" element in "Monitoring_Workflows_Box" on "Projects" wizard And wait load page - Then verify redirection to "projects/*/jobs-monitoring/workflows?state=all" + Then verify redirection to "projects/*/jobs-monitoring/workflows?state=all&dates=past24hours" Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Workflows_Tab" wizard Then verify "Status_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" When select "Error" option in "Status_Filter_Dropdown" filter dropdown on "FilterBy_Popup" wizard @@ -718,6 +992,13 @@ Feature: Jobs Monitoring Page And wait load page Then verify "Workflows_Table" element visibility on "Jobs_Monitoring_Workflows_Tab" wizard Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Workflows_Tab" wizard + Then verify "Status_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "4 items selected" + When select "Terminating" option in "Status_Filter_Dropdown" filter dropdown on "FilterBy_Popup" wizard + Then click on "Title" element on "FilterBy_Popup" wizard + Then click on "Apply_Button" element on "FilterBy_Popup" wizard + And wait load page + Then verify "Workflows_Table" element visibility on "Jobs_Monitoring_Workflows_Tab" wizard + Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Workflows_Tab" wizard Then verify "Status_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Workflows_Tab" wizard Then select "View YAML" option in action menu on "Jobs_Monitoring_Workflows_Tab" wizard in "Workflows_Table" table at row with "kfpipeline 2021-07-06 11-16-28" value in "name" column @@ -731,19 +1012,8 @@ Feature: Jobs Monitoring Page And wait load page Then verify if "Notification_Popup" popup dialog appears Then verify "Notification_Pop_Up" element visibility on "Notification_Popup" wizard - Then "Notification_Pop_Up" component on "Notification_Popup" should contains "Jobs_And_Workflows"."Workflows_Unsuccessful_Run_Message" + Then "Notification_Pop_Up" component on "Notification_Popup" should contains "Jobs_And_Workflows"."Workflows_Successful_Run_Message" Then verify "Notification_Pop_Up_Cross_Close_Button" element visibility on "Notification_Popup" wizard - Then verify "Retry_Button" element visibility on "Notification_Popup" wizard - Then "Retry_Button" element on "Notification_Popup" should contains "RETRY" value - Then click on "Retry_Button" element on "Notification_Popup" wizard - And wait load page - Then verify if "Notification_Popup" popup dialog appears - Then verify "Notification_Pop_Up" element visibility on "Notification_Popup" wizard - Then "Notification_Pop_Up" component on "Notification_Popup" should contains "Jobs_And_Workflows"."Workflows_Unsuccessful_Run_Message" - Then verify "Retry_Button" element visibility on "Notification_Popup" wizard - Then "Retry_Button" element on "Notification_Popup" should contains "RETRY" value - Then verify "Notification_Pop_Up_Cross_Close_Button" element visibility on "Notification_Popup" wizard - Then click on "Notification_Pop_Up_Cross_Close_Button" element on "Notification_Popup" wizard @MLJM @smoke @@ -754,12 +1024,10 @@ Feature: Jobs Monitoring Page Then verify "Monitoring_Scheduled_Box" element visibility in "Projects_Monitoring_Container" on "Projects" wizard Then verify "Monitoring_Scheduled_Box_Title" element visibility in "Monitoring_Scheduled_Box" on "Projects" wizard Then "Monitoring_Scheduled_Box_Title" element in "Monitoring_Scheduled_Box" on "Projects" should contains "Scheduled" value - Then verify "Total_Scheduled_Title" element visibility in "Monitoring_Scheduled_Box" on "Projects" wizard - Then "Total_Scheduled_Title" element in "Monitoring_Scheduled_Box" on "Projects" should contains "Total" value Then verify "Total_Scheduled_Number" element visibility in "Monitoring_Scheduled_Box" on "Projects" wizard When click on "Total_Scheduled_Number" element in "Monitoring_Scheduled_Box" on "Projects" wizard And wait load page - Then verify redirection to "projects/*/jobs-monitoring/scheduled?type=all" + Then verify redirection to "projects/*/jobs-monitoring/scheduled?type=all&dates=next24hours" Then verify breadcrumbs "cross" label should be equal "Jobs monitoring" value Then verify breadcrumbs "projectsPage" label should be equal "Projects" value Then verify "Cross_Jobs_Tab_Selector" on "Jobs_Monitoring_Scheduled_Tab" wizard should contains "Jobs_Monitoring"."Tab_List" @@ -776,10 +1044,22 @@ Feature: Jobs Monitoring Page Then verify "Scheduled_Table" element visibility on "Jobs_Monitoring_Scheduled_Tab" wizard Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Scheduled_Tab" wizard Then "Title" element on "FilterBy_Popup" should contains "Filter by" value - Then verify "Table_Project_Filter_Input" element visibility on "FilterBy_Popup" wizard - Then verify "Type_Filter_Dropdown" element visibility on "FilterBy_Popup" wizard - Then verify "Type_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" - Then verify "Type_Filter_Dropdown" dropdown element on "FilterBy_Popup" wizard should contains "Dropdown_Options"."Scheduled_Type_Filter_Options" + Then verify "Project_Name_Filter_Dropdown" element visibility on "FilterBy_Popup" wizard + Then verify "Project_Name_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" + Then verify "Type_Filter_Dropdown_Schedule" element visibility on "FilterBy_Popup" wizard + Then verify "Type_Filter_Dropdown_Schedule" dropdown on "FilterBy_Popup" wizard selected option value "All" + Then click on "Type_Filter_Element" element on "FilterBy_Popup" wizard + And wait load page + Then "Type_All_Checkbox" element should be checked on "FilterBy_Popup" wizard + Then "Type_Job_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Workflow_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Spark_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Horovod_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Dask_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Databricks_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then click on "Type_Filter_Element" element on "FilterBy_Popup" wizard + And wait load page + Then verify "Type_Filter_Dropdown_Schedule" dropdown element on "FilterBy_Popup" wizard should contains "Dropdown_Options"."Scheduled_Type_Filter_Options" Then verify "Table_Label_Filter_Input" element visibility on "FilterBy_Popup" wizard Then verify "Clear_Button" element visibility on "FilterBy_Popup" wizard Then verify "Apply_Button" element visibility on "FilterBy_Popup" wizard @@ -792,7 +1072,8 @@ Feature: Jobs Monitoring Page Then verify "Total_Job_Counter_Number" element visibility in "Monitoring_Scheduled_Box" on "Projects" wizard When click on "Total_Job_Counter_Number" element in "Monitoring_Scheduled_Box" on "Projects" wizard And wait load page - Then verify redirection to "projects/*/jobs-monitoring/scheduled?type=job" + Then verify redirection to "projects/*/jobs-monitoring/scheduled?type=job%2Cspark%2Cmpijob%2Cdask%2Cdatabricks&dates=next24hours" + And wait load page Then verify breadcrumbs "cross" label should be equal "Jobs monitoring" value Then verify breadcrumbs "projectsPage" label should be equal "Projects" value Then verify "Cross_Jobs_Tab_Selector" on "Jobs_Monitoring_Scheduled_Tab" wizard should contains "Jobs_Monitoring"."Tab_List" @@ -803,16 +1084,29 @@ Feature: Jobs Monitoring Page Then verify "Date_Picker_Filter_Dropdown" dropdown on "Jobs_Monitoring_Scheduled_Tab" wizard selected option value "Next 24 hours" Then verify "Date_Picker_Filter_Dropdown" dropdown element on "Jobs_Monitoring_Scheduled_Tab" wizard should contains "Dropdown_Options"."Scheduled_Date_Picker_Filter_Options" Then verify "Table_FilterBy_Button" element visibility on "Jobs_Monitoring_Scheduled_Tab" wizard + Then verify "Table_FilterBy_Button" element on "Jobs_Monitoring_Scheduled_Tab" wizard should display hover tooltip "Common_Tooltips"."FilterBy_Button_1" Then verify "Refresh_Button" element visibility on "Jobs_Monitoring_Scheduled_Tab" wizard Then click on "Refresh_Button" element on "Jobs_Monitoring_Scheduled_Tab" wizard And wait load page Then verify "Scheduled_Table" element visibility on "Jobs_Monitoring_Scheduled_Tab" wizard Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Scheduled_Tab" wizard Then "Title" element on "FilterBy_Popup" should contains "Filter by" value - Then verify "Table_Project_Filter_Input" element visibility on "FilterBy_Popup" wizard - Then verify "Type_Filter_Dropdown" element visibility on "FilterBy_Popup" wizard - Then verify "Type_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "Job" - Then verify "Type_Filter_Dropdown" dropdown element on "FilterBy_Popup" wizard should contains "Dropdown_Options"."Scheduled_Type_Filter_Options" + Then verify "Project_Name_Filter_Dropdown" element visibility on "FilterBy_Popup" wizard + Then verify "Project_Name_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" + Then verify "Type_Filter_Dropdown_Schedule" element visibility on "FilterBy_Popup" wizard + Then verify "Type_Filter_Dropdown_Schedule" dropdown on "FilterBy_Popup" wizard selected option value "5 items selected" + Then click on "Type_Filter_Element" element on "FilterBy_Popup" wizard + And wait load page + Then "Type_All_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Job_Checkbox" element should be checked on "FilterBy_Popup" wizard + Then "Type_Workflow_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Spark_Checkbox" element should be checked on "FilterBy_Popup" wizard + Then "Type_Horovod_Checkbox" element should be checked on "FilterBy_Popup" wizard + Then "Type_Dask_Checkbox" element should be checked on "FilterBy_Popup" wizard + Then "Type_Databricks_Checkbox" element should be checked on "FilterBy_Popup" wizard + Then click on "Type_Filter_Element" element on "FilterBy_Popup" wizard + And wait load page + Then verify "Type_Filter_Dropdown_Schedule" dropdown element on "FilterBy_Popup" wizard should contains "Dropdown_Options"."Scheduled_Type_Filter_Options" Then verify "Table_Label_Filter_Input" element visibility on "FilterBy_Popup" wizard Then verify "Clear_Button" element visibility on "FilterBy_Popup" wizard Then verify "Apply_Button" element visibility on "FilterBy_Popup" wizard @@ -824,7 +1118,8 @@ Feature: Jobs Monitoring Page Then "Total_Workflows_Counter_Title" element in "Monitoring_Scheduled_Box" on "Projects" should contains "Workflows" value Then verify "Total_Workflows_Counter_Number" element visibility in "Monitoring_Scheduled_Box" on "Projects" wizard When click on "Total_Workflows_Counter_Number" element in "Monitoring_Scheduled_Box" on "Projects" wizard - Then verify redirection to "projects/*/jobs-monitoring/scheduled?type=workflow" + And wait load page + Then verify redirection to "projects/*/jobs-monitoring/scheduled?type=workflow&dates=next24hours" Then verify breadcrumbs "cross" label should be equal "Jobs monitoring" value Then verify breadcrumbs "projectsPage" label should be equal "Projects" value Then verify "Cross_Jobs_Tab_Selector" on "Jobs_Monitoring_Scheduled_Tab" wizard should contains "Jobs_Monitoring"."Tab_List" @@ -835,12 +1130,25 @@ Feature: Jobs Monitoring Page Then verify "Date_Picker_Filter_Dropdown" dropdown on "Jobs_Monitoring_Scheduled_Tab" wizard selected option value "Next 24 hours" Then verify "Date_Picker_Filter_Dropdown" dropdown element on "Jobs_Monitoring_Scheduled_Tab" wizard should contains "Dropdown_Options"."Scheduled_Date_Picker_Filter_Options" Then verify "Table_FilterBy_Button" element visibility on "Jobs_Monitoring_Scheduled_Tab" wizard + Then verify "Table_FilterBy_Button" element on "Jobs_Monitoring_Scheduled_Tab" wizard should display hover tooltip "Common_Tooltips"."FilterBy_Button_1" Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Scheduled_Tab" wizard Then "Title" element on "FilterBy_Popup" should contains "Filter by" value - Then verify "Table_Project_Filter_Input" element visibility on "FilterBy_Popup" wizard - Then verify "Type_Filter_Dropdown" element visibility on "FilterBy_Popup" wizard - Then verify "Type_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "Workflow" - Then verify "Type_Filter_Dropdown" dropdown element on "FilterBy_Popup" wizard should contains "Dropdown_Options"."Scheduled_Type_Filter_Options" + Then verify "Project_Name_Filter_Dropdown" element visibility on "FilterBy_Popup" wizard + Then verify "Project_Name_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" + Then verify "Type_Filter_Dropdown_Schedule" element visibility on "FilterBy_Popup" wizard + Then verify "Type_Filter_Dropdown_Schedule" dropdown on "FilterBy_Popup" wizard selected option value "Workflow" + Then click on "Type_Filter_Element" element on "FilterBy_Popup" wizard + And wait load page + Then "Type_All_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Job_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Workflow_Checkbox" element should be checked on "FilterBy_Popup" wizard + Then "Type_Spark_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Horovod_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Dask_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Databricks_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then click on "Type_Filter_Element" element on "FilterBy_Popup" wizard + And wait load page + Then verify "Type_Filter_Dropdown_Schedule" dropdown element on "FilterBy_Popup" wizard should contains "Dropdown_Options"."Scheduled_Type_Filter_Options" Then verify "Table_Label_Filter_Input" element visibility on "FilterBy_Popup" wizard Then verify "Clear_Button" element visibility on "FilterBy_Popup" wizard Then verify "Apply_Button" element visibility on "FilterBy_Popup" wizard @@ -849,17 +1157,16 @@ Feature: Jobs Monitoring Page Then click on breadcrumbs "projectsPage" label on "commonPagesHeader" wizard And wait load page Then verify redirection to "projects" - Then verify "Total_Scheduled_Title" element visibility in "Monitoring_Scheduled_Box" on "Projects" wizard - Then "Total_Scheduled_Title" element in "Monitoring_Scheduled_Box" on "Projects" should contains "Total" value Then verify "Total_Job_Counter_Number" element visibility in "Monitoring_Scheduled_Box" on "Projects" wizard Then verify "Total_Workflows_Counter_Number" element visibility in "Monitoring_Scheduled_Box" on "Projects" wizard Then verify "Total_Scheduled_Number" element visibility in "Monitoring_Scheduled_Box" on "Projects" wizard When click on "Total_Scheduled_Number" element in "Monitoring_Scheduled_Box" on "Projects" wizard And wait load page - Then verify redirection to "projects/*/jobs-monitoring/scheduled?type=all" + Then verify redirection to "projects/*/jobs-monitoring/scheduled?type=all&dates=next24hours" Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Scheduled_Tab" wizard - Then verify "Table_Project_Filter_Input" element visibility on "FilterBy_Popup" wizard - Then type value "test" to "Table_Project_Filter_Input" field on "FilterBy_Popup" wizard + Then verify "Project_Name_Filter_Dropdown" element visibility on "FilterBy_Popup" wizard + Then verify "Project_Name_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" + When select "auto-generated-data" option in "Project_Name_Filter_Dropdown" filter dropdown on "FilterBy_Popup" wizard And wait load page Then click on "Apply_Button" element on "FilterBy_Popup" wizard And wait load page @@ -872,7 +1179,7 @@ Feature: Jobs Monitoring Page And wait load page When click on "Total_Scheduled_Number" element in "Monitoring_Scheduled_Box" on "Projects" wizard And wait load page - Then verify redirection to "projects/*/jobs-monitoring/scheduled?type=all" + Then verify redirection to "projects/*/jobs-monitoring/scheduled?type=all&dates=next24hours" Then verify "Scheduled_Table" element visibility on "Jobs_Monitoring_Scheduled_Tab" wizard Then verify that 8 row elements are displayed in "Scheduled_Table" on "Jobs_Monitoring_Scheduled_Tab" wizard Then verify "Date_Picker_Filter_Dropdown" element visibility on "Jobs_Monitoring_Scheduled_Tab" wizard @@ -886,10 +1193,13 @@ Feature: Jobs Monitoring Page Then verify that 2 row elements are displayed in "Scheduled_Table" on "Jobs_Monitoring_Scheduled_Tab" wizard Then value in "name" column with "text" in "Scheduled_Table" on "Jobs_Monitoring_Scheduled_Tab" wizard should contains "clean" And select "Workflows" tab in "Cross_Jobs_Tab_Selector" on "Jobs_Monitoring_Workflows_Tab" wizard + And wait load page And select "Scheduled" tab in "Cross_Jobs_Tab_Selector" on "Jobs_Monitoring_Scheduled_Tab" wizard Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Scheduled_Tab" wizard - Then verify "Table_Project_Filter_Input" element visibility on "FilterBy_Popup" wizard - Then type value "default" to "Table_Project_Filter_Input" field on "FilterBy_Popup" wizard + Then verify "Project_Name_Filter_Dropdown" element visibility on "FilterBy_Popup" wizard + Then verify "Project_Name_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" + When select "default" option in "Project_Name_Filter_Dropdown" filter dropdown on "FilterBy_Popup" wizard + And wait load page Then click on "Apply_Button" element on "FilterBy_Popup" wizard And wait load page Then value in "project_name" column with "text" in "Scheduled_Table" on "Jobs_Monitoring_Scheduled_Tab" wizard should contains "default" @@ -925,6 +1235,7 @@ Feature: Jobs Monitoring Page Then verify "Scheduled_Table" element visibility on "Jobs_Monitoring_Scheduled_Tab" wizard Then verify that 8 row elements are displayed in "Scheduled_Table" on "Jobs_Monitoring_Scheduled_Tab" wizard When pick up "Custom range" from "09/03/2024 00:00" to "09/04/2024 00:00" in "Date_Time_Picker" via "Date_Picker_Filter_Dropdown" on "Jobs_Monitoring_Scheduled_Tab" wizard + And wait load page Then verify from "09/03/2024 00:00" to "09/04/2024 00:00" filter band in "Custom_Range_Filter_Dropdown" filter dropdown on "Jobs_Monitoring_Scheduled_Tab" wizard And wait load page @@ -935,13 +1246,37 @@ Feature: Jobs Monitoring Page And wait load page When click on "Total_Scheduled_Number" element in "Monitoring_Scheduled_Box" on "Projects" wizard And wait load page - Then verify redirection to "projects/*/jobs-monitoring/scheduled?type=all" + Then verify redirection to "projects/*/jobs-monitoring/scheduled?type=all&dates=next24hours" Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Scheduled_Tab" wizard - Then verify "Type_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" - When select "Job" option in "Type_Filter_Dropdown" filter dropdown on "FilterBy_Popup" wizard + Then verify "Type_Filter_Dropdown_Schedule" dropdown on "FilterBy_Popup" wizard selected option value "All" + Then click on "Type_Filter_Element" element on "FilterBy_Popup" wizard + And wait load page + Then "Type_All_Checkbox" element should be checked on "FilterBy_Popup" wizard + Then "Type_Job_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Workflow_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Spark_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Horovod_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Dask_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Databricks_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then click on "Type_Filter_Element" element on "FilterBy_Popup" wizard + And wait load page + When select "Job" option in "Type_Filter_Dropdown_Schedule" filter dropdown on "FilterBy_Popup" wizard + And wait load page Then click on "Title" element on "FilterBy_Popup" wizard + And wait load page Then click on "Apply_Button" element on "FilterBy_Popup" wizard And wait load page + Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Scheduled_Tab" wizard + Then click on "Type_Filter_Element" element on "FilterBy_Popup" wizard + Then "Type_All_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Job_Checkbox" element should be checked on "FilterBy_Popup" wizard + Then "Type_Workflow_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Spark_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Horovod_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Dask_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Databricks_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then click on "Type_Filter_Element" element on "FilterBy_Popup" wizard + And wait load page Then verify "Scheduled_Table" element visibility on "Jobs_Monitoring_Scheduled_Tab" wizard Then select "View YAML" option in action menu on "Jobs_Monitoring_Scheduled_Tab" wizard in "Scheduled_Table" table at row with "clean-data" value in "name" column Then verify if "View_YAML" popup dialog appears @@ -950,29 +1285,94 @@ Feature: Jobs Monitoring Page Then click on "Cross_Cancel_Button" element on "View_YAML" wizard And wait load page Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Scheduled_Tab" wizard - Then verify "Type_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "Job" - When select "Workflow" option in "Type_Filter_Dropdown" filter dropdown on "FilterBy_Popup" wizard + Then verify "Type_Filter_Dropdown_Schedule" dropdown on "FilterBy_Popup" wizard selected option value "Job" + When select "Job" option in "Type_Filter_Dropdown_Schedule" filter dropdown on "FilterBy_Popup" wizard + Then click on "Title" element on "FilterBy_Popup" wizard + When select "Workflow" option in "Type_Filter_Dropdown_Schedule" filter dropdown on "FilterBy_Popup" wizard Then click on "Title" element on "FilterBy_Popup" wizard Then click on "Apply_Button" element on "FilterBy_Popup" wizard And wait load page - Then verify "Scheduled_Table" element visibility on "Jobs_Monitoring_Scheduled_Tab" wizard - Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Scheduled_Tab" wizard - Then verify "Type_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "Workflow" Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Scheduled_Tab" wizard + Then click on "Type_Filter_Element" element on "FilterBy_Popup" wizard + Then "Type_All_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Job_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Workflow_Checkbox" element should be checked on "FilterBy_Popup" wizard + Then "Type_Spark_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Horovod_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Dask_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Databricks_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then click on "Type_Filter_Element" element on "FilterBy_Popup" wizard + And wait load page + Then verify "Scheduled_Table" element visibility on "Jobs_Monitoring_Scheduled_Tab" wizard Then select "View YAML" option in action menu on "Jobs_Monitoring_Scheduled_Tab" wizard in "Scheduled_Table" table at row with "main3" value in "name" column Then verify if "View_YAML" popup dialog appears Then verify "Cross_Cancel_Button" element visibility on "View_YAML" wizard Then verify "YAML_Modal_Container" element visibility on "View_YAML" wizard - + Then click on "Cross_Cancel_Button" element on "View_YAML" wizard + And wait load page + Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Scheduled_Tab" wizard + Then verify "Type_Filter_Dropdown_Schedule" dropdown on "FilterBy_Popup" wizard selected option value "Workflow" + @MLJM @smoke + Scenario: MLJM021 - Check filter by Types options on Scheduled tab of Jobs monitoring page + Given open url + And wait load page + When click on "Total_Scheduled_Number" element in "Monitoring_Scheduled_Box" on "Projects" wizard + And wait load page + Then verify redirection to "projects/*/jobs-monitoring/scheduled?type=all&dates=next24hours" + Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Scheduled_Tab" wizard + Then verify "Project_Name_Filter_Dropdown" element visibility on "FilterBy_Popup" wizard + Then verify "Project_Name_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" + Then verify "Type_Filter_Dropdown_Schedule" dropdown on "FilterBy_Popup" wizard selected option value "All" + When select "Databricks" option in "Type_Filter_Dropdown_Schedule" filter dropdown on "FilterBy_Popup" wizard + Then click on "Title" element on "FilterBy_Popup" wizard + Then verify "Type_Filter_Dropdown_Schedule" dropdown on "FilterBy_Popup" wizard selected option value "Databricks" + When select "Dask" option in "Type_Filter_Dropdown_Schedule" filter dropdown on "FilterBy_Popup" wizard + Then click on "Title" element on "FilterBy_Popup" wizard + Then verify "Type_Filter_Dropdown_Schedule" dropdown on "FilterBy_Popup" wizard selected option value "Dask, Databricks" + When select "Horovod" option in "Type_Filter_Dropdown_Schedule" filter dropdown on "FilterBy_Popup" wizard + Then click on "Title" element on "FilterBy_Popup" wizard + Then verify "Type_Filter_Dropdown_Schedule" dropdown on "FilterBy_Popup" wizard selected option value "3 items selected" + When select "Spark" option in "Type_Filter_Dropdown_Schedule" filter dropdown on "FilterBy_Popup" wizard + Then click on "Title" element on "FilterBy_Popup" wizard + Then verify "Type_Filter_Dropdown_Schedule" dropdown on "FilterBy_Popup" wizard selected option value "4 items selected" + When select "Workflow" option in "Type_Filter_Dropdown_Schedule" filter dropdown on "FilterBy_Popup" wizard + Then click on "Title" element on "FilterBy_Popup" wizard + Then verify "Type_Filter_Dropdown_Schedule" dropdown on "FilterBy_Popup" wizard selected option value "5 items selected" + Then click on "Apply_Button" element on "FilterBy_Popup" wizard + And wait load page + Then verify "Scheduled_Table" element visibility on "Jobs_Monitoring_Scheduled_Tab" wizard + Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Scheduled_Tab" wizard + Then verify "Type_Filter_Dropdown_Schedule" dropdown on "FilterBy_Popup" wizard selected option value "5 items selected" + When select "Job" option in "Type_Filter_Dropdown_Schedule" filter dropdown on "FilterBy_Popup" wizard + Then click on "Title" element on "FilterBy_Popup" wizard + Then verify "Type_Filter_Dropdown_Schedule" dropdown on "FilterBy_Popup" wizard selected option value "All" + Then click on "Apply_Button" element on "FilterBy_Popup" wizard + And wait load page + Then verify "Scheduled_Table" element visibility on "Jobs_Monitoring_Scheduled_Tab" wizard + Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Scheduled_Tab" wizard + Then verify "Type_Filter_Dropdown_Schedule" dropdown on "FilterBy_Popup" wizard selected option value "All" + When select "Spark" option in "Type_Filter_Dropdown_Schedule" filter dropdown on "FilterBy_Popup" wizard + Then click on "Title" element on "FilterBy_Popup" wizard + When select "Horovod" option in "Type_Filter_Dropdown_Schedule" filter dropdown on "FilterBy_Popup" wizard + Then click on "Title" element on "FilterBy_Popup" wizard + Then verify "Type_Filter_Dropdown_Schedule" dropdown on "FilterBy_Popup" wizard selected option value "Spark, Horovod" + Then click on "Apply_Button" element on "FilterBy_Popup" wizard + And wait load page + And verify "No_Data_Message" element visibility on "commonPagesHeader" wizard + Then "No_Data_Message" component on "commonPagesHeader" should be equal "No_Data_Message"."Common_Message_Scheduled_Type" + + @MLJM + @smoke + # TODO: Total wf counter = 4, 3 row elements are displayed - known bug (due to running not in 24h period), couldn't be fixed yet Scenario: MLJM012 - Check jobs/workflows/scheduled count consistency among counter data and Jobs monitoring Tabs Given open url And wait load page Then verify "Monitoring_Container" element visibility in "Projects_Monitoring_Container" on "Projects" wizard When click on "Total_Counter_Number" element in "Monitoring_Jobs_Box" on "Projects" wizard And wait load page - Then verify redirection to "projects/*/jobs-monitoring/jobs?state=all&bePage=1&fePage=1" + Then verify redirection to "projects/*/jobs-monitoring/jobs?state=all&dates=past24hours&bePage=1&fePage=1" Then verify "Jobs" tab is active in "Cross_Jobs_Tab_Selector" on "Jobs_Monitoring_Jobs_Tab" wizard Then verify "Jobs_Table" element visibility on "Jobs_Monitoring_Jobs_Tab" wizard Then "Pagination_Count" element on "Pagination_Info_Pane" should contains "Showing 1 - 50" value @@ -1002,19 +1402,19 @@ Feature: Jobs Monitoring Page Then click on breadcrumbs "projectsPage" label on "commonPagesHeader" wizard And wait load page Then verify "Total_Counter_Number" element visibility in "Monitoring_Workflows_Box" on "Projects" wizard - Then "Total_Counter_Number" element in "Monitoring_Workflows_Box" on "Projects" should contains "3" value + Then "Total_Counter_Number" element in "Monitoring_Workflows_Box" on "Projects" should contains "4" value When click on "Total_Counter_Number" element in "Monitoring_Workflows_Box" on "Projects" wizard And wait load page - Then verify redirection to "projects/*/jobs-monitoring/workflows?state=all" + Then verify redirection to "projects/*/jobs-monitoring/workflows?state=all&dates=past24hours" Then verify "Workflows_Table" element visibility on "Jobs_Monitoring_Workflows_Tab" wizard Then verify that 3 row elements are displayed in "Workflows_Table" on "Jobs_Monitoring_Workflows_Tab" wizard Then navigate back And wait load page - Then verify "Counter_Running_Status_Number" element visibility in "Monitoring_Workflows_Box" on "Projects" wizard - Then "Counter_Running_Status_Number" element in "Monitoring_Workflows_Box" on "Projects" should contains "0" value - When click on "Counter_Running_Status_Number" element in "Monitoring_Workflows_Box" on "Projects" wizard + Then verify "Counter_In_Process_Status_Number" element visibility in "Monitoring_Workflows_Box" on "Projects" wizard + Then "Counter_In_Process_Status_Number" element in "Monitoring_Workflows_Box" on "Projects" should contains "1" value + When click on "Counter_In_Process_Status_Number" element in "Monitoring_Workflows_Box" on "Projects" wizard And wait load page - Then verify that 0 row elements are displayed in "Workflows_Table" on "Jobs_Monitoring_Workflows_Tab" wizard + Then verify that 1 row elements are displayed in "Workflows_Table" on "Jobs_Monitoring_Workflows_Tab" wizard Then click on breadcrumbs "projectsPage" label on "commonPagesHeader" wizard And wait load page Then verify "Counter_Failed_Status_Number" element visibility in "Monitoring_Workflows_Box" on "Projects" wizard @@ -1037,7 +1437,7 @@ Feature: Jobs Monitoring Page Then "Total_Scheduled_Number" element in "Monitoring_Scheduled_Box" on "Projects" should contains "8" value When click on "Total_Scheduled_Number" element in "Monitoring_Scheduled_Box" on "Projects" wizard And wait load page - Then verify redirection to "projects/*/jobs-monitoring/scheduled?type=all" + Then verify redirection to "projects/*/jobs-monitoring/scheduled?type=all&dates=next24hours" Then verify that 8 row elements are displayed in "Scheduled_Table" on "Jobs_Monitoring_Scheduled_Tab" wizard Then navigate back And wait load page @@ -1066,7 +1466,7 @@ Feature: Jobs Monitoring Page Then verify "Monitoring_Container" element visibility in "Projects_Monitoring_Container" on "Projects" wizard When click on "Total_Counter_Number" element in "Monitoring_Jobs_Box" on "Projects" wizard And wait load page - Then verify redirection to "projects/*/jobs-monitoring/jobs?state=all&bePage=1&fePage=1" + Then verify redirection to "projects/*/jobs-monitoring/jobs?state=all&dates=past24hours&bePage=1&fePage=1" Then verify breadcrumbs "cross" label should be equal "Jobs monitoring" value Then verify breadcrumbs "projectsPage" label should be equal "Projects" value Then verify "Cross_Jobs_Tab_Selector" on "Jobs_Monitoring_Jobs_Tab" wizard should contains "Jobs_Monitoring"."Tab_List" @@ -1131,3 +1531,86 @@ Feature: Jobs Monitoring Page Then "Pagination_Count" element on "Pagination_Info_Pane" should contains "Showing 1 - 50" value Then verify "BE_Pagination_Navigate_Next" element on "Pagination_Info_Pane" wizard is disabled Then verify "BE_Pagination_Navigate_Next" element on "Pagination_Info_Pane" wizard should display hover tooltip "Common_Tooltips"."Auto_Refresh" + + @MLJM + @smoke + Scenario: MLJM017 - Check filtering of different projects within identical job function runs + Given open url + And wait load page + Then verify "Monitoring_Container" element visibility in "Projects_Monitoring_Container" on "Projects" wizard + When click on "Total_Counter_Number" element in "Monitoring_Jobs_Box" on "Projects" wizard + And wait load page + Then verify redirection to "projects/*/jobs-monitoring/jobs?state=all&dates=past24hours&bePage=1&fePage=1" + Then verify breadcrumbs "cross" label should be equal "Jobs monitoring" value + Then verify breadcrumbs "projectsPage" label should be equal "Projects" value + Then verify "Cross_Jobs_Tab_Selector" on "Jobs_Monitoring_Jobs_Tab" wizard should contains "Jobs_Monitoring"."Tab_List" + Then verify "Jobs" tab is active in "Cross_Jobs_Tab_Selector" on "Jobs_Monitoring_Jobs_Tab" wizard + Then verify "Jobs_Table" element visibility on "Jobs_Monitoring_Jobs_Tab" wizard + When select "Any time" option in "Date_Picker_Filter_Dropdown" filter dropdown on "Jobs_Monitoring_Jobs_Tab" wizard + And wait load page + Then verify "Date_Picker_Filter_Dropdown" dropdown on "Jobs_Monitoring_Jobs_Tab" wizard selected option value "Any time" + Then verify "Search_By_Name_Filter_Input" element visibility on "Jobs_Monitoring_Jobs_Tab" wizard + Then type value "fesf" to "Search_By_Name_Filter_Input" field on "Jobs_Monitoring_Jobs_Tab" wizard + Then click on "Refresh_Button" element on "Jobs_Monitoring_Jobs_Tab" wizard + And wait load page + Then value in "name" column with "text" in "Jobs_Table" on "Jobs_Monitoring_Jobs_Tab" wizard should contains "fesf" + Then verify that 2 row elements are displayed in "Jobs_Table" on "Jobs_Monitoring_Jobs_Tab" wizard + When click on cell with row index 1 in "name" column in "Jobs_Table" table on "Jobs_Monitoring_Jobs_Tab" wizard + And wait load page + Then verify that 3 row elements are displayed in "Jobs_Table" on "Jobs_Monitoring_Jobs_Tab" wizard + Then value in "project_name" column with "text" in "Jobs_Table" on "Jobs_Monitoring_Jobs_Tab" wizard should contains "cat-vs-dog-classification" + Then click on "Arrow_Back" element on "Jobs_Monitor_Tab" wizard + And wait load page + When click on cell with row index 2 in "name" column in "Jobs_Table" table on "Jobs_Monitoring_Jobs_Tab" wizard + And wait load page + Then verify that 1 row elements are displayed in "Jobs_Table" on "Jobs_Monitoring_Jobs_Tab" wizard + Then value in "project_name" column with "text" in "Jobs_Table" on "Jobs_Monitoring_Jobs_Tab" wizard should contains "fsdemo-admin" + Then click on breadcrumbs "projectsPage" label on "commonPagesHeader" wizard + And wait load page + When click on "Total_Counter_Number" element in "Monitoring_Jobs_Box" on "Projects" wizard + And wait load page + Then verify redirection to "projects/*/jobs-monitoring/jobs?state=all&dates=past24hours&bePage=1&fePage=1" + Then verify breadcrumbs "cross" label should be equal "Jobs monitoring" value + When select "Any time" option in "Date_Picker_Filter_Dropdown" filter dropdown on "Jobs_Monitoring_Jobs_Tab" wizard + And wait load page + Then verify "Date_Picker_Filter_Dropdown" dropdown on "Jobs_Monitoring_Jobs_Tab" wizard selected option value "Any time" + Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Jobs_Tab" wizard + Then "Title" element on "FilterBy_Popup" should contains "Filter by" value + Then verify "Project_Name_Filter_Dropdown" element visibility on "FilterBy_Popup" wizard + Then verify "Project_Name_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" + When select "cat-vs-dog-classification" option in "Project_Name_Filter_Dropdown" filter dropdown on "FilterBy_Popup" wizard + And wait load page + Then click on "Apply_Button" element on "FilterBy_Popup" wizard + And wait load page + Then value in "project_name" column with "text" in "Jobs_Table" on "Jobs_Monitoring_Jobs_Tab" wizard should contains "cat-vs-dog-classification" + When click on cell with value "fesf" in "name" column in "Jobs_Table" table on "Jobs_Monitoring_Jobs_Tab" wizard + And wait load page + Then verify that 3 row elements are displayed in "Jobs_Table" on "Jobs_Monitoring_Jobs_Tab" wizard + Then value in "project_name" column with "text" in "Jobs_Table" on "Jobs_Monitoring_Jobs_Tab" wizard should contains "cat-vs-dog-classification" + Then click on "Arrow_Back" element on "Jobs_Monitor_Tab" wizard + And wait load page + Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Jobs_Tab" wizard + Then click on "Clear_Button" element on "FilterBy_Popup" wizard + And wait load page + Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Jobs_Tab" wizard + Then "Title" element on "FilterBy_Popup" should contains "Filter by" value + Then verify "Project_Name_Filter_Dropdown" element visibility on "FilterBy_Popup" wizard + Then verify "Project_Name_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" + When select "fsdemo-admin" option in "Project_Name_Filter_Dropdown" filter dropdown on "FilterBy_Popup" wizard + And wait load page + Then click on "Apply_Button" element on "FilterBy_Popup" wizard + And wait load page + Then value in "project_name" column with "text" in "Jobs_Table" on "Jobs_Monitoring_Jobs_Tab" wizard should contains "fsdemo-admin" + When click on cell with value "fesf" in "name" column in "Jobs_Table" table on "Jobs_Monitoring_Jobs_Tab" wizard + And wait load page + Then verify that 1 row elements are displayed in "Jobs_Table" on "Jobs_Monitoring_Jobs_Tab" wizard + Then value in "project_name" column with "text" in "Jobs_Table" on "Jobs_Monitoring_Jobs_Tab" wizard should contains "fsdemo-admin" + Then click on "Arrow_Back" element on "Jobs_Monitor_Tab" wizard + And wait load page + Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Jobs_Tab" wizard + Then click on "Clear_Button" element on "FilterBy_Popup" wizard + And wait load page + Then click on "Table_FilterBy_Button" element on "Jobs_Monitoring_Jobs_Tab" wizard + Then verify "Project_Name_Filter_Dropdown" element visibility on "FilterBy_Popup" wizard + Then verify "Project_Name_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" + \ No newline at end of file diff --git a/tests/features/llmPrompts.feature b/tests/features/llmPrompts.feature index 1874682e0a..d257cf7607 100644 --- a/tests/features/llmPrompts.feature +++ b/tests/features/llmPrompts.feature @@ -7,15 +7,16 @@ Feature: LLM prompts Page Scenario: MLLP001 - Check components on LLM prompts page Given open url And wait load page - And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard + And click on row root with value "llmdeploy332" in "name" column in "Projects_Table" table on "Projects" wizard And wait load page Then verify breadcrumbs "tab" label should be equal "Project monitoring" value - Then verify breadcrumbs "project" label should be equal "default" value + Then verify breadcrumbs "project" label should be equal "llmdeploy332" value And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard And click on cell with value "LLM prompts" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard And hover "MLRun_Logo" component on "commonPagesHeader" wizard And wait load page - Then verify redirection to "projects/default/llm-prompts" + Then verify breadcrumbs "tab" label should be equal "LLM prompts" value + Then verify redirection to "projects/llmdeploy332/llm-prompts?bePage=1&fePage=1" And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard And click on cell with value "Project monitoring" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard And hover "MLRun_Logo" component on "commonPagesHeader" wizard @@ -24,4 +25,1004 @@ Feature: LLM prompts Page And wait load page And select "tab" with "LLM prompts" value in breadcrumbs menu And wait load page - Then verify redirection to "projects/default/llm-prompts" + Then verify redirection to "projects/llmdeploy332/llm-prompts?bePage=1&fePage=1" + Then verify breadcrumbs "tab" label should be equal "LLM prompts" value + Then verify "Search_By_Name_Filter_Input" element visibility on "LLM_Prompts" wizard + Then verify "LLMPrompts_Table" element visibility on "LLM_Prompts" wizard + Then verify "Table_FilterBy_Button" element visibility on "LLM_Prompts" wizard + Then verify "Table_FilterBy_Button" element on "LLM_Prompts" wizard should display hover tooltip "Common_Tooltips"."FilterBy_Button" + Then click on "Table_FilterBy_Button" element on "LLM_Prompts" wizard + And wait load page + Then verify "Table_Label_Filter_Input" element visibility on "FilterBy_Popup" wizard + Then verify "Table_Tree_Filter_Dropdown" element visibility on "FilterBy_Popup" wizard + Then verify "Table_Tree_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected attribute option value "latest" + Then verify "Model_Name_Filter_Input" element visibility on "FilterBy_Popup" wizard + Then verify "Model_Version_Tag_Filter_Input" element visibility on "FilterBy_Popup" wizard + Then verify "Model_Version_Tag_Filter_Field" element on "FilterBy_Popup" wizard is disabled by class name + Then verify "Model_Version_Tag_Filter_Tip" element visibility on "FilterBy_Popup" wizard + Then verify "Model_Version_Tag_Filter_Tip" element on "FilterBy_Popup" wizard should display hover hint "Label_Hint"."Model_Version_Tag" + Then verify "Show_Iterations_Checkbox" element visibility on "FilterBy_Popup" wizard + Then "Show_Iterations_Checkbox" element should be checked on "FilterBy_Popup" wizard + Then verify "Clear_Button" element visibility on "FilterBy_Popup" wizard + Then verify "Clear_Button" element on "FilterBy_Popup" wizard is disabled + Then verify "Apply_Button" element visibility on "FilterBy_Popup" wizard + Then verify "Apply_Button" element on "FilterBy_Popup" wizard is disabled + Then uncheck "Show_Iterations_Checkbox" element on "FilterBy_Popup" wizard + And wait load page + Then verify "Apply_Button" element on "FilterBy_Popup" wizard is enabled + Then verify "Clear_Button" element on "FilterBy_Popup" wizard is enabled + Then click on "Apply_Button" element on "FilterBy_Popup" wizard + And wait load page + Then click on "Table_FilterBy_Button" element on "LLM_Prompts" wizard + And wait load page + Then "Show_Iterations_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then verify "Apply_Button" element on "FilterBy_Popup" wizard is disabled + Then verify "Clear_Button" element on "FilterBy_Popup" wizard is enabled + Then click on "Table_FilterBy_Button" element on "LLM_Prompts" wizard + And wait load page + Then verify "LLMPrompts_Table" element visibility on "LLM_Prompts" wizard + Then verify "Refresh_Button" element visibility on "LLM_Prompts" wizard + Then verify "Refresh_Button" element on "LLM_Prompts" wizard should display hover tooltip "Common_Tooltips"."Refresh_Button" + Then verify "Table_FilterBy_Button" element on "LLM_Prompts" wizard should display hover tooltip "Common_Tooltips"."FilterBy_Button_1" + Then verify "BE_Pagination_Navigate_Prev" element visibility on "Pagination_Info_Pane" wizard + Then verify "BE_Pagination_Navigate_Prev" element on "Pagination_Info_Pane" wizard is disabled + Then verify "BE_Pagination_Navigate_Next" element visibility on "Pagination_Info_Pane" wizard + Then verify "BE_Pagination_Navigate_Next" element on "Pagination_Info_Pane" wizard is disabled + Then verify "FE_Pagination_Navigate_Next" element visibility on "Pagination_Info_Pane" wizard + Then verify "FE_Pagination_Navigate_Next" element on "Pagination_Info_Pane" wizard is disabled + Then verify "FE_Pagination_Navigate_Prev" element visibility on "Pagination_Info_Pane" wizard + Then verify "FE_Pagination_Navigate_Prev" element on "Pagination_Info_Pane" wizard is disabled + Then verify "Pagination_Page_Number" element visibility on "Pagination_Info_Pane" wizard + Then "Pagination_Page_Number" element on "Pagination_Info_Pane" should contains "1" value + Then verify "Pagination_Count" element visibility on "Pagination_Info_Pane" wizard + Then "Pagination_Count" element on "Pagination_Info_Pane" should contains "Showing 1 - 1" value + + @MLLP + @smoke + Scenario: MLLP002 - Verify searching by llm prompt name on LLM prompts page + Given open url + And wait load page + And click on row root with value "auto-generated-data" in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "Project monitoring" value + Then verify breadcrumbs "project" label should be equal "auto-generated-data" value + And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard + And click on cell with value "LLM prompts" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard + And hover "MLRun_Logo" component on "commonPagesHeader" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "LLM prompts" value + Then verify redirection to "projects/auto-generated-data/llm-prompts?bePage=1&fePage=1" + And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard + And click on cell with value "Project monitoring" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard + And hover "MLRun_Logo" component on "commonPagesHeader" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "Project monitoring" value + And wait load page + Then verify "LLM_Prompts_Counter_Subtitle" element visibility in "Artifacts_Stats_Container" on "Project" wizard + Then "LLM_Prompts_Counter_Subtitle" element in "Artifacts_Stats_Container" on "Project" should contains "LLM prompt artifacts" value + When click on "LLM_Prompts_Counter_Number" element in "Artifacts_Stats_Container" on "Project" wizard + And wait load page + Then verify redirection to "projects/auto-generated-data/llm-prompts?bePage=1&fePage=1" + Then verify breadcrumbs "tab" label should be equal "LLM prompts" value + Then verify "Search_By_Name_Filter_Input" element visibility on "LLM_Prompts" wizard + Then type value "59" to "Search_By_Name_Filter_Input" field on "LLM_Prompts" wizard + Then click on "Refresh_Button" element on "LLM_Prompts" wizard + And wait load page + Then value in "name" column with "text" in "LLMPrompts_Table" on "LLM_Prompts" wizard should contains "59" + And wait load page + Then type value "yyyy" to "Search_By_Name_Filter_Input" field on "LLM_Prompts" wizard + Then click on "Refresh_Button" element on "LLM_Prompts" wizard + And wait load page + And verify "No_Data_Message" element visibility on "commonPagesHeader" wizard + Then "No_Data_Message" component on "commonPagesHeader" should be equal "No_Data_Message"."Common_Message_LLM_Prompt_Name" + + @MLLP + @smoke + Scenario: MLLP003 - Verify filtering by llm prompt label on LLM prompts page + Given open url + And wait load page + And click on row root with value "auto-generated-data" in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "Project monitoring" value + Then verify breadcrumbs "project" label should be equal "auto-generated-data" value + And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard + And click on cell with value "LLM prompts" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard + And hover "MLRun_Logo" component on "commonPagesHeader" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "LLM prompts" value + Then verify redirection to "projects/auto-generated-data/llm-prompts?bePage=1&fePage=1" + And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard + And click on cell with value "Project monitoring" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard + And hover "MLRun_Logo" component on "commonPagesHeader" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "Project monitoring" value + And wait load page + Then verify "LLM_Prompts_Counter_Subtitle" element visibility in "Artifacts_Stats_Container" on "Project" wizard + Then "LLM_Prompts_Counter_Subtitle" element in "Artifacts_Stats_Container" on "Project" should contains "LLM prompt artifacts" value + When click on "LLM_Prompts_Counter_Number" element in "Artifacts_Stats_Container" on "Project" wizard + And wait load page + Then verify redirection to "projects/auto-generated-data/llm-prompts?bePage=1&fePage=1" + Then verify breadcrumbs "tab" label should be equal "LLM prompts" value + Then click on "Table_FilterBy_Button" element on "LLM_Prompts" wizard + Then type value "language" to "Table_Label_Filter_Input" field on "FilterBy_Popup" wizard + Then click on "Apply_Button" element on "FilterBy_Popup" wizard + And wait load page + Then type value "50" to "Search_By_Name_Filter_Input" field on "LLM_Prompts" wizard + Then click on "Refresh_Button" element on "LLM_Prompts" wizard + And wait load page + Then value in "labels" column with "dropdowns" in "LLMPrompts_Table" on "LLM_Prompts" wizard should contains "language" in "Overlay" + Then type value "5" to "Search_By_Name_Filter_Input" field on "LLM_Prompts" wizard + Then click on "Refresh_Button" element on "LLM_Prompts" wizard + And wait load page + Then click on "Table_FilterBy_Button" element on "LLM_Prompts" wizard + Then type value "type=qa" to "Table_Label_Filter_Input" field on "FilterBy_Popup" wizard + Then click on "Apply_Button" element on "FilterBy_Popup" wizard + And wait load page + Then value in "labels" column with "text" in "LLMPrompts_Table" on "LLM_Prompts" wizard should contains "type=qa" + Then click on "Table_FilterBy_Button" element on "LLM_Prompts" wizard + Then type value "v3io_user=123" to "Table_Label_Filter_Input" field on "FilterBy_Popup" wizard + Then click on "Apply_Button" element on "FilterBy_Popup" wizard + And wait load page + And verify "No_Data_Message" element visibility on "commonPagesHeader" wizard + Then "No_Data_Message" component on "commonPagesHeader" should be equal "No_Data_Message"."Common_Message_LLM_Prompt_Label" + + @MLLP + @smoke + Scenario: MLLP004 - Verify the Show iterations checkbox on LLM prompts page + Given open url + And wait load page + And click on row root with value "llmdeploy332" in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "Project monitoring" value + Then verify breadcrumbs "project" label should be equal "llmdeploy332" value + And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard + And click on cell with value "LLM prompts" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard + And hover "MLRun_Logo" component on "commonPagesHeader" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "LLM prompts" value + Then verify redirection to "projects/llmdeploy332/llm-prompts?bePage=1&fePage=1" + And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard + And click on cell with value "Project monitoring" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard + And hover "MLRun_Logo" component on "commonPagesHeader" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "Project monitoring" value + And wait load page + And select "tab" with "LLM prompts" value in breadcrumbs menu + And wait load page + Then verify redirection to "projects/llmdeploy332/llm-prompts?bePage=1&fePage=1" + Then verify breadcrumbs "tab" label should be equal "LLM prompts" value + Then verify "LLMPrompts_Table" element visibility on "LLM_Prompts" wizard + Then click on "Table_FilterBy_Button" element on "LLM_Prompts" wizard + Then verify "Show_Iterations_Checkbox" element visibility on "FilterBy_Popup" wizard + Then "Show_Iterations_Checkbox" element should be checked on "FilterBy_Popup" wizard + Then uncheck "Show_Iterations_Checkbox" element on "FilterBy_Popup" wizard + Then click on "Apply_Button" element on "FilterBy_Popup" wizard + And wait load page + Then click on "Table_FilterBy_Button" element on "LLM_Prompts" wizard + Then "Show_Iterations_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then verify "LLMPrompts_Table" element visibility on "LLM_Prompts" wizard + Then click on "Table_FilterBy_Button" element on "LLM_Prompts" wizard + Then verify "show_all_versions" option is present on "LLM_Prompts" wizard in "LLMPrompts_Table" table with "my_llm" value in "name" column + Then verify "show_all_versions" option on "LLM_Prompts" wizard in "LLMPrompts_Table" table with "my_llm" value in "name" column should display hover tooltip "Common_Tooltips"."Show_All_Versions" with scroll "false" + Then click on cell with row index 1 in "name" column in "LLMPrompts_Table" table on "LLM_Prompts" wizard + And wait load page + Then verify "Header" element visibility on "LLM_Prompts_Info_Pane" wizard + Then click on "Table_FilterBy_Button" element on "LLM_Prompts" wizard + Then check "Show_Iterations_Checkbox" element on "FilterBy_Popup" wizard + Then click on "Apply_Button" element on "FilterBy_Popup" wizard + And wait load page + Then verify "Header" element not exists on "LLM_Prompts_Info_Pane" wizard + Then click on "Table_FilterBy_Button" element on "LLM_Prompts" wizard + Then "Show_Iterations_Checkbox" element should be checked on "FilterBy_Popup" wizard + + @MLLP + @smoke + Scenario: MLLP005 - Check components on prompt item infopane on Overview tab table + Given open url + And wait load page + And click on row root with value "llmdeploy332" in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "Project monitoring" value + Then verify breadcrumbs "project" label should be equal "llmdeploy332" value + And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard + And click on cell with value "LLM prompts" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard + And hover "MLRun_Logo" component on "commonPagesHeader" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "LLM prompts" value + Then verify redirection to "projects/llmdeploy332/llm-prompts?bePage=1&fePage=1" + Then verify "LLMPrompts_Table" element visibility on "LLM_Prompts" wizard + Then click on cell with row index 1 in "name" column in "LLMPrompts_Table" table on "LLM_Prompts" wizard + And wait load page + Then verify "Header" element visibility on "LLM_Prompts_Info_Pane" wizard + Then verify "Info_Pane_Tab_Selector" element visibility on "LLM_Prompts_Info_Pane" wizard + Then verify "Info_Pane_Tab_Selector" on "LLM_Prompts_Info_Pane" wizard should contains "LLM_Prompts_Info_Pane"."Tab_List" + Then verify "Overview" tab is active in "Info_Pane_Tab_Selector" on "LLM_Prompts_Info_Pane" wizard + Then verify "Header" element visibility on "LLM_Prompts_Info_Pane" wizard + Then verify "Updated" element visibility on "LLM_Prompts_Info_Pane" wizard + Then verify "Action_Menu" element visibility on "LLM_Prompts_Info_Pane" wizard + Then verify "Action_Menu" dropdown element on "LLM_Prompts_Info_Pane" wizard should contains "Common_Lists"."Action_Menu_List_LLM_Prompt" + Then select "Download" option in action menu on "LLM_Prompts_Info_Pane" wizard + And wait load page + And wait load page + Then verify "Download_Pop_Up" element visibility on "Downloads_Popup" wizard + And wait load page + Then verify "Download_Pop_Up_Cross_Cancel_Button" element visibility on "Downloads_Popup" wizard + And wait load page + Then verify "Download_Pop_Up_Cross_Cancel_Button" element visibility on "Downloads_Popup" wizard + And wait load page + Then verify "Header_Download_Pop_Up" element visibility on "Downloads_Popup" wizard + Then "Header_Download_Pop_Up" element on "Downloads_Popup" should contains "Downloads" value + Then click on "Download_Pop_Up_Cross_Cancel_Button" element on "Downloads_Popup" wizard + Then verify "Cross_Close_Button" element visibility on "LLM_Prompts_Info_Pane" wizard + Then verify "Full_View_Button" element visibility on "LLM_Prompts_Info_Pane" wizard + Then verify "Overview_General_Headers" on "LLM_Prompts_Info_Pane" wizard should contains "LLM_Prompts_Info_Pane"."Overview_General_Headers" + Then verify "Overview_Hash_Header" on "LLM_Prompts_Info_Pane" wizard should display "Label_Hint"."Overview_Hash" + Then verify "Overview_Producer_Headers" on "LLM_Prompts_Info_Pane" wizard should contains "LLM_Prompts_Info_Pane"."Overview_Producer_Headers" + Then verify "Overview_UID_Header" on "LLM_Prompts_Info_Pane" wizard should display "Label_Hint"."Overview_UID" + Then click on "Full_View_Button" element on "LLM_Prompts_Info_Pane" wizard + Then verify "Cross_Close_Button" element not exists on "LLM_Prompts_Info_Pane" wizard + Then click on "Tabel_View_Button" element on "LLM_Prompts_Info_Pane" wizard + Then verify "Cross_Close_Button" element visibility on "LLM_Prompts_Info_Pane" wizard + + @MLLP + @smoke + Scenario: MLLP006 - Verify Add a Tag, Edit a tag action and detail panel behavior after page refresh + Given open url + And wait load page + And click on row root with value "llmdeploy332" in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "Project monitoring" value + Then verify breadcrumbs "project" label should be equal "llmdeploy332" value + And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard + And click on cell with value "LLM prompts" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard + And hover "MLRun_Logo" component on "commonPagesHeader" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "LLM prompts" value + Then verify redirection to "projects/llmdeploy332/llm-prompts?bePage=1&fePage=1" + Then verify "LLMPrompts_Table" element visibility on "LLM_Prompts" wizard + Then select "Add a tag" option in action menu on "LLM_Prompts" wizard in "LLMPrompts_Table" table at row with "my_llm" value in "name" column + And wait load page + Then verify "Add_Tag_Popup" element visibility on "Add_Tag_Popup" wizard + Then type value "test" to "Tag_Input" field on "Add_Tag_Popup" wizard + Then click on "Add_Button" element on "Add_Tag_Popup" wizard + And wait load page + Then verify "Notification_Pop_Up" element visibility on "Notification_Popup" wizard + And wait load page + Then "Notification_Pop_Up" element on "Notification_Popup" should contains "Tag was added successfully" value + And wait load page + Then verify "Notification_Pop_Up_Cross_Close_Button" element visibility on "Notification_Popup" wizard + Then click on "Notification_Pop_Up_Cross_Close_Button" element on "Notification_Popup" wizard + Then verify "Table_FilterBy_Button" element on "LLM_Prompts" wizard should display hover tooltip "Common_Tooltips"."FilterBy_Button" + Then click on "Table_FilterBy_Button" element on "LLM_Prompts" wizard + Then select "test" option in "Table_Tree_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard + Then click on "Apply_Button" element on "FilterBy_Popup" wizard + And wait load page + When click on cell with value "my_llm" in "name" column in "LLMPrompts_Table" table on "LLM_Prompts" wizard + And wait load page + Then check "test" value in "tag" column in "Overview_Table" table on "LLM_Prompts_Info_Pane" wizard + Then click on "Edit_btn_table_view" element on "LLM_Prompts_Info_Pane" wizard + And wait load page + When type value "v1" to "Version_tag_Input" field on "LLM_Prompts_Info_Pane" wizard + Then click on "Apply_Button" element on "LLM_Prompts_Info_Pane" wizard + Then click on "Apply_Changes_Button" element on "LLM_Prompts_Info_Pane" wizard + And wait load page + Then verify "Info_Pane_Tab_Selector" element visibility on "LLM_Prompts_Info_Pane" wizard + Then verify "Not_In_Filtered_List_Message" element visibility on "LLM_Prompts_Info_Pane" wizard + Then "Not_In_Filtered_List_Message" component on "LLM_Prompts_Info_Pane" should be equal "LLM_Prompts_Info_Pane"."Info_Banner_Message" + Then verify "Info_Pane_Tab_Selector" element visibility on "LLM_Prompts_Info_Pane" wizard + Then verify "Info_Pane_Tab_Selector" on "LLM_Prompts_Info_Pane" wizard should contains "LLM_Prompts_Info_Pane"."Tab_List" + Then verify "Overview" tab is active in "Info_Pane_Tab_Selector" on "LLM_Prompts_Info_Pane" wizard + Then verify "Header" element visibility on "LLM_Prompts_Info_Pane" wizard + Then "Header" element on "LLM_Prompts_Info_Pane" should contains "my_llm" value + Then refresh a page + And wait load page + Then verify "Info_Pane_Tab_Selector" element visibility on "LLM_Prompts_Info_Pane" wizard + Then verify "Not_In_Filtered_List_Message" element visibility on "LLM_Prompts_Info_Pane" wizard + Then "Not_In_Filtered_List_Message" component on "LLM_Prompts_Info_Pane" should be equal "LLM_Prompts_Info_Pane"."Info_Banner_Message" + Then verify "Info_Pane_Tab_Selector" element visibility on "LLM_Prompts_Info_Pane" wizard + Then verify "Info_Pane_Tab_Selector" on "LLM_Prompts_Info_Pane" wizard should contains "LLM_Prompts_Info_Pane"."Tab_List" + Then verify "Overview" tab is active in "Info_Pane_Tab_Selector" on "LLM_Prompts_Info_Pane" wizard + Then verify "Header" element visibility on "LLM_Prompts_Info_Pane" wizard + Then "Header" element on "LLM_Prompts_Info_Pane" should contains "my_llm" value + Then verify "Refresh_Button" element visibility on "LLM_Prompts" wizard + Then verify "Refresh_Button" element on "LLM_Prompts" wizard should display hover tooltip "Common_Tooltips"."Refresh_Button" + Then click on "Refresh_Button" element on "LLM_Prompts" wizard + And wait load page + Then verify "Info_Pane_Tab_Selector" element visibility on "LLM_Prompts_Info_Pane" wizard + Then verify "Not_In_Filtered_List_Message" element visibility on "LLM_Prompts_Info_Pane" wizard + Then "Not_In_Filtered_List_Message" component on "LLM_Prompts_Info_Pane" should be equal "LLM_Prompts_Info_Pane"."Info_Banner_Message" + Then verify "Info_Pane_Tab_Selector" element visibility on "LLM_Prompts_Info_Pane" wizard + Then verify "Info_Pane_Tab_Selector" on "LLM_Prompts_Info_Pane" wizard should contains "LLM_Prompts_Info_Pane"."Tab_List" + Then verify "Overview" tab is active in "Info_Pane_Tab_Selector" on "LLM_Prompts_Info_Pane" wizard + Then verify "Header" element visibility on "LLM_Prompts_Info_Pane" wizard + Then click on "Cross_Close_Button" element on "LLM_Prompts_Info_Pane" wizard + And wait load page + Then verify "Header" element not exists on "LLM_Prompts_Info_Pane" wizard + And wait load page + And verify "No_Data_Message" element visibility on "commonPagesHeader" wizard + Then "No_Data_Message" component on "commonPagesHeader" should be equal "No_Data_Message"."Common_Message_LLM_Prompt_Tag" + Then click on "Table_FilterBy_Button" element on "LLM_Prompts" wizard + Then click on "Clear_Button" element on "FilterBy_Popup" wizard + And wait load page + When click on cell with value "my_llm" in "name" column in "LLMPrompts_Table" table on "LLM_Prompts" wizard + And wait load page + Then verify "Info_Pane_Tab_Selector" element visibility on "LLM_Prompts_Info_Pane" wizard + Then verify "Not_In_Filtered_List_Message" element not exists on "LLM_Prompts_Info_Pane" wizard + Then verify "Info_Pane_Tab_Selector" element visibility on "LLM_Prompts_Info_Pane" wizard + Then verify "Info_Pane_Tab_Selector" on "LLM_Prompts_Info_Pane" wizard should contains "LLM_Prompts_Info_Pane"."Tab_List" + Then verify "Overview" tab is active in "Info_Pane_Tab_Selector" on "LLM_Prompts_Info_Pane" wizard + Then verify "Header" element visibility on "LLM_Prompts_Info_Pane" wizard + Then click on "Table_FilterBy_Button" element on "LLM_Prompts" wizard + Then select "v1" option in "Table_Tree_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard + Then click on "Apply_Button" element on "FilterBy_Popup" wizard + And wait load page + When click on cell with value "my_llm" in "name" column in "LLMPrompts_Table" table on "LLM_Prompts" wizard + And wait load page + Then verify "Info_Pane_Tab_Selector" element visibility on "LLM_Prompts_Info_Pane" wizard + Then verify "Not_In_Filtered_List_Message" element not exists on "LLM_Prompts_Info_Pane" wizard + Then verify "Info_Pane_Tab_Selector" element visibility on "LLM_Prompts_Info_Pane" wizard + Then verify "Info_Pane_Tab_Selector" on "LLM_Prompts_Info_Pane" wizard should contains "LLM_Prompts_Info_Pane"."Tab_List" + Then verify "Overview" tab is active in "Info_Pane_Tab_Selector" on "LLM_Prompts_Info_Pane" wizard + Then verify "Header" element visibility on "LLM_Prompts_Info_Pane" wizard + + @MLLP + @smoke + Scenario: MLLP007 - Check components on prompt item infopane on Prompt Template tab table + Given open url + And wait load page + And click on row root with value "llmdeploy332" in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "Project monitoring" value + Then verify breadcrumbs "project" label should be equal "llmdeploy332" value + And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard + And click on cell with value "LLM prompts" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard + And hover "MLRun_Logo" component on "commonPagesHeader" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "LLM prompts" value + Then verify redirection to "projects/llmdeploy332/llm-prompts?bePage=1&fePage=1" + Then verify "LLMPrompts_Table" element visibility on "LLM_Prompts" wizard + Then click on cell with row index 1 in "name" column in "LLMPrompts_Table" table on "LLM_Prompts" wizard + And wait load page + Then select "Prompt Template" tab in "Info_Pane_Tab_Selector" on "LLM_Prompts_Info_Pane" wizard + And wait load page + Then verify "Prompt_Template_Tab_Selector" element visibility on "LLM_Prompts_Info_Pane" wizard + Then verify "Prompt_Template_Tab_Selector" on "LLM_Prompts_Info_Pane" wizard should contains "LLM_Prompts_Info_Pane"."Tab_List" + Then verify "Prompt Template" tab is active in "Prompt_Template_Tab_Selector" on "LLM_Prompts_Info_Pane" wizard + Then verify "Header" element visibility on "LLM_Prompts_Info_Pane" wizard + Then verify "Updated" element visibility on "LLM_Prompts_Info_Pane" wizard + Then verify "Action_Menu" element visibility on "LLM_Prompts_Info_Pane" wizard + Then verify "Action_Menu" dropdown element on "LLM_Prompts_Info_Pane" wizard should contains "Common_Lists"."Action_Menu_List_LLM_Prompt" + Then verify "Cross_Close_Button" element visibility on "LLM_Prompts_Info_Pane" wizard + Then verify "Prompt_Arguments_Tab_Selector" element visibility on "LLM_Prompts_Info_Pane" wizard + Then verify "Prompt_Arguments_Tab_Selector" on "LLM_Prompts_Info_Pane" wizard should contains "LLM_Prompts_Info_Pane"."Tab_List_Prompt_Template" + Then verify "Prompt" tab is active in "Prompt_Arguments_Tab_Selector" on "LLM_Prompts_Info_Pane" wizard + Then verify "Find_In_Prompt_Filter_Input" element visibility on "LLM_Prompts_Info_Pane" wizard + Then verify "Prompt_Template_Table" element visibility on "LLM_Prompts_Info_Pane" wizard + Then verify "Prompt_Template_Argument" element visibility on "LLM_Prompts_Info_Pane" wizard + Then "Prompt_Template_Argument" element on "LLM_Prompts_Info_Pane" should contains "{something_with_meaning}" value + Then verify "Prompt_Template_Argument" element on "LLM_Prompts_Info_Pane" wizard should display hover tooltip "Common_Tooltips"."Argument" + Then click on "Prompt_Template_Argument" element on "LLM_Prompts_Info_Pane" wizard + And wait load page + Then verify "Prompt Template" tab is active in "Prompt_Template_Tab_Selector" on "LLM_Prompts_Info_Pane" wizard + Then verify "Arguments" tab is active in "Prompt_Arguments_Tab_Selector" on "LLM_Prompts_Info_Pane" wizard + Then value in "key" column with "text" in "Arguments_Tab_Table" on "LLM_Prompts_Info_Pane" wizard should contains "word" + Then value in "value" column with "text" in "Arguments_Tab_Table" on "LLM_Prompts_Info_Pane" wizard should contains "The essence of all things" + + @MLLP + @smoke + Scenario: MLLP008 - Check components on prompt item infopane on Generation Configuration tab table + Given open url + And wait load page + And click on row root with value "llmdeploy332" in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "Project monitoring" value + Then verify breadcrumbs "project" label should be equal "llmdeploy332" value + And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard + And click on cell with value "LLM prompts" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard + And hover "MLRun_Logo" component on "commonPagesHeader" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "LLM prompts" value + Then verify redirection to "projects/llmdeploy332/llm-prompts?bePage=1&fePage=1" + Then verify "LLMPrompts_Table" element visibility on "LLM_Prompts" wizard + Then click on cell with row index 1 in "name" column in "LLMPrompts_Table" table on "LLM_Prompts" wizard + And wait load page + Then select "Generation Configuration" tab in "Info_Pane_Tab_Selector" on "LLM_Prompts_Info_Pane" wizard + And wait load page + Then verify "Prompt_Template_Tab_Selector" element visibility on "LLM_Prompts_Info_Pane" wizard + Then verify "Prompt_Template_Tab_Selector" on "LLM_Prompts_Info_Pane" wizard should contains "LLM_Prompts_Info_Pane"."Tab_List" + Then verify "Generation Configuration" tab is active in "Prompt_Template_Tab_Selector" on "LLM_Prompts_Info_Pane" wizard + Then verify "Header" element visibility on "LLM_Prompts_Info_Pane" wizard + Then verify "Updated" element visibility on "LLM_Prompts_Info_Pane" wizard + Then verify "Action_Menu" element visibility on "LLM_Prompts_Info_Pane" wizard + Then verify "Action_Menu" dropdown element on "LLM_Prompts_Info_Pane" wizard should contains "Common_Lists"."Action_Menu_List_LLM_Prompt" + Then verify "Cross_Close_Button" element visibility on "LLM_Prompts_Info_Pane" wizard + Then verify "Generation_Configuration_Counter" element visibility on "LLM_Prompts_Info_Pane" wizard + Then "Generation_Configuration_Counter" element on "LLM_Prompts_Info_Pane" should contains "1 modifications made to the default configuration:" value + Then value in "key" column with "text" in "Generation_Configuration_Tab_Table" on "LLM_Prompts_Info_Pane" wizard should contains "temperature" + Then value in "value" column with "text" in "Generation_Configuration_Tab_Table" on "LLM_Prompts_Info_Pane" wizard should contains "0.5" + + @MLLP + @smoke + Scenario: MLLP009 - Check components on prompt version history page + Given open url + And wait load page + And click on row root with value "llmdeploy332" in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "Project monitoring" value + Then verify breadcrumbs "project" label should be equal "llmdeploy332" value + And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard + And click on cell with value "LLM prompts" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard + And hover "MLRun_Logo" component on "commonPagesHeader" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "LLM prompts" value + Then verify redirection to "projects/llmdeploy332/llm-prompts?bePage=1&fePage=1" + Then verify "LLMPrompts_Table" element visibility on "LLM_Prompts" wizard + Then verify action menu on "LLM_Prompts" wizard in "LLMPrompts_Table" table with "my_llm" value in "name" column should contains "Common_Lists"."Action_Menu_List_LLM_Prompt" + Then verify "show_all_versions" option is present on "LLM_Prompts" wizard in "LLMPrompts_Table" table with "my_llm" value in "name" column + Then verify "show_all_versions" option on "LLM_Prompts" wizard in "LLMPrompts_Table" table with "my_llm" value in "name" column should display hover tooltip "Common_Tooltips"."Show_All_Versions" with scroll "false" + Then click on "show_all_versions" option on "LLM_Prompts" wizard in "LLMPrompts_Table" table with "my_llm" value in "name" column with scroll "false" + And wait load page + Then verify "History_Back_Button" element visibility on "LLM_Prompts" wizard + Then verify "Version_History_Title" element visibility on "LLM_Prompts" wizard + Then "Version_History_Title" element on "LLM_Prompts" should contains "Version history:" value + Then verify "Version_History_Prompt_Name" element visibility on "LLM_Prompts" wizard + Then "Version_History_Prompt_Name" element on "LLM_Prompts" should contains "my_llm" value + Then verify "Refresh_Button" element visibility on "LLM_Prompts" wizard + Then verify "Table_FilterBy_Button" element visibility on "LLM_Prompts" wizard + Then click on "Table_FilterBy_Button" element on "LLM_Prompts" wizard + Then "Show_Iterations_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then verify action menu on "LLM_Prompts" wizard in "LLMPrompts_Table" table with "1d459c52a1102adcbbe242e6bb36e99129f2a8b9" value in "uid" column should contains "Common_Lists"."Action_Menu_List_LLM_Prompt" + When click on cell with row index 1 in "uid" column in "LLMPrompts_Table" table on "LLM_Prompts" wizard + And wait load page + Then check "latest" value in "tag" column in "Overview_Table" table on "LLM_Prompts_Info_Pane" wizard + Then verify "Action_Menu" element visibility on "LLM_Prompts_Info_Pane" wizard + Then verify "Action_Menu" dropdown element on "LLM_Prompts_Info_Pane" wizard should contains "Common_Lists"."Action_Menu_List_LLM_Prompt" + Then verify "Header" element visibility on "LLM_Prompts_Info_Pane" wizard + Then "Header" element on "LLM_Prompts_Info_Pane" should contains "my_llm" value + Then click on "History_Back_Button" element on "LLM_Prompts" wizard + Then verify "LLMPrompts_Table" element visibility on "LLM_Prompts" wizard + + @MLLP + @smoke + Scenario: MLLP010 - Verify action menu list options on main llm prompts list + Given open url + And wait load page + And click on row root with value "llmdeploy332" in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "Project monitoring" value + Then verify breadcrumbs "project" label should be equal "llmdeploy332" value + And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard + And click on cell with value "LLM prompts" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard + And hover "MLRun_Logo" component on "commonPagesHeader" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "LLM prompts" value + Then verify redirection to "projects/llmdeploy332/llm-prompts?bePage=1&fePage=1" + Then verify "LLMPrompts_Table" element visibility on "LLM_Prompts" wizard + Then verify action menu on "LLM_Prompts" wizard in "LLMPrompts_Table" table with "my_llm" value in "name" column should contains "Common_Lists"."Action_Menu_List_LLM_Prompt" + Then select "Download" option in action menu on "LLM_Prompts" wizard in "LLMPrompts_Table" table at row with "my_llm" value in "name" column + And wait load page + And wait load page + Then verify "Download_Pop_Up" element visibility on "Downloads_Popup" wizard + And wait load page + Then verify "Download_Pop_Up_Cross_Cancel_Button" element visibility on "Downloads_Popup" wizard + And wait load page + Then verify "Header_Download_Pop_Up" element visibility on "Downloads_Popup" wizard + Then "Header_Download_Pop_Up" element on "Downloads_Popup" should contains "Downloads" value + Then click on "Download_Pop_Up_Cross_Cancel_Button" element on "Downloads_Popup" wizard + Then select "View YAML" option in action menu on "LLM_Prompts" wizard in "LLMPrompts_Table" table at row with "my_llm" value in "name" column + Then verify if "View_YAML" popup dialog appears + Then verify "Cross_Cancel_Button" element visibility on "View_YAML" wizard + Then verify "YAML_Modal_Container" element visibility on "View_YAML" wizard + Then click on "Cross_Cancel_Button" element on "View_YAML" wizard + Then select "Copy URI" option in action menu on "LLM_Prompts" wizard in "LLMPrompts_Table" table at row with "my_llm" value in "name" column + And wait load page + Then verify if "Notification_Popup" popup dialog appears + Then verify "Notification_Pop_Up" element visibility on "Notification_Popup" wizard + Then "Notification_Pop_Up" element on "Notification_Popup" should contains "Copied to clipboard successfully" value + Then verify "Notification_Pop_Up_Cross_Close_Button" element visibility on "Notification_Popup" wizard + Then click on "Notification_Pop_Up_Cross_Close_Button" element on "Notification_Popup" wizard + Then verify "LLMPrompts_Table" element visibility on "LLM_Prompts" wizard + Then click on cell with row index 1 in "name" column in "LLMPrompts_Table" table on "LLM_Prompts" wizard + And wait load page + Then verify "Header" element visibility on "LLM_Prompts_Info_Pane" wizard + Then verify "Info_Pane_Tab_Selector" element visibility on "LLM_Prompts_Info_Pane" wizard + Then verify "Action_Menu" dropdown element on "LLM_Prompts_Info_Pane" wizard should contains "Common_Lists"."Action_Menu_List_LLM_Prompt" + Then select "Download" option in action menu on "LLM_Prompts_Info_Pane" wizard + And wait load page + And wait load page + Then verify "Download_Pop_Up" element visibility on "Downloads_Popup" wizard + And wait load page + Then verify "Download_Pop_Up_Cross_Cancel_Button" element visibility on "Downloads_Popup" wizard + And wait load page + Then verify "Header_Download_Pop_Up" element visibility on "Downloads_Popup" wizard + Then "Header_Download_Pop_Up" element on "Downloads_Popup" should contains "Downloads" value + Then click on "Download_Pop_Up_Cross_Cancel_Button" element on "Downloads_Popup" wizard + Then select "View YAML" option in action menu on "LLM_Prompts_Info_Pane" wizard + Then verify if "View_YAML" popup dialog appears + Then verify "Cross_Cancel_Button" element visibility on "View_YAML" wizard + Then verify "YAML_Modal_Container" element visibility on "View_YAML" wizard + Then click on "Cross_Cancel_Button" element on "View_YAML" wizard + Then select "Copy URI" option in action menu on "LLM_Prompts_Info_Pane" wizard + And wait load page + Then verify if "Notification_Popup" popup dialog appears + Then verify "Notification_Pop_Up" element visibility on "Notification_Popup" wizard + Then "Notification_Pop_Up" element on "Notification_Popup" should contains "Copied to clipboard successfully" value + Then verify "Notification_Pop_Up_Cross_Close_Button" element visibility on "Notification_Popup" wizard + Then click on "Notification_Pop_Up_Cross_Close_Button" element on "Notification_Popup" wizard + Then click on "Cross_Close_Button" element on "LLM_Prompts_Info_Pane" wizard + Then verify "LLMPrompts_Table" element visibility on "LLM_Prompts" wizard + Then select "Add a tag" option in action menu on "LLM_Prompts" wizard in "LLMPrompts_Table" table at row with "my_llm" value in "name" column + And wait load page + Then verify "Add_Tag_Popup" element visibility on "Add_Tag_Popup" wizard + Then type value "instructions" to "Tag_Input" field on "Add_Tag_Popup" wizard + Then click on "Add_Button" element on "Add_Tag_Popup" wizard + And wait load page + Then verify "Notification_Pop_Up" element visibility on "Notification_Popup" wizard + And wait load page + Then "Notification_Pop_Up" element on "Notification_Popup" should contains "Tag was added successfully" value + And wait load page + Then verify "Notification_Pop_Up_Cross_Close_Button" element visibility on "Notification_Popup" wizard + Then click on "Notification_Pop_Up_Cross_Close_Button" element on "Notification_Popup" wizard + Then verify "Table_FilterBy_Button" element on "LLM_Prompts" wizard should display hover tooltip "Common_Tooltips"."FilterBy_Button" + Then click on "Table_FilterBy_Button" element on "LLM_Prompts" wizard + Then select "instructions" option in "Table_Tree_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard + Then click on "Apply_Button" element on "FilterBy_Popup" wizard + And wait load page + When click on cell with value "my_llm" in "name" column in "LLMPrompts_Table" table on "LLM_Prompts" wizard + And wait load page + Then check "instructions" value in "tag" column in "Overview_Table" table on "LLM_Prompts_Info_Pane" wizard + Then select "Add a tag" option in action menu on "LLM_Prompts_Info_Pane" wizard + And wait load page + Then verify "Add_Tag_Popup" element visibility on "Add_Tag_Popup" wizard + Then type value "criteria" to "Tag_Input" field on "Add_Tag_Popup" wizard + Then click on "Add_Button" element on "Add_Tag_Popup" wizard + And wait load page + Then verify "Notification_Pop_Up" element visibility on "Notification_Popup" wizard + And wait load page + Then "Notification_Pop_Up" element on "Notification_Popup" should contains "Tag was added successfully" value + And wait load page + Then verify "Notification_Pop_Up_Cross_Close_Button" element visibility on "Notification_Popup" wizard + Then click on "Notification_Pop_Up_Cross_Close_Button" element on "Notification_Popup" wizard + Then verify "Table_FilterBy_Button" element on "LLM_Prompts" wizard should display hover tooltip "Common_Tooltips"."FilterBy_Button_1" + Then click on "Table_FilterBy_Button" element on "LLM_Prompts" wizard + Then select "criteria" option in "Table_Tree_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard + Then click on "Apply_Button" element on "FilterBy_Popup" wizard + And wait load page + When click on cell with value "my_llm" in "name" column in "LLMPrompts_Table" table on "LLM_Prompts" wizard + And wait load page + Then check "criteria" value in "tag" column in "Overview_Table" table on "LLM_Prompts_Info_Pane" wizard + + @MLLP + @smoke + Scenario: MLLP011 - Verify action menu list options on version history llm prompts list + Given open url + And wait load page + And click on row root with value "llmdeploy332" in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "Project monitoring" value + Then verify breadcrumbs "project" label should be equal "llmdeploy332" value + And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard + And click on cell with value "LLM prompts" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard + And hover "MLRun_Logo" component on "commonPagesHeader" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "LLM prompts" value + Then verify redirection to "projects/llmdeploy332/llm-prompts?bePage=1&fePage=1" + Then verify "LLMPrompts_Table" element visibility on "LLM_Prompts" wizard + Then verify "show_all_versions" option is present on "LLM_Prompts" wizard in "LLMPrompts_Table" table with "my_llm" value in "name" column + Then verify "show_all_versions" option on "LLM_Prompts" wizard in "LLMPrompts_Table" table with "my_llm" value in "name" column should display hover tooltip "Common_Tooltips"."Show_All_Versions" with scroll "false" + Then click on "show_all_versions" option on "LLM_Prompts" wizard in "LLMPrompts_Table" table with "my_llm" value in "name" column with scroll "false" + And wait load page + Then verify "History_Back_Button" element visibility on "LLM_Prompts" wizard + Then "Version_History_Prompt_Name" element on "LLM_Prompts" should contains "my_llm" value + Then verify "Refresh_Button" element visibility on "LLM_Prompts" wizard + Then verify "Table_FilterBy_Button" element visibility on "LLM_Prompts" wizard + Then click on "Table_FilterBy_Button" element on "LLM_Prompts" wizard + Then "Show_Iterations_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then verify action menu on "LLM_Prompts" wizard in "LLMPrompts_Table" table with "1d459c52a1102adcbbe242e6bb36e99129f2a8b9" value in "uid" column should contains "Common_Lists"."Action_Menu_List_LLM_Prompt" + Then verify action menu on "LLM_Prompts" wizard in "LLMPrompts_Table" table with "1d459c52a1102adcbbe242e6bb36e99129f2a8b9" value in "uid" column should contains "Common_Lists"."Action_Menu_List_LLM_Prompt" + Then select "Download" option in action menu on "LLM_Prompts" wizard in "LLMPrompts_Table" table at row with "1d459c52a1102adcbbe242e6bb36e99129f2a8b9" value in "uid" column + And wait load page + And wait load page + Then verify "Download_Pop_Up" element visibility on "Downloads_Popup" wizard + And wait load page + Then verify "Download_Pop_Up_Cross_Cancel_Button" element visibility on "Downloads_Popup" wizard + And wait load page + Then verify "Header_Download_Pop_Up" element visibility on "Downloads_Popup" wizard + Then "Header_Download_Pop_Up" element on "Downloads_Popup" should contains "Downloads" value + Then click on "Download_Pop_Up_Cross_Cancel_Button" element on "Downloads_Popup" wizard + Then select "View YAML" option in action menu on "LLM_Prompts" wizard in "LLMPrompts_Table" table at row with "1d459c52a1102adcbbe242e6bb36e99129f2a8b9" value in "uid" column + Then verify if "View_YAML" popup dialog appears + Then verify "Cross_Cancel_Button" element visibility on "View_YAML" wizard + Then verify "YAML_Modal_Container" element visibility on "View_YAML" wizard + Then click on "Cross_Cancel_Button" element on "View_YAML" wizard + Then select "Copy URI" option in action menu on "LLM_Prompts" wizard in "LLMPrompts_Table" table at row with "1d459c52a1102adcbbe242e6bb36e99129f2a8b9" value in "uid" column + And wait load page + Then verify if "Notification_Popup" popup dialog appears + Then verify "Notification_Pop_Up" element visibility on "Notification_Popup" wizard + Then "Notification_Pop_Up" element on "Notification_Popup" should contains "Copied to clipboard successfully" value + Then verify "Notification_Pop_Up_Cross_Close_Button" element visibility on "Notification_Popup" wizard + Then click on "Notification_Pop_Up_Cross_Close_Button" element on "Notification_Popup" wizard + Then verify "History_Back_Button" element visibility on "LLM_Prompts" wizard + Then verify "LLMPrompts_Table" element visibility on "LLM_Prompts" wizard + When click on cell with row index 1 in "uid" column in "LLMPrompts_Table" table on "LLM_Prompts" wizard + And wait load page + Then verify "Header" element visibility on "LLM_Prompts_Info_Pane" wizard + Then verify "Info_Pane_Tab_Selector" element visibility on "LLM_Prompts_Info_Pane" wizard + Then verify "Action_Menu" dropdown element on "LLM_Prompts_Info_Pane" wizard should contains "Common_Lists"."Action_Menu_List_LLM_Prompt" + Then select "Download" option in action menu on "LLM_Prompts_Info_Pane" wizard + And wait load page + And wait load page + Then verify "Download_Pop_Up" element visibility on "Downloads_Popup" wizard + And wait load page + Then verify "Download_Pop_Up_Cross_Cancel_Button" element visibility on "Downloads_Popup" wizard + And wait load page + Then verify "Header_Download_Pop_Up" element visibility on "Downloads_Popup" wizard + Then "Header_Download_Pop_Up" element on "Downloads_Popup" should contains "Downloads" value + Then click on "Download_Pop_Up_Cross_Cancel_Button" element on "Downloads_Popup" wizard + Then select "View YAML" option in action menu on "LLM_Prompts_Info_Pane" wizard + Then verify if "View_YAML" popup dialog appears + Then verify "Cross_Cancel_Button" element visibility on "View_YAML" wizard + Then verify "YAML_Modal_Container" element visibility on "View_YAML" wizard + Then click on "Cross_Cancel_Button" element on "View_YAML" wizard + Then select "Copy URI" option in action menu on "LLM_Prompts_Info_Pane" wizard + And wait load page + Then verify if "Notification_Popup" popup dialog appears + Then verify "Notification_Pop_Up" element visibility on "Notification_Popup" wizard + Then "Notification_Pop_Up" element on "Notification_Popup" should contains "Copied to clipboard successfully" value + Then verify "Notification_Pop_Up_Cross_Close_Button" element visibility on "Notification_Popup" wizard + Then click on "Notification_Pop_Up_Cross_Close_Button" element on "Notification_Popup" wizard + Then click on "Cross_Close_Button" element on "LLM_Prompts_Info_Pane" wizard + Then verify "History_Back_Button" element visibility on "LLM_Prompts" wizard + Then verify "LLMPrompts_Table" element visibility on "LLM_Prompts" wizard + Then select "Add a tag" option in action menu on "LLM_Prompts" wizard in "LLMPrompts_Table" table at row with "1d459c52a1102adcbbe242e6bb36e99129f2a8b9" value in "uid" column + And wait load page + Then verify "Add_Tag_Popup" element visibility on "Add_Tag_Popup" wizard + Then type value "context" to "Tag_Input" field on "Add_Tag_Popup" wizard + Then click on "Add_Button" element on "Add_Tag_Popup" wizard + And wait load page + Then verify "Notification_Pop_Up" element visibility on "Notification_Popup" wizard + And wait load page + Then "Notification_Pop_Up" element on "Notification_Popup" should contains "Tag was added successfully" value + And wait load page + Then verify "Notification_Pop_Up_Cross_Close_Button" element visibility on "Notification_Popup" wizard + Then click on "Notification_Pop_Up_Cross_Close_Button" element on "Notification_Popup" wizard + Then verify "Table_FilterBy_Button" element on "LLM_Prompts" wizard should display hover tooltip "Common_Tooltips"."FilterBy_Button" + Then click on "Table_FilterBy_Button" element on "LLM_Prompts" wizard + Then select "context" option in "Table_Tree_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard + Then click on "Apply_Button" element on "FilterBy_Popup" wizard + And wait load page + When click on cell with value "1d459c52a1102adcbbe242e6bb36e99129f2a8b9" in "uid" column in "LLMPrompts_Table" table on "LLM_Prompts" wizard + And wait load page + Then check "context" value in "tag" column in "Overview_Table" table on "LLM_Prompts_Info_Pane" wizard + Then select "Add a tag" option in action menu on "LLM_Prompts_Info_Pane" wizard + And wait load page + Then verify "Add_Tag_Popup" element visibility on "Add_Tag_Popup" wizard + Then type value "Final_Answer" to "Tag_Input" field on "Add_Tag_Popup" wizard + Then click on "Add_Button" element on "Add_Tag_Popup" wizard + And wait load page + Then verify "Notification_Pop_Up" element visibility on "Notification_Popup" wizard + And wait load page + Then "Notification_Pop_Up" element on "Notification_Popup" should contains "Tag was added successfully" value + And wait load page + Then verify "Notification_Pop_Up_Cross_Close_Button" element visibility on "Notification_Popup" wizard + Then click on "Notification_Pop_Up_Cross_Close_Button" element on "Notification_Popup" wizard + Then verify "Table_FilterBy_Button" element on "LLM_Prompts" wizard should display hover tooltip "Common_Tooltips"."FilterBy_Button_1" + Then click on "Table_FilterBy_Button" element on "LLM_Prompts" wizard + Then select "Final_Answer" option in "Table_Tree_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard + Then click on "Apply_Button" element on "FilterBy_Popup" wizard + And wait load page + When click on cell with value "1d459c52a1102adcbbe242e6bb36e99129f2a8b9" in "uid" column in "LLMPrompts_Table" table on "LLM_Prompts" wizard + And wait load page + Then check "Final_Answer" value in "tag" column in "Overview_Table" table on "LLM_Prompts_Info_Pane" wizard + + @MLLP + @smoke + #TODO: verify 'Add a Tag' behavior in Version History page when overwriting an existing prompt instance + Scenario: MLLP012 - Verify overwrite Add a tag option in action menu on llm prompts list + Given open url + And wait load page + And click on row root with value "llmdeploy332" in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "Project monitoring" value + Then verify breadcrumbs "project" label should be equal "llmdeploy332" value + And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard + And click on cell with value "LLM prompts" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard + And hover "MLRun_Logo" component on "commonPagesHeader" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "LLM prompts" value + Then verify redirection to "projects/llmdeploy332/llm-prompts?bePage=1&fePage=1" + Then verify "LLMPrompts_Table" element visibility on "LLM_Prompts" wizard + Then select "Add a tag" option in action menu on "LLM_Prompts" wizard in "LLMPrompts_Table" table at row with "my_llm" value in "name" column + And wait load page + Then verify "Add_Tag_Popup" element visibility on "Add_Tag_Popup" wizard + Then type value "latest" to "Tag_Input" field on "Add_Tag_Popup" wizard + Then click on "Add_Button" element on "Add_Tag_Popup" wizard + And wait load page + Then verify "Add_Button" element on "Add_Tag_Popup" wizard is disabled + Then type value "system" to "Tag_Input" field on "Add_Tag_Popup" wizard + Then click on "Add_Button" element on "Add_Tag_Popup" wizard + And wait load page + Then verify "Notification_Pop_Up" element visibility on "Notification_Popup" wizard + And wait load page + Then "Notification_Pop_Up" element on "Notification_Popup" should contains "Tag was added successfully" value + And wait load page + Then verify "Notification_Pop_Up_Cross_Close_Button" element visibility on "Notification_Popup" wizard + Then click on "Notification_Pop_Up_Cross_Close_Button" element on "Notification_Popup" wizard + Then select "Add a tag" option in action menu on "LLM_Prompts" wizard in "LLMPrompts_Table" table at row with "my_llm" value in "name" column + And wait load page + Then verify "Add_Tag_Popup" element visibility on "Add_Tag_Popup" wizard + Then type value "system" to "Tag_Input" field on "Add_Tag_Popup" wizard + Then click on "Add_Button" element on "Add_Tag_Popup" wizard + And wait load page + Then verify if "Confirm_Popup" popup dialog appears + Then "Title" element on "Confirm_Popup" should contains "Overwrite LLM prompt?" value + Then verify "Cross_Cancel_Button" element visibility on "Confirm_Popup" wizard + Then verify "Confirm_Dialog_Message" element visibility on "Confirm_Popup" wizard + Then "Confirm_Dialog_Message" component on "Confirm_Popup" should be equal "Descriptions"."Add_A_Tag_Overwrite_Message" + Then verify "Cancel_Button" element visibility on "Confirm_Popup" wizard + Then "Cancel_Button" element on "Confirm_Popup" should contains "Cancel" value + Then verify "Overwrite_Button" element visibility on "Confirm_Popup" wizard + Then "Overwrite_Button" element on "Confirm_Popup" should contains "Overwrite" value + When click on "Cancel_Button" element on "Confirm_Popup" wizard + When click on "Cancel_Button" element on "Add_Tag_Popup" wizard + Then verify if "Common_Popup" popup dialog appears + Then "Title" element on "Common_Popup" should contains "Are you sure?" value + Then "Description" element on "Common_Popup" should contains "All changes will be lost" value + Then click on "Confirm_Button" element on "Common_Popup" wizard + Then select "Add a tag" option in action menu on "LLM_Prompts" wizard in "LLMPrompts_Table" table at row with "my_llm" value in "name" column + And wait load page + Then verify "Add_Tag_Popup" element visibility on "Add_Tag_Popup" wizard + Then type value "system" to "Tag_Input" field on "Add_Tag_Popup" wizard + Then click on "Add_Button" element on "Add_Tag_Popup" wizard + Then verify if "Confirm_Popup" popup dialog appears + Then "Title" element on "Confirm_Popup" should contains "Overwrite LLM prompt?" value + Then verify "Cross_Cancel_Button" element visibility on "Confirm_Popup" wizard + Then verify "Confirm_Dialog_Message" element visibility on "Confirm_Popup" wizard + Then "Confirm_Dialog_Message" component on "Confirm_Popup" should be equal "Descriptions"."Add_A_Tag_Overwrite_Message" + Then verify "Cancel_Button" element visibility on "Confirm_Popup" wizard + Then "Cancel_Button" element on "Confirm_Popup" should contains "Cancel" value + Then verify "Overwrite_Button" element visibility on "Confirm_Popup" wizard + Then "Overwrite_Button" element on "Confirm_Popup" should contains "Overwrite" value + When click on "Overwrite_Button" element on "Confirm_Popup" wizard + And wait load page + Then verify "Notification_Pop_Up" element visibility on "Notification_Popup" wizard + And wait load page + Then "Notification_Pop_Up" element on "Notification_Popup" should contains "Tag was added successfully" value + And wait load page + Then verify "Notification_Pop_Up_Cross_Close_Button" element visibility on "Notification_Popup" wizard + Then click on "Notification_Pop_Up_Cross_Close_Button" element on "Notification_Popup" wizard + + @MLLP + @smoke + Scenario: MLLP013 - Verify prompt preview option on the main an version history llm prompts lists + Given open url + And wait load page + And click on row root with value "llmdeploy332" in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "Project monitoring" value + Then verify breadcrumbs "project" label should be equal "llmdeploy332" value + And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard + And click on cell with value "LLM prompts" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard + And hover "MLRun_Logo" component on "commonPagesHeader" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "LLM prompts" value + Then verify redirection to "projects/llmdeploy332/llm-prompts?bePage=1&fePage=1" + Then verify "LLMPrompts_Table" element visibility on "LLM_Prompts" wizard + Then verify "preview" option is present on "LLM_Prompts" wizard in "LLMPrompts_Table" table with "my_llm" value in "name" column + Then click on "preview" option on "LLM_Prompts" wizard in "LLMPrompts_Table" table with "my_llm" value in "name" column with scroll "false" + And wait load page + Then verify if "Preview_Popup" popup dialog appears + Then verify "Cross_Cancel_Button" element visibility on "Preview_Popup" wizard + Then verify "Preview_Modal_Container" element visibility on "Preview_Popup" wizard + Then verify "Download_Button" element visibility on "Preview_Popup" wizard + Then click on "Download_Button" element on "Preview_Popup" wizard + And wait load page + And wait load page + Then verify "Download_Pop_Up" element visibility on "Downloads_Popup" wizard + And wait load page + Then verify "Download_Pop_Up_Cross_Cancel_Button" element visibility on "Downloads_Popup" wizard + And wait load page + Then verify "Header_Download_Pop_Up" element visibility on "Downloads_Popup" wizard + Then "Header_Download_Pop_Up" element on "Downloads_Popup" should contains "Downloads" value + Then click on "Download_Pop_Up_Cross_Cancel_Button" element on "Downloads_Popup" wizard + Then verify visibility of header column "name" in "Preview_Table" table on "Preview_Popup" wizard + Then check "Name" header value in "name" column in "Preview_Table" table on "Preview_Popup" wizard + Then verify visibility of header column "path" in "Preview_Table" table on "Preview_Popup" wizard + Then check "Path" header value in "path" column in "Preview_Table" table on "Preview_Popup" wizard + Then verify visibility of header column "size" in "Preview_Table" table on "Preview_Popup" wizard + Then check "Size" header value in "size" column in "Preview_Table" table on "Preview_Popup" wizard + Then verify visibility of header column "updated" in "Preview_Table" table on "Preview_Popup" wizard + Then check "Updated" header value in "updated" column in "Preview_Table" table on "Preview_Popup" wizard + Then click on "Cross_Cancel_Button" element on "Preview_Popup" wizard + Then verify "show_all_versions" option is present on "LLM_Prompts" wizard in "LLMPrompts_Table" table with "my_llm" value in "name" column + Then click on "show_all_versions" option on "LLM_Prompts" wizard in "LLMPrompts_Table" table with "my_llm" value in "name" column with scroll "false" + And wait load page + Then verify "History_Back_Button" element visibility on "LLM_Prompts" wizard + Then "Version_History_Prompt_Name" element on "LLM_Prompts" should contains "my_llm" value + Then verify "preview" option is present on "LLM_Prompts" wizard in "LLMPrompts_Table" table with "1d459c52a1102adcbbe242e6bb36e99129f2a8b9" value in "uid" column + Then click on "preview" option on "LLM_Prompts" wizard in "LLMPrompts_Table" table with "1d459c52a1102adcbbe242e6bb36e99129f2a8b9" value in "uid" column with scroll "false" + And wait load page + Then verify if "Preview_Popup" popup dialog appears + Then verify "Cross_Cancel_Button" element visibility on "Preview_Popup" wizard + Then verify "Preview_Modal_Container" element visibility on "Preview_Popup" wizard + Then verify "Download_Button" element visibility on "Preview_Popup" wizard + Then click on "Download_Button" element on "Preview_Popup" wizard + And wait load page + And wait load page + Then verify "Download_Pop_Up" element visibility on "Downloads_Popup" wizard + And wait load page + Then verify "Download_Pop_Up_Cross_Cancel_Button" element visibility on "Downloads_Popup" wizard + And wait load page + Then verify "Header_Download_Pop_Up" element visibility on "Downloads_Popup" wizard + Then "Header_Download_Pop_Up" element on "Downloads_Popup" should contains "Downloads" value + Then click on "Download_Pop_Up_Cross_Cancel_Button" element on "Downloads_Popup" wizard + Then verify visibility of header column "name" in "Preview_Table" table on "Preview_Popup" wizard + Then check "Name" header value in "name" column in "Preview_Table" table on "Preview_Popup" wizard + Then verify visibility of header column "path" in "Preview_Table" table on "Preview_Popup" wizard + Then check "Path" header value in "path" column in "Preview_Table" table on "Preview_Popup" wizard + Then verify visibility of header column "size" in "Preview_Table" table on "Preview_Popup" wizard + Then check "Size" header value in "size" column in "Preview_Table" table on "Preview_Popup" wizard + Then verify visibility of header column "updated" in "Preview_Table" table on "Preview_Popup" wizard + Then check "Updated" header value in "updated" column in "Preview_Table" table on "Preview_Popup" wizard + Then click on "Cross_Cancel_Button" element on "Preview_Popup" wizard + Then verify "LLMPrompts_Table" element visibility on "LLM_Prompts" wizard + + @MLLP + @smoke + Scenario: MLLP014 - Verify prompt filtering by model name and tag + Given open url + And wait load page + And click on row root with value "auto-generated-data" in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "Project monitoring" value + Then verify breadcrumbs "project" label should be equal "auto-generated-data" value + And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard + And click on cell with value "LLM prompts" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard + And hover "MLRun_Logo" component on "commonPagesHeader" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "LLM prompts" value + Then verify redirection to "projects/auto-generated-data/llm-prompts?bePage=1&fePage=1" + Then click on "Table_FilterBy_Button" element on "LLM_Prompts" wizard + Then verify "Model_Name_Filter_Input" element visibility on "FilterBy_Popup" wizard + Then verify "Model_Version_Tag_Filter_Input" element visibility on "FilterBy_Popup" wizard + Then verify "Model_Version_Tag_Filter_Field" element on "FilterBy_Popup" wizard is disabled by class name + Then type value "model_8" to "Model_Name_Filter_Input" field on "FilterBy_Popup" wizard + Then verify "Model_Version_Tag_Filter_Field" element on "FilterBy_Popup" wizard is enabled by class name + Then click on "Apply_Button" element on "FilterBy_Popup" wizard + And wait load page + Then verify "Table_FilterBy_Button" element on "LLM_Prompts" wizard should display hover tooltip "Common_Tooltips"."FilterBy_Button_1" + Then verify "LLMPrompts_Table" element visibility on "LLM_Prompts" wizard + Then value in "model_name" column with "text" in "LLMPrompts_Table" on "LLM_Prompts" wizard should contains "model_8" + And wait load page + Then click on "Table_FilterBy_Button" element on "LLM_Prompts" wizard + Then type value "v1" to "Model_Version_Tag_Filter_Input" field on "FilterBy_Popup" wizard + Then click on "Apply_Button" element on "FilterBy_Popup" wizard + And wait load page + Then verify "Table_FilterBy_Button" element on "LLM_Prompts" wizard should display hover tooltip "Common_Tooltips"."FilterBy_Button_2" + Then verify "LLMPrompts_Table" element visibility on "LLM_Prompts" wizard + Then value in "model_tag" column with "text" in "LLMPrompts_Table" on "LLM_Prompts" wizard should contains "v1" + And wait load page + Then click on "Table_FilterBy_Button" element on "LLM_Prompts" wizard + Then type value "" to "Model_Name_Filter_Input" field on "FilterBy_Popup" wizard + Then verify "Model_Version_Tag_Filter_Field" element on "FilterBy_Popup" wizard is disabled by class name + Then click on "Apply_Button" element on "FilterBy_Popup" wizard + And wait load page + Then verify "Table_FilterBy_Button" element on "LLM_Prompts" wizard should display hover tooltip "Common_Tooltips"."FilterBy_Button" + And wait load page + And select "project" with "llmdeploy332" value in breadcrumbs menu + And wait load page + Then click on "Table_FilterBy_Button" element on "LLM_Prompts" wizard + Then type value "model_art1" to "Model_Name_Filter_Input" field on "FilterBy_Popup" wizard + Then click on "Apply_Button" element on "FilterBy_Popup" wizard + And wait load page + Then verify "Table_FilterBy_Button" element on "LLM_Prompts" wizard should display hover tooltip "Common_Tooltips"."FilterBy_Button_1" + Then verify "LLMPrompts_Table" element visibility on "LLM_Prompts" wizard + Then value in "model_name" column with "text" in "LLMPrompts_Table" on "LLM_Prompts" wizard should contains "model_art1" + And wait load page + Then click on "Table_FilterBy_Button" element on "LLM_Prompts" wizard + Then type value "model_art1" to "Model_Name_Filter_Input" field on "FilterBy_Popup" wizard + Then type value "v2" to "Model_Version_Tag_Filter_Input" field on "FilterBy_Popup" wizard + Then click on "Apply_Button" element on "FilterBy_Popup" wizard + And wait load page + And verify "No_Data_Message" element visibility on "commonPagesHeader" wizard + Then "No_Data_Message" component on "commonPagesHeader" should be equal "No_Data_Message"."Common_Message_LLM_Prompt_Model_Name_Tag" + + @MLLP + @smoke + Scenario: MLLP015 - Verify model detail popup from the LLM promts table list + Given open url + And wait load page + And click on row root with value "llmdeploy332" in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "Project monitoring" value + Then verify breadcrumbs "project" label should be equal "llmdeploy332" value + And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard + And click on cell with value "LLM prompts" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard + And hover "MLRun_Logo" component on "commonPagesHeader" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "LLM prompts" value + Then verify redirection to "projects/llmdeploy332/llm-prompts?bePage=1&fePage=1" + Then verify "LLMPrompts_Table" element visibility on "LLM_Prompts" wizard + When click on cell with value "model_art1" in "model_name" column in "LLMPrompts_Table" table on "LLM_Prompts" wizard + And wait load page + Then verify if "Modal_Transition_Popup" popup dialog appears + Then verify "Title" element visibility on "Modal_Transition_Popup" wizard + Then "Title" element on "Modal_Transition_Popup" should contains "model_art1" value + Then verify "Data_Status" element visibility on "Modal_Transition_Popup" wizard + Then verify "Refresh_Button" element visibility on "Modal_Transition_Popup" wizard + Then verify "Refresh_Button" element on "Modal_Transition_Popup" wizard should display hover tooltip "Common_Tooltips"."Refresh_Button" + Then click on "Refresh_Button" element on "Modal_Transition_Popup" wizard + And wait load page + Then verify "Refresh_Button" element visibility on "Modal_Transition_Popup" wizard + Then verify "Action_Menu" element visibility on "Modal_Transition_Popup" wizard + Then verify "Action_Menu" dropdown element on "Modal_Transition_Popup" wizard should contains "Common_Lists"."Action_Menu_List_Dataset_Transition_Popup" + Then select "View YAML" option in action menu on "Modal_Transition_Popup" wizard + And wait load page + Then verify if "View_YAML" popup dialog appears + Then verify "Cross_Cancel_Button" element visibility on "View_YAML" wizard + Then verify "YAML_Modal_Container" element visibility on "View_YAML" wizard + Then click on "Cross_Cancel_Button" element on "View_YAML" wizard + And wait load page + Then select "Copy URI" option in action menu on "Modal_Transition_Popup" wizard + And wait load page + Then verify if "Notification_Popup" popup dialog appears + Then verify "Notification_Pop_Up" element visibility on "Notification_Popup" wizard + Then "Notification_Pop_Up" element on "Notification_Popup" should contains "Copied to clipboard successfully" value + Then verify "Notification_Pop_Up_Cross_Close_Button" element visibility on "Notification_Popup" wizard + Then click on "Notification_Pop_Up_Cross_Close_Button" element on "Notification_Popup" wizard + Then select "Download" option in action menu on "Modal_Transition_Popup" wizard + And wait load page + And wait load page + Then verify "Download_Pop_Up" element visibility on "Downloads_Popup" wizard + And wait load page + Then verify "Download_Pop_Up_Cross_Cancel_Button" element visibility on "Downloads_Popup" wizard + And wait load page + Then verify "Download_Pop_Up_Cross_Cancel_Button" element visibility on "Downloads_Popup" wizard + And wait load page + Then verify "Header_Download_Pop_Up" element visibility on "Downloads_Popup" wizard + Then "Header_Download_Pop_Up" element on "Downloads_Popup" should contains "Downloads" value + Then click on "Download_Pop_Up_Cross_Cancel_Button" element on "Downloads_Popup" wizard + Then verify "Tab_Selector" element visibility on "Modal_Transition_Popup" wizard + Then verify "Tab_Selector" on "Modal_Transition_Popup" wizard should contains "Models_Info_Pane"."Tab_List_Two_Tabs" + Then verify "Overview" tab is active in "Tab_Selector" on "Modal_Transition_Popup" wizard + Then verify "Overview_General_Headers" on "Modal_Transition_Popup" wizard should contains "Models_Info_Pane"."Overview_General_Headers" + Then verify "Overview_Producer_Headers" on "Modal_Transition_Popup" wizard should contains "Models_Info_Pane"."Overview_Producer_Headers_Kind_Project" + And select "Preview" tab in "Tab_Selector" on "Modal_Transition_Popup" wizard + Then verify "Preview" tab is active in "Tab_Selector" on "Modal_Transition_Popup" wizard + Then verify "Pop_Out_Button" element visibility on "Modal_Transition_Popup" wizard + Then click on "Pop_Out_Button" element on "Modal_Transition_Popup" wizard + And wait load page + Then verify "Preview_Table" element visibility on "Preview_Popup" wizard + Then verify visibility of header column "name" in "Preview_Table" table on "Preview_Popup" wizard + Then check "Name" header value in "name" column in "Preview_Table" table on "Preview_Popup" wizard + Then verify visibility of header column "path" in "Preview_Table" table on "Preview_Popup" wizard + Then check "Path" header value in "path" column in "Preview_Table" table on "Preview_Popup" wizard + Then verify visibility of header column "size" in "Preview_Table" table on "Preview_Popup" wizard + Then check "Size" header value in "size" column in "Preview_Table" table on "Preview_Popup" wizard + Then verify visibility of header column "updated" in "Preview_Table" table on "Preview_Popup" wizard + Then check "Updated" header value in "updated" column in "Preview_Table" table on "Preview_Popup" wizard + Then value in "name" column with "text" in "Preview_Table" on "Preview_Popup" wizard should contains "model_art1" + Then verify "Cross_Cancel_Button" element visibility on "Preview_Popup" wizard + Then verify "Download_Button" element visibility on "Preview_Popup" wizard + Then click on "Download_Button" element on "Preview_Popup" wizard + And wait load page + And wait load page + Then verify "Download_Pop_Up" element visibility on "Downloads_Popup" wizard + And wait load page + Then verify "Download_Pop_Up_Cross_Cancel_Button" element visibility on "Downloads_Popup" wizard + And wait load page + Then verify "Header_Download_Pop_Up" element visibility on "Downloads_Popup" wizard + Then "Header_Download_Pop_Up" element on "Downloads_Popup" should contains "Downloads" value + Then click on "Download_Pop_Up_Cross_Cancel_Button" element on "Downloads_Popup" wizard + Then click on "Cross_Cancel_Button" element on "Preview_Popup" wizard + Then verify "Cross_Close_Button" element visibility on "Modal_Transition_Popup" wizard + Then click on "Cross_Close_Button" element on "Modal_Transition_Popup" wizard + And wait load page + When click on cell with value "model_art1" in "model_name" column in "LLMPrompts_Table" table on "LLM_Prompts" wizard + And wait load page + Then verify if "Modal_Transition_Popup" popup dialog appears + Then verify "Title" element visibility on "Modal_Transition_Popup" wizard + Then "Title" element on "Modal_Transition_Popup" should contains "model_art1" value + Then click on "Cross_Close_Button" element on "Modal_Transition_Popup" wizard + And wait load page + Then verify "LLMPrompts_Table" element visibility on "LLM_Prompts" wizard diff --git a/tests/features/models.feature b/tests/features/models.feature index f1594e4d89..bcda7c3fd1 100644 --- a/tests/features/models.feature +++ b/tests/features/models.feature @@ -74,6 +74,10 @@ Feature: Models Page Then verify "Table_FilterBy_Button" element on "Model_Endpoints" wizard should display hover tooltip "Common_Tooltips"."FilterBy_Button" Then click on "Table_FilterBy_Button" element on "Model_Endpoints" wizard Then verify "Table_Label_Filter_Input" element visibility on "FilterBy_Popup" wizard + Then verify "Mode_Filter_Dropdown" element visibility on "FilterBy_Popup" wizard + Then verify "Mode_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" + Then verify "Mode_Filter_Dropdown" dropdown element on "FilterBy_Popup" wizard should contains "Dropdown_Options"."Endpoint_Mode_Filter_Options" + And wait load page Then verify "Apply_Button" element visibility on "FilterBy_Popup" wizard Then verify "Apply_Button" element on "FilterBy_Popup" wizard is disabled Then verify "Clear_Button" element visibility on "FilterBy_Popup" wizard @@ -676,10 +680,19 @@ Feature: Models Page Then verify "Pop_Out_Button" element visibility on "Models_Info_Pane" wizard Then click on "Pop_Out_Button" element on "Models_Info_Pane" wizard And wait load page - Then verify "Preview_Row" element visibility on "Artifact_Preview_Popup" wizard - Then verify "Cross_Cancel_Button" element visibility on "Artifact_Preview_Popup" wizard - Then check "download_btn" visibility in "Preview_Row" on "Artifact_Preview_Popup" wizard with 1 offset - Then click on "Download_Button" element on "Artifact_Preview_Popup" wizard + Then verify "Preview_Table" element visibility on "Preview_Popup" wizard + Then verify visibility of header column "name" in "Preview_Table" table on "Preview_Popup" wizard + Then check "Name" header value in "name" column in "Preview_Table" table on "Preview_Popup" wizard + Then verify visibility of header column "path" in "Preview_Table" table on "Preview_Popup" wizard + Then check "Path" header value in "path" column in "Preview_Table" table on "Preview_Popup" wizard + Then verify visibility of header column "size" in "Preview_Table" table on "Preview_Popup" wizard + Then check "Size" header value in "size" column in "Preview_Table" table on "Preview_Popup" wizard + Then verify visibility of header column "updated" in "Preview_Table" table on "Preview_Popup" wizard + Then check "Updated" header value in "updated" column in "Preview_Table" table on "Preview_Popup" wizard + Then value in "name" column with "text" in "Preview_Table" on "Preview_Popup" wizard should contains "transaction_fraud_xgboost" + Then verify "Cross_Cancel_Button" element visibility on "Preview_Popup" wizard + Then verify "Download_Button" element visibility on "Preview_Popup" wizard + Then click on "Download_Button" element on "Preview_Popup" wizard And wait load page And wait load page Then verify "Download_Pop_Up" element visibility on "Downloads_Popup" wizard @@ -689,7 +702,7 @@ Feature: Models Page Then verify "Header_Download_Pop_Up" element visibility on "Downloads_Popup" wizard Then "Header_Download_Pop_Up" element on "Downloads_Popup" should contains "Downloads" value Then click on "Download_Pop_Up_Cross_Cancel_Button" element on "Downloads_Popup" wizard - Then click on "Cross_Cancel_Button" element on "Artifact_Preview_Popup" wizard + Then click on "Cross_Cancel_Button" element on "Preview_Popup" wizard @MLM @passive @@ -838,26 +851,103 @@ Feature: Models Page And wait load page Then verify "Header" element visibility on "Models_Info_Pane" wizard Then "Header" element on "Models_Info_Pane" should contains "test-model" value + Then click on "Table_FilterBy_Button" element on "Models" wizard + Then click on "Clear_Button" element on "FilterBy_Popup" wizard + And wait load page + When click on cell with value "train_model" in "name" column in "Models_Table" table on "Models" wizard + And wait load page + Then verify "Overview" tab is active in "Info_Pane_Tab_Selector" on "Models_Info_Pane" wizard + Then verify "Overview_Producer_Headers" on "Models_Info_Pane" wizard should contains "Models_Info_Pane"."Overview_Producer_Headers" + When click on cell with value "sk-project-admin/3d03c190ad57442099024be6bb8f5895-3" in "producer_link" column in "Overview_Producer_Headers" table on "Models_Info_Pane" wizard + And wait load page + Then verify if "Modal_Transition_Popup" popup dialog appears + Then verify "Title" element visibility on "Modal_Transition_Popup" wizard + Then "Title" element on "Modal_Transition_Popup" should contains "train" value + Then verify "Data_Status" element visibility on "Modal_Transition_Popup" wizard @MLM @passive @inProgress @smoke - Scenario: MLM028 - Check tab list compontnts on Model Item infopane + Scenario: MLM028 - Check Overview tab Sources components on Model Item infopane Given open url And wait load page - And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard + And click on row root with value "churn-project-admin" in "name" column in "Projects_Table" table on "Projects" wizard And wait load page And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard And click on cell with value "Models" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard And hover "MLRun_Logo" component on "commonPagesHeader" wizard And wait load page - When click on cell with row index 1 in "name" column in "Models_Table" table on "Models" wizard + When click on cell with value "transaction_fraud_adaboost" in "name" column in "Models_Table" table on "Models" wizard And wait load page Then verify "Info_Pane_Tab_Selector" element visibility on "Models_Info_Pane" wizard Then verify "Info_Pane_Tab_Selector" on "Models_Info_Pane" wizard should contains "Models_Info_Pane"."Tab_List_Extended" Then verify "Overview" tab is active in "Info_Pane_Tab_Selector" on "Models_Info_Pane" wizard Then verify "Overview_Sources_Headers" on "Models_Info_Pane" wizard should contains "Models_Info_Pane"."Overview_Sources_Headers" + Then check "dataset" value in "name_value" column in "Info_Sources_Table" table on "Models_Info_Pane" wizard + Then check "store://feature-vectors/churn-project-admin/transactions-fraud" value in "path_value" column in "Info_Sources_Table" table on "Models_Info_Pane" wizard + When click on cell with value "store://feature-vectors/churn-project-admin/transactions-fraud" in "path_value" column in "Info_Sources_Table" table on "Models_Info_Pane" wizard + And wait load page + Then verify if "Modal_Transition_Popup" popup dialog appears + Then verify "Title" element visibility on "Modal_Transition_Popup" wizard + Then "Title" element on "Modal_Transition_Popup" should contains "transactions-fraud" value + Then verify "Data_Status" element visibility on "Modal_Transition_Popup" wizard + Then verify "Refresh_Button" element visibility on "Modal_Transition_Popup" wizard + Then verify "Refresh_Button" element on "Modal_Transition_Popup" wizard should display hover tooltip "Common_Tooltips"."Refresh_Button" + Then click on "Refresh_Button" element on "Modal_Transition_Popup" wizard + And wait load page + Then verify "Refresh_Button" element visibility on "Modal_Transition_Popup" wizard + Then verify "Action_Menu" element visibility on "Modal_Transition_Popup" wizard + Then verify "Action_Menu" dropdown element on "Modal_Transition_Popup" wizard should contains "Common_Lists"."Action_Menu_List_Function_Transition_Popup" + Then select "View YAML" option in action menu on "Modal_Transition_Popup" wizard + And wait load page + Then verify if "View_YAML" popup dialog appears + Then verify "Cross_Cancel_Button" element visibility on "View_YAML" wizard + Then verify "YAML_Modal_Container" element visibility on "View_YAML" wizard + Then click on "Cross_Cancel_Button" element on "View_YAML" wizard + And wait load page + Then verify "Tab_Selector" element visibility on "Modal_Transition_Popup" wizard + Then verify "Tab_Selector" on "Modal_Transition_Popup" wizard should contains "Feature_Vectors_Info_Pane"."Tab_List_Extended" + Then verify "Overview" tab is active in "Tab_Selector" on "Modal_Transition_Popup" wizard + Then verify "Overview_General_Headers" on "Modal_Transition_Popup" wizard should contains "Feature_Vectors_Info_Pane"."Overview_General_Headers" + And select "Requested Features" tab in "Tab_Selector" on "Modal_Transition_Popup" wizard + And wait load page + Then verify "Requested Features" tab is active in "Tab_Selector" on "Modal_Transition_Popup" wizard + Then verify "Requested_Features_Table" element visibility on "Modal_Transition_Popup" wizard + And select "Returned Features" tab in "Tab_Selector" on "Modal_Transition_Popup" wizard + And wait load page + Then verify "Returned Features" tab is active in "Tab_Selector" on "Modal_Transition_Popup" wizard + Then verify "Returned_Features_Table" element visibility on "Modal_Transition_Popup" wizard + Then select "Statistics" tab in "Tab_Selector" on "Modal_Transition_Popup" wizard + Then verify "Statistics" tab is active in "Tab_Selector" on "Modal_Transition_Popup" wizard + Then verify cell with "Statistics" value in "key" column in "Tab_Selector" table on "Modal_Transition_Popup" wizard should display "Label_Hint"."Models_Statistics" + Then verify "Statistics_Table" element visibility on "Modal_Transition_Popup" wizard + Then select "Analysis" tab in "Tab_Selector" on "Modal_Transition_Popup" wizard + Then verify "Analysis" tab is active in "Tab_Selector" on "Modal_Transition_Popup" wizard + And verify "No_Data_Message" element visibility on "commonPagesHeader" wizard + Then "No_Data_Message" component on "commonPagesHeader" should contains "No_Data_Message"."No_Data" + Then verify "Cross_Close_Button" element visibility on "Modal_Transition_Popup" wizard + Then click on "Cross_Close_Button" element on "Modal_Transition_Popup" wizard + And wait load page + Then verify "Info_Pane_Tab_Selector" element visibility on "Models_Info_Pane" wizard + Then verify "Info_Pane_Tab_Selector" on "Models_Info_Pane" wizard should contains "Models_Info_Pane"."Tab_List_Extended" + Then verify "Overview" tab is active in "Info_Pane_Tab_Selector" on "Models_Info_Pane" wizard + When click on cell with value "current-state_model" in "name" column in "Models_Table" table on "Models" wizard + And wait load page + Then verify "Header" element visibility on "Models_Info_Pane" wizard + Then "Header" element on "Models_Info_Pane" should contains "current-state_model" value + Then check "dataset" value in "name_value" column in "Info_Sources_Table" table on "Models_Info_Pane" wizard + Then check "/User/demos/customer-churn-prediction/data/pipeline/eaae138e-439a-47fa-93c6-ba0fe1dc3b79/encoded-data.csv" value in "path_value" column in "Info_Sources_Table" table on "Models_Info_Pane" wizard + When click on cell with value "/User/demos/customer-churn-prediction/data/pipeline/eaae138e-439a-47fa-93c6-ba0fe1dc3b79/encoded-data.csv" in "path_value" column in "Info_Sources_Table" table on "Models_Info_Pane" wizard + And wait load page + And wait load page + Then verify if "Notification_Popup" popup dialog appears + Then verify "Notification_Pop_Up" element visibility on "Notification_Popup" wizard + Then "Notification_Pop_Up" element on "Notification_Popup" should contains "Copied to clipboard successfully" value + Then verify "Notification_Pop_Up_Cross_Close_Button" element visibility on "Notification_Popup" wizard + Then click on "Notification_Pop_Up_Cross_Close_Button" element on "Notification_Popup" wizard + Then verify "Info_Pane_Tab_Selector" element visibility on "Models_Info_Pane" wizard + Then verify "Overview" tab is active in "Info_Pane_Tab_Selector" on "Models_Info_Pane" wizard @MLM @passive @@ -1026,8 +1116,9 @@ Feature: Models Page And select "Real-Time Pipelines" tab in "Models_Tab_Selector" on "Models" wizard And wait load page Then verify "Real-Time Pipelines" tab is active in "Models_Tab_Selector" on "Models" wizard - Then save to context "name" column and "href" attribute on 2 row from "Real_Time_Pipelines_Table" table on "Real_Time_Pipelines" wizard - When click on cell with row index 2 in "name" column in "Real_Time_Pipelines_Table" table on "Real_Time_Pipelines" wizard + Then save to context "name" column and "href" attribute on 4 row from "Real_Time_Pipelines_Table" table on "Real_Time_Pipelines" wizard + When click on cell with value "model-monitoring-stream" in "name_link" column in "Real_Time_Pipelines_Table" table on "Real_Time_Pipelines" wizard + And wait load page And wait load page Then compare current browser URL with test "href" context value Then verify "Real_Time_Pipelines_Graph" element visibility on "Real_Time_Pipelines" wizard @@ -1038,7 +1129,7 @@ Feature: Models Page Then verify "Overview_Headers" on "Real_Time_Pipeline_Pane" wizard should contains "Real_Time_Pipeline_Pane"."Overview_Headers" Then click on "Arrow_Back" element on "Real_Time_Pipeline_Pane" wizard And wait load page - Then click on cell with row index 2 in "function" column in "Real_Time_Pipelines_Table" table on "Real_Time_Pipelines" wizard + Then click on cell with row index 4 in "function" column in "Real_Time_Pipelines_Table" table on "Real_Time_Pipelines" wizard And wait load page Then verify if "Modal_Transition_Popup" popup dialog appears Then verify "Title" element visibility on "Modal_Transition_Popup" wizard @@ -1063,7 +1154,7 @@ Feature: Models Page Then verify "Cross_Close_Button" element visibility on "Modal_Transition_Popup" wizard Then click on "Cross_Close_Button" element on "Modal_Transition_Popup" wizard And wait load page - Then click on cell with row index 2 in "function" column in "Real_Time_Pipelines_Table" table on "Real_Time_Pipelines" wizard + Then click on cell with row index 4 in "function" column in "Real_Time_Pipelines_Table" table on "Real_Time_Pipelines" wizard And wait load page Then verify if "Modal_Transition_Popup" popup dialog appears Then verify "Tab_Selector" element visibility on "Modal_Transition_Popup" wizard @@ -1086,10 +1177,89 @@ Feature: Models Page Then click on "Cross_Close_Button" element on "Modal_Transition_Popup" wizard And wait load page Then verify "Real_Time_Pipelines_Table" element visibility on "Real_Time_Pipelines" wizard - Then click on cell with row index 1 in "name" column in "Real_Time_Pipelines_Table" table on "Real_Time_Pipelines" wizard + When click on cell with value "vizro" in "name_link" column in "Real_Time_Pipelines_Table" table on "Real_Time_Pipelines" wizard And wait load page And verify "No_Data_Message" element visibility on "commonPagesHeader" wizard Then "No_Data_Message" element on "commonPagesHeader" should contains "The ingestion function has no steps and therefore no graph." value + And wait load page + + @MLM + @passive + @smoke + Scenario: MLM039 - Check the model runner step on the Real-Time Pipeline graph + Given open url + And wait load page + And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + Then verify breadcrumbs "project" label should be equal "default" value + When click on "Model_Stats_Counter" element in "Models_Stats_Container" on "Project" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "Models" value + And select "Real-Time Pipelines" tab in "Models_Tab_Selector" on "Models" wizard + And wait load page + Then verify "Real-Time Pipelines" tab is active in "Models_Tab_Selector" on "Models" wizard + When click on cell with value "function-with-llm" in "name_link" column in "Real_Time_Pipelines_Table" table on "Real_Time_Pipelines" wizard + And wait load page + Then verify "Real_Time_Pipelines_Graph" element visibility on "Real_Time_Pipelines" wizard + Then verify "Pipeline_Back_Button" element visibility on "Real_Time_Pipelines" wizard + Then verify "Pipeline_Link_Title" element visibility on "Real_Time_Pipelines" wizard + Then "Pipeline_Link_Title" element on "Real_Time_Pipelines" should contains "function-with-llm" value + Then verify "Model_Runner_Step_Icon" element visibility on "Real_Time_Pipelines" wizard + Then verify "Model_Runner_Step_Label" element visibility on "Real_Time_Pipelines" wizard + Then "Model_Runner_Step_Label" element on "Real_Time_Pipelines" should contains "model-runner" value + Then verify "Model_Runner_Step_Sub_Label" element visibility on "Real_Time_Pipelines" wizard + Then "Model_Runner_Step_Sub_Label" element on "Real_Time_Pipelines" should contains "Model runner step" value + Then verify "Model_Runner_Monitoring_Icon" element visibility on "Real_Time_Pipelines" wizard + Then verify "Model_Runner_Monitoring_Icon" element on "Real_Time_Pipelines" wizard should display hover tooltip "Real_Time_Pipeline_Pane"."In_Monitoring_State" + Then verify "Model_Runner_Chips_Title" element visibility on "Real_Time_Pipelines" wizard + Then "Model_Runner_Chips_Title" element on "Real_Time_Pipelines" should contains "Running models" value + Then verify "Model_Runner_Chip_Container" element visibility on "Real_Time_Pipelines" wizard + Then verify "Model_Runner_Chip_Container" element on "Real_Time_Pipelines" wizard should display hover tooltip "Real_Time_Pipeline_Pane"."Chip_Tooltip" + When click on node with index 1 in "node_title" column in "Real_Time_Pipelines_Graph" graph on "Real_Time_Pipelines" wizard + And wait load page + Then verify "Header" element visibility on "Real_Time_Pipeline_Pane" wizard + Then verify "Title_Icon" element visibility on "Real_Time_Pipeline_Pane" wizard + Then verify "Cross_Close_Button" element visibility on "Real_Time_Pipeline_Pane" wizard + Then verify "General_Section_Title" element visibility on "Real_Time_Pipeline_Pane" wizard + Then "General_Section_Title" element on "Real_Time_Pipeline_Pane" should contains "General" value + Then verify "Overview_Headers" on "Real_Time_Pipeline_Pane" wizard should contains "Real_Time_Pipeline_Pane"."Overview_Headers_Model_Runner" + Then verify "Running_Models_Section_Title" element visibility on "Real_Time_Pipeline_Pane" wizard + Then "Running_Models_Section_Title" element on "Real_Time_Pipeline_Pane" should contains "Running models (1)" value + Then verify "Graph_Pane_Expand_Icon" element visibility on "Real_Time_Pipeline_Pane" wizard + Then click on "Graph_Pane_Expand_Icon" element on "Real_Time_Pipeline_Pane" wizard + And wait load page + Then verify "Running_Models_Headers" on "Real_Time_Pipeline_Pane" wizard should contains "Real_Time_Pipeline_Pane"."Running_Models_Headers" + When click on cell with value "c3e9308aaab54e53b1013ecda9234e43" in "key_value" column in "Running_Models_Headers" table on "Real_Time_Pipeline_Pane" wizard + And wait load page + Then verify if "Modal_Transition_Popup" popup dialog appears + Then verify "Title" element visibility on "Modal_Transition_Popup" wizard + Then "Title" element on "Modal_Transition_Popup" should contains "my-endpoint" value + Then verify "Data_Status" element visibility on "Modal_Transition_Popup" wizard + Then verify "Cross_Close_Button" element visibility on "Modal_Transition_Popup" wizard + Then click on "Cross_Close_Button" element on "Modal_Transition_Popup" wizard + And wait load page + When click on cell with value "store://llm-prompts/default/my_llm4#0@9c0c8773-b1ce-4fa0-ac94-2f6c1fb71554^d28e010ba24e272a3ba2ba522f6caecde05ff383" in "key_value" column in "Running_Models_Headers" table on "Real_Time_Pipeline_Pane" wizard + And wait load page + Then verify if "Modal_Transition_Popup" popup dialog appears + Then verify "Title" element visibility on "Modal_Transition_Popup" wizard + Then "Title" element on "Modal_Transition_Popup" should contains "my_llm4" value + Then verify "Data_Status" element visibility on "Modal_Transition_Popup" wizard + Then verify "Cross_Close_Button" element visibility on "Modal_Transition_Popup" wizard + Then click on "Cross_Close_Button" element on "Modal_Transition_Popup" wizard + And wait load page + Then click on "Arrow_Back" element on "Real_Time_Pipeline_Pane" wizard + And wait load page + When click on cell with value "model-monitoring-stream" in "name_link" column in "Real_Time_Pipelines_Table" table on "Real_Time_Pipelines" wizard + And wait load page + Then verify "Real_Time_Pipelines_Graph" element visibility on "Real_Time_Pipelines" wizard + When click on node with index 1 in "Real_Time_Pipelines_Graph" graph on "Real_Time_Pipelines" wizard + Then verify "Header" element visibility on "Real_Time_Pipeline_Pane" wizard + Then verify "Cross_Close_Button" element visibility on "Real_Time_Pipeline_Pane" wizard + Then verify "Overview_Headers" on "Real_Time_Pipeline_Pane" wizard should contains "Real_Time_Pipeline_Pane"."Overview_Headers" + And wait load page + Then verify "Graph_Pane_Expand_Icon" element not exists on "Real_Time_Pipeline_Pane" wizard + Then click on "Arrow_Back" element on "Real_Time_Pipeline_Pane" wizard + And wait load page @MLM @smoke @@ -1459,7 +1629,7 @@ Feature: Models Page And wait load page And select "Model Endpoints" tab in "Models_Tab_Selector" on "Models" wizard And wait load page - When click on cell with row index 1 in "name" column in "Model_Endpoints_Table" table on "Model_Endpoints" wizard + When click on cell with value "GradientBoostingClassifier" in "name" column in "Model_Endpoints_Table" table on "Model_Endpoints" wizard And wait load page Then verify "Info_Pane_Tab_Selector" element visibility on "Model_Endpoints_Info_Pane" wizard Then verify "Info_Pane_Tab_Selector" on "Model_Endpoints_Info_Pane" wizard should contains "Models_Endpoints_Info_Pane"."Tab_List" @@ -1516,7 +1686,7 @@ Feature: Models Page And wait load page And select "Model Endpoints" tab in "Models_Tab_Selector" on "Models" wizard And wait load page - When click on cell with row index 1 in "name" column in "Model_Endpoints_Table" table on "Model_Endpoints" wizard + When click on cell with value "GradientBoostingClassifier" in "name" column in "Model_Endpoints_Table" table on "Model_Endpoints" wizard Then select "Metrics" tab in "Info_Pane_Tab_Selector" on "Model_Endpoints_Info_Pane" wizard Then click on "Choose_Metrics_Dropdown" element on "Model_Endpoints_Info_Pane" wizard And wait load page @@ -1541,6 +1711,7 @@ Feature: Models Page @MLM @smoke + # !!! restart mock is required Scenario: MLM037 - Verify the Delete option in Models table, details panel, full view action menu Given open url And wait load page diff --git a/tests/features/monitoringApp.feature b/tests/features/monitoringApp.feature index 54c31fca79..dc53a6967b 100644 --- a/tests/features/monitoringApp.feature +++ b/tests/features/monitoringApp.feature @@ -4,11 +4,13 @@ Feature: Monitoring app Page @MLMA @smoke - Scenario: MLMA001 - Check components on Monitoring app page + Scenario: MLMA001 - Check action bar components on Monitoring app page Given open url And wait load page And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard And wait load page + When turn on demo mode with query params "false" + And wait load page Then verify breadcrumbs "tab" label should be equal "Project monitoring" value Then verify breadcrumbs "project" label should be equal "default" value And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard @@ -27,6 +29,528 @@ Feature: Monitoring app Page And wait load page Then verify "Date_Picker_Filter_Dropdown" element visibility on "Monitoring_App" wizard Then verify "Date_Picker_Filter_Dropdown" dropdown on "Monitoring_App" wizard selected option value "Past 24 hours" - Then verify "Date_Picker_Filter_Dropdown" dropdown element on "Monitoring_App" wizard should contains "Dropdown_Options"."Date_Picker_Filter_Options_Endpoint" + Then verify "Date_Picker_Filter_Dropdown" dropdown element on "Monitoring_App" wizard should contains "Dropdown_Options"."Date_Picker_Filter_Options_Monitoring_App" Then verify "Refresh_Button" element visibility on "Monitoring_App" wizard Then verify "Refresh_Button" element on "Monitoring_App" wizard should display hover tooltip "Common_Tooltips"."Refresh_Button" + When select "Past hour" option in "Date_Picker_Filter_Dropdown" filter dropdown on "Monitoring_App" wizard + And wait load page + Then verify "Date_Picker_Filter_Dropdown" dropdown on "Monitoring_App" wizard selected option value "Past hour" + When select "Past week" option in "Date_Picker_Filter_Dropdown" filter dropdown on "Monitoring_App" wizard + And wait load page + Then verify "Date_Picker_Filter_Dropdown" dropdown on "Monitoring_App" wizard selected option value "Past week" + When select "Past month" option in "Date_Picker_Filter_Dropdown" filter dropdown on "Monitoring_App" wizard + And wait load page + Then verify "Date_Picker_Filter_Dropdown" dropdown on "Monitoring_App" wizard selected option value "Past month" + + @MLMA + @smoke + Scenario: MLMA002 - Check statistics section components on Monitoring app page + Given open url + And wait load page + And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + When turn on demo mode with query params "false" + And wait load page + Then verify breadcrumbs "tab" label should be equal "Project monitoring" value + Then verify breadcrumbs "project" label should be equal "default" value + And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard + And click on cell with value "Monitoring app" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard + And hover "MLRun_Logo" component on "commonPagesHeader" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "Monitoring app" value + Then verify "Applications_Stats_Title" element visibility on "Monitoring_App" wizard + Then "Applications_Stats_Title" element on "Monitoring_App" should contains "Applications" value + Then verify "Applications_Stats_Counter" element visibility on "Monitoring_App" wizard + Then verify "Apps_Status_Title" element visibility on "Monitoring_App" wizard + Then "Apps_Status_Title" element on "Monitoring_App" should contains "Apps Status" value + Then verify "Apps_Status_Running_SubTitle" element visibility on "Monitoring_App" wizard + Then "Apps_Status_Running_SubTitle" element on "Monitoring_App" should contains "Running" value + Then verify "Apps_Status_Running_Counter" element visibility on "Monitoring_App" wizard + Then verify "Apps_Status_Running_Tip" element visibility on "Monitoring_App" wizard + Then verify "Apps_Status_Running_Tip" element on "Monitoring_App" wizard should display hover tooltip "Common_Tooltips"."Running" + Then verify "Apps_Status_Failed_SubTitle" element visibility on "Monitoring_App" wizard + Then "Apps_Status_Failed_SubTitle" element on "Monitoring_App" should contains "Failed" value + Then verify "Apps_Status_Failed_Counter" element visibility on "Monitoring_App" wizard + Then verify "Apps_Status_Failed_Tip" element visibility on "Monitoring_App" wizard + Then verify "Apps_Status_Failed_Tip" element on "Monitoring_App" wizard should display hover tooltip "Common_Tooltips"."Failed_Tip" + Then verify "Endpoints_Stats_Title" element visibility on "Monitoring_App" wizard + Then "Endpoints_Stats_Title" element on "Monitoring_App" should contains "Endpoints" value + Then verify "Endpoints_Batch_SubTitle" element visibility on "Monitoring_App" wizard + Then "Endpoints_Batch_SubTitle" element on "Monitoring_App" should contains "Batch" value + Then verify "Endpoints_Batch_Counter" element visibility on "Monitoring_App" wizard + Then verify "Endpoints_RealTime_SubTitle" element visibility on "Monitoring_App" wizard + Then "Endpoints_RealTime_SubTitle" element on "Monitoring_App" should contains "Real-time" value + Then verify "Endpoints_RealTime_Counter" element visibility on "Monitoring_App" wizard + Then verify "RunningFrequency_Stats_Title" element visibility on "Monitoring_App" wizard + Then "RunningFrequency_Stats_Title" element on "Monitoring_App" should contains "Running interval" value + Then verify "RunningFrequency_Value_Title" element visibility on "Monitoring_App" wizard + Then "RunningFrequency_Value_Title" element on "Monitoring_App" should contains "Every 10 minutes" value + + @MLMA + @smoke + Scenario: MLMA003 - Check monitoring-app section components on Monitoring app page + Given open url + And wait load page + And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + When turn on demo mode with query params "false" + And wait load page + And select "tab" with "Monitoring app" value in breadcrumbs menu + And wait load page + Then verify breadcrumbs "tab" label should be equal "Monitoring app" value + And wait load page + Then verify "Model_Endpoint_Detections_Title" element visibility on "Monitoring_App" wizard + Then "Model_Endpoint_Detections_Title" element on "Monitoring_App" should contains "Model Endpoints with suspected/detected issue" value + Then verify "Model_Endpoint_Detections_Tip" element visibility on "Monitoring_App" wizard + Then verify "Model_Endpoint_Detections_Tip" element on "Monitoring_App" wizard should display hover hint "Label_Hint"."Model_Endpoint_With_Detections" + Then verify "Model_Endpoint_Detections_Chart" element visibility on "Monitoring_App" wizard + Then verify "Operating_Functions_Title" element visibility on "Monitoring_App" wizard + Then "Operating_Functions_Title" element on "Monitoring_App" should contains "System functions" value + Then verify "Operating_Functions_Tip" element visibility on "Monitoring_App" wizard + Then verify "Operating_Functions_Tip" element on "Monitoring_App" wizard should display hover hint "Label_Hint"."Operating_Functions" + Then verify "Operating_Functions_Table" element visibility on "Monitoring_App" wizard + Then verify "Operating_Functions_Lag_Tip" element visibility on "Monitoring_App" wizard + Then verify "Operating_Functions_Lag_Tip" element on "Monitoring_App" wizard should display hover hint "Label_Hint"."Lag" + Then verify "Operating_Functions_Commited_Offset_Tip" element visibility on "Monitoring_App" wizard + Then verify "Operating_Functions_Commited_Offset_Tip" element on "Monitoring_App" wizard should display hover hint "Label_Hint"."Commited_Offset" + + @MLMA + @smoke + Scenario: MLMA004 - Check All Applications section components on Monitoring app page + Given open url + And wait load page + And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + When turn on demo mode with query params "false" + And wait load page + And select "tab" with "Monitoring app" value in breadcrumbs menu + And wait load page + Then verify breadcrumbs "tab" label should be equal "Monitoring app" value + And wait load page + Then verify "All_Applications_Title" element visibility on "Monitoring_App" wizard + Then "All_Applications_Title" element on "Monitoring_App" should contains "All Applications" value + Then verify "All_Applications_Table" element visibility on "Monitoring_App" wizard + Then verify "All_Applications_Lag_Tip" element visibility on "Monitoring_App" wizard + Then verify "All_Applications_Lag_Tip" element on "Monitoring_App" wizard should display hover hint "Label_Hint"."Lag" + Then verify "All_Applications_Commited_Offset_Tip" element visibility on "Monitoring_App" wizard + Then verify "All_Applications_Commited_Offset_Tip" element on "Monitoring_App" wizard should display hover hint "Label_Hint"."Commited_Offset" + Then verify "open_metrics" option is present on "Monitoring_App" wizard in "All_Applications_Table" table with "monitorAppV1" value in "name" column + Then verify "open_metrics" option on "Monitoring_App" wizard in "All_Applications_Table" table with "monitorAppV1" value in "name" column should display hover tooltip "Common_Tooltips"."Open_Metrics" with scroll "false" + Then click on "open_metrics" option on "Monitoring_App" wizard in "All_Applications_Table" table with "monitorAppV1" value in "name" column with scroll "false" + And wait load page + Then verify "Application_Monitoring_Button" element visibility on "Application_Metrics" wizard + Then "Application_Monitoring_Button" element on "Application_Metrics" should contains "Application monitoring" value + Then navigate back + And wait load page + Then click on cell with value "monitorAppV1" in "name" column in "All_Applications_Table" table on "Monitoring_App" wizard + And wait load page + Then verify "Application_Metrics_Button" element visibility on "Application_Monitoring" wizard + Then "Application_Metrics_Button" element on "Application_Monitoring" should contains "Application metrics" value + + @MLMA + @smoke + Scenario: MLMA005 - Check action bar components on Application monitoring page + Given open url + And wait load page + And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + When turn on demo mode with query params "false" + And wait load page + And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard + And click on cell with value "Monitoring app" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard + And hover "MLRun_Logo" component on "commonPagesHeader" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "Monitoring app" value + And wait load page + Then verify "All_Applications_Title" element visibility on "Monitoring_App" wizard + Then "All_Applications_Title" element on "Monitoring_App" should contains "All Applications" value + Then click on cell with value "monitorAppV2" in "name" column in "All_Applications_Table" table on "Monitoring_App" wizard + And wait load page + Then verify "Back_Button" element visibility on "Application_Monitoring" wizard + Then verify "Back_Button" element on "Application_Monitoring" wizard should display hover tooltip "Common_Tooltips"."Back_Button" + Then click on "Back_Button" element on "Application_Monitoring" wizard + And wait load page + Then verify "All_Applications_Title" element visibility on "Monitoring_App" wizard + Then "All_Applications_Title" element on "Monitoring_App" should contains "All Applications" value + Then click on cell with value "monitorAppV2" in "name" column in "All_Applications_Table" table on "Monitoring_App" wizard + And wait load page + Then verify "Application_Name" element visibility on "Application_Monitoring" wizard + Then "Application_Name" element on "Application_Monitoring" should contains "monitorAppV2" value + Then verify "Date_Picker_Filter_Dropdown" element visibility on "Application_Monitoring" wizard + Then verify "Date_Picker_Filter_Dropdown" dropdown on "Application_Monitoring" wizard selected option value "Past 24 hours" + Then verify "Date_Picker_Filter_Dropdown" dropdown element on "Application_Monitoring" wizard should contains "Dropdown_Options"."Date_Picker_Filter_Options_Monitoring_App" + When select "Past hour" option in "Date_Picker_Filter_Dropdown" filter dropdown on "Application_Monitoring" wizard + And wait load page + Then verify "Date_Picker_Filter_Dropdown" dropdown on "Application_Monitoring" wizard selected option value "Past hour" + When select "Past week" option in "Date_Picker_Filter_Dropdown" filter dropdown on "Application_Monitoring" wizard + And wait load page + Then verify "Date_Picker_Filter_Dropdown" dropdown on "Application_Monitoring" wizard selected option value "Past week" + When select "Past month" option in "Date_Picker_Filter_Dropdown" filter dropdown on "Application_Monitoring" wizard + And wait load page + Then verify "Date_Picker_Filter_Dropdown" dropdown on "Application_Monitoring" wizard selected option value "Past month" + Then verify "Application_Metrics_Button" element visibility on "Application_Monitoring" wizard + Then "Application_Metrics_Button" element on "Application_Monitoring" should contains "Application metrics" value + Then click on "Application_Metrics_Button" element on "Application_Monitoring" wizard + And wait load page + Then verify "Application_Monitoring_Button" element visibility on "Application_Metrics" wizard + Then "Application_Monitoring_Button" element on "Application_Metrics" should contains "Application monitoring" value + Then click on "Application_Monitoring_Button" element on "Application_Metrics" wizard + And wait load page + Then verify "Application_Name" element visibility on "Application_Monitoring" wizard + Then "Application_Name" element on "Application_Monitoring" should contains "monitorAppV2" value + And wait load page + Then verify "Refresh_Button" element visibility on "Application_Monitoring" wizard + Then verify "Refresh_Button" element on "Application_Monitoring" wizard should display hover tooltip "Common_Tooltips"."Refresh_Button" + And wait load page + Then click on "Refresh_Button" element on "Application_Monitoring" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "Monitoring app" value + Then verify "Back_Button" element visibility on "Application_Monitoring" wizard + Then "Application_Name" element on "Application_Monitoring" should contains "monitorAppV2" value + Then "Application_Metrics_Button" element on "Application_Monitoring" should contains "Application metrics" value + + @MLMA + @smoke + Scenario: MLMA006 - Check statistics section components on Application monitoring page + Given open url + And wait load page + And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + When turn on demo mode with query params "false" + And wait load page + And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard + And click on cell with value "Monitoring app" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard + And hover "MLRun_Logo" component on "commonPagesHeader" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "Monitoring app" value + And wait load page + Then verify "All_Applications_Title" element visibility on "Monitoring_App" wizard + Then "All_Applications_Title" element on "Monitoring_App" should contains "All Applications" value + Then click on cell with value "monitorAppV1" in "name" column in "All_Applications_Table" table on "Monitoring_App" wizard + And wait load page + Then verify "Back_Button" element visibility on "Application_Monitoring" wizard + Then verify "App_Status_Title" element visibility on "Application_Monitoring" wizard + Then "App_Status_Title" element on "Application_Monitoring" should contains "App Status" value + Then verify "App_Status_SubTitle" element visibility on "Application_Monitoring" wizard + Then "App_Status_SubTitle" element on "Application_Monitoring" should contains "Ready" value + Then verify "Endpoints_Title" element visibility on "Application_Monitoring" wizard + Then "Endpoints_Title" element on "Application_Monitoring" should contains "Endpoints" value + Then verify "Endpoints_Tip" element visibility on "Application_Monitoring" wizard + Then verify "Endpoints_Tip" element on "Application_Monitoring" wizard should display hover hint "Label_Hint"."Endpoints_Tip" + Then verify "Endpoints_Counter" element visibility on "Application_Monitoring" wizard + Then verify "Detections_Title" element visibility on "Application_Monitoring" wizard + Then "Detections_Title" element on "Application_Monitoring" should contains "Detections" value + Then verify "Detections_Counter" element visibility on "Application_Monitoring" wizard + Then verify "Possible_Detections_Title" element visibility on "Application_Monitoring" wizard + Then "Possible_Detections_Title" element on "Application_Monitoring" should contains "Possible Detections" value + Then verify "Possible_Detections_Counter" element visibility on "Application_Monitoring" wizard + Then verify "Lag_Title" element visibility on "Application_Monitoring" wizard + Then "Lag_Title" element on "Application_Monitoring" should contains "Lag" value + Then verify "Lag_Tip" element visibility on "Application_Monitoring" wizard + Then verify "Lag_Tip" element on "Application_Monitoring" wizard should display hover hint "Label_Hint"."Lag" + Then verify "Lag_Counter" element visibility on "Application_Monitoring" wizard + Then verify "Commited_Offset_Title" element visibility on "Application_Monitoring" wizard + Then "Commited_Offset_Title" element on "Application_Monitoring" should contains "Commited Offset" value + Then verify "Commited_Offset_Tip" element visibility on "Application_Monitoring" wizard + Then verify "Commited_Offset_Tip" element on "Application_Monitoring" wizard should display hover hint "Label_Hint"."Commited_Offset" + Then verify "Commited_Offset_Counter" element visibility on "Application_Monitoring" wizard + + @MLMA + @smoke + Scenario: MLMA007 - Check Artifacts section components on Application monitoring page + Given open url + And wait load page + And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + When turn on demo mode with query params "false" + And wait load page + And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard + And click on cell with value "Monitoring app" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard + And hover "MLRun_Logo" component on "commonPagesHeader" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "Monitoring app" value + And wait load page + Then verify "All_Applications_Title" element visibility on "Monitoring_App" wizard + Then "All_Applications_Title" element on "Monitoring_App" should contains "All Applications" value + Then click on cell with value "monitorAppV1" in "name" column in "All_Applications_Table" table on "Monitoring_App" wizard + And wait load page + Then verify "Artifacts_Title" element visibility on "Application_Monitoring" wizard + Then "Artifacts_Title" element on "Application_Monitoring" should contains "Artifacts" value + Then verify "Artifacts_Table" element visibility on "Application_Monitoring" wizard + Then verify "See_All_Link" element visibility on "Application_Monitoring" wizard + Then click on "See_All_Link" element on "Application_Monitoring" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "Artifacts" value + And wait load page + Then click on "Table_FilterBy_Button" element on "Files" wizard + And wait load page + Then "Table_Label_Filter_Input" element on "FilterBy_Popup" should contains "mlrun/app-name=monitorAppV1" attribute value + And wait load page + + @MLMA + @smoke + Scenario: MLMA008 - Check Results section components on Application monitoring page + Given open url + And wait load page + And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + When turn on demo mode with query params "false" + And wait load page + And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard + And click on cell with value "Monitoring app" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard + And hover "MLRun_Logo" component on "commonPagesHeader" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "Monitoring app" value + And wait load page + Then verify "All_Applications_Title" element visibility on "Monitoring_App" wizard + Then "All_Applications_Title" element on "Monitoring_App" should contains "All Applications" value + Then click on cell with value "monitorAppV1" in "name" column in "All_Applications_Table" table on "Monitoring_App" wizard + And wait load page + Then verify "Results_Title" element visibility on "Application_Monitoring" wizard + Then "Results_Title" element on "Application_Monitoring" should contains "Results" value + Then verify "Results_Table" element visibility on "Application_Monitoring" wizard + + @MLMA + @smoke + Scenario: MLMA009 - Check Metrics section components on Application monitoring page + Given open url + And wait load page + And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + When turn on demo mode with query params "false" + And wait load page + And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard + And click on cell with value "Monitoring app" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard + And hover "MLRun_Logo" component on "commonPagesHeader" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "Monitoring app" value + And wait load page + Then verify "All_Applications_Title" element visibility on "Monitoring_App" wizard + Then "All_Applications_Title" element on "Monitoring_App" should contains "All Applications" value + Then click on cell with value "monitorAppV1" in "name" column in "All_Applications_Table" table on "Monitoring_App" wizard + And wait load page + Then verify "Metrics_Title" element visibility on "Application_Monitoring" wizard + Then "Metrics_Title" element on "Application_Monitoring" should contains "Metrics" value + Then verify "Metrics_Tip" element visibility on "Application_Monitoring" wizard + Then verify "Metrics_Tip" element on "Application_Monitoring" wizard should display hover hint "Label_Hint"."Metrics_Tip" + Then verify "Metrics_Table" element visibility on "Application_Monitoring" wizard + + @MLMA + @smoke + Scenario: MLMA010 - Check Shards/partitions status section components on Application monitoring page + Given open url + And wait load page + And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + When turn on demo mode with query params "false" + And wait load page + And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard + And click on cell with value "Monitoring app" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard + And hover "MLRun_Logo" component on "commonPagesHeader" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "Monitoring app" value + And wait load page + Then verify "All_Applications_Title" element visibility on "Monitoring_App" wizard + Then "All_Applications_Title" element on "Monitoring_App" should contains "All Applications" value + Then click on cell with value "monitorAppV1" in "name" column in "All_Applications_Table" table on "Monitoring_App" wizard + And wait load page + When scroll to the "Shards_Partitions_Status_Title" element on "Application_Monitoring" wizard + Then verify "Shards_Partitions_Status_Title" element visibility on "Application_Monitoring" wizard + Then "Shards_Partitions_Status_Title" element on "Application_Monitoring" should contains "Shards/partitions status" value + Then verify "Shards_Partitions_Status_Tip" element visibility on "Application_Monitoring" wizard + Then verify "Shards_Partitions_Status_Tip" element on "Application_Monitoring" wizard should display hover hint "Label_Hint"."Shards_Partitions_Status_Tip" + Then verify "Shards_Partitions_Status_Table" element visibility on "Application_Monitoring" wizard + Then verify "Partitions_Status_Lag_Tip" element visibility on "Application_Monitoring" wizard + Then verify "Partitions_Status_Lag_Tip" element on "Application_Monitoring" wizard should display hover hint "Label_Hint"."Lag" + Then verify "Partitions_Status_Commited_Offset_Tip" element visibility on "Application_Monitoring" wizard + Then verify "Partitions_Status_Commited_Offset_Tip" element on "Application_Monitoring" wizard should display hover hint "Label_Hint"."Commited_Offset" + + @MLMA + @smoke + Scenario: MLMA011 - Check action bar components on Applications metrics page + Given open url + And wait load page + And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + When turn on demo mode with query params "false" + And wait load page + And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard + And click on cell with value "Monitoring app" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard + And hover "MLRun_Logo" component on "commonPagesHeader" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "Monitoring app" value + And wait load page + Then verify "All_Applications_Title" element visibility on "Monitoring_App" wizard + Then "All_Applications_Title" element on "Monitoring_App" should contains "All Applications" value + Then click on cell with value "monitorAppV1" in "name" column in "All_Applications_Table" table on "Monitoring_App" wizard + And wait load page + Then verify "Application_Metrics_Button" element visibility on "Application_Monitoring" wizard + Then "Application_Metrics_Button" element on "Application_Monitoring" should contains "Application metrics" value + Then click on "Application_Metrics_Button" element on "Application_Monitoring" wizard + And wait load page + Then verify "Back_Button" element visibility on "Application_Metrics" wizard + Then verify "Back_Button" element on "Application_Metrics" wizard should display hover tooltip "Common_Tooltips"."Back_Button" + Then click on "Back_Button" element on "Application_Metrics" wizard + And wait load page + Then verify "Back_Button" element visibility on "Application_Monitoring" wizard + Then click on "Back_Button" element on "Application_Monitoring" wizard + And wait load page + Then verify "All_Applications_Title" element visibility on "Monitoring_App" wizard + Then "All_Applications_Title" element on "Monitoring_App" should contains "All Applications" value + Then verify "open_metrics" option is present on "Monitoring_App" wizard in "All_Applications_Table" table with "monitorAppV1" value in "name" column + Then click on "open_metrics" option on "Monitoring_App" wizard in "All_Applications_Table" table with "monitorAppV1" value in "name" column with scroll "false" + And wait load page + Then verify "Applications_Metrics_Title" element visibility on "Application_Metrics" wizard + Then "Applications_Metrics_Title" element on "Application_Metrics" should contains "Applications metrics:" value + Then verify "Application_Name" element visibility on "Application_Metrics" wizard + Then "Application_Name" element on "Application_Metrics" should contains "monitorAppV1" value + Then verify "Application_Monitoring_Button" element visibility on "Application_Metrics" wizard + Then "Application_Monitoring_Button" element on "Application_Metrics" should contains "Application monitoring" value + Then verify "Refresh_Button" element visibility on "Application_Metrics" wizard + Then verify "Refresh_Button" element on "Application_Metrics" wizard should display hover tooltip "Common_Tooltips"."Refresh_Button" + And wait load page + Then click on "Refresh_Button" element on "Application_Metrics" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "Monitoring app" value + Then verify "Back_Button" element visibility on "Application_Metrics" wizard + Then "Application_Name" element on "Application_Metrics" should contains "monitorAppV1" value + Then "Application_Monitoring_Button" element on "Application_Metrics" should contains "Application monitoring" value + + @MLMA + @smoke + Scenario: MLMA012 - Check Endpoints list section components on Applications metrics page + Given open url + And wait load page + And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + When turn on demo mode with query params "false" + And wait load page + And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard + And click on cell with value "Monitoring app" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard + And hover "MLRun_Logo" component on "commonPagesHeader" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "Monitoring app" value + And wait load page + Then verify "All_Applications_Title" element visibility on "Monitoring_App" wizard + Then "All_Applications_Title" element on "Monitoring_App" should contains "All Applications" value + Then click on cell with value "monitorAppV1" in "name" column in "All_Applications_Table" table on "Monitoring_App" wizard + And wait load page + Then verify "Application_Metrics_Button" element visibility on "Application_Monitoring" wizard + Then "Application_Metrics_Button" element on "Application_Monitoring" should contains "Application metrics" value + Then click on "Application_Metrics_Button" element on "Application_Monitoring" wizard + And wait load page + Then verify "Applications_Metrics_Title" element visibility on "Application_Metrics" wizard + Then "Applications_Metrics_Title" element on "Application_Metrics" should contains "Applications metrics:" value + Then verify "Endpoints_List_Section" element visibility on "Application_Metrics" wizard + Then verify "Search_Endpoints_Counter" element visibility on "Application_Metrics" wizard + Then "Search_Endpoints_Counter" element on "Application_Metrics" should contains "5 endpoints found" value + Then verify "Endpoints_List_Table" element visibility on "Application_Metrics" wizard + Then verify "Search_By_Endpoint_Filter_Input" element visibility on "Application_Metrics" wizard + Then type value "boo" to "Search_By_Endpoint_Filter_Input" field on "Application_Metrics" wizard + And wait load page + Then value in "name" column with "text" in "Endpoints_List_Table" on "Application_Metrics" wizard should contains "GradientBoostingClassifier" + Then "Search_Endpoints_Counter" element on "Application_Metrics" should contains "2 endpoints found" value + Then type value "RandomForestClassifier2" to "Search_By_Endpoint_Filter_Input" field on "Application_Metrics" wizard + And wait load page + Then value in "name" column with "text" in "Endpoints_List_Table" on "Application_Metrics" wizard should contains "RandomForestClassifier" + Then "Search_Endpoints_Counter" element on "Application_Metrics" should contains "1 endpoint found" value + Then type value "qwe" to "Search_By_Endpoint_Filter_Input" field on "Application_Metrics" wizard + And wait load page + Then "Search_Endpoints_Counter" element on "Application_Metrics" should contains "0 endpoints found" value + + @MLMA + @smoke + Scenario: MLMA013 - Check redirection to Model Endpoints filtering by mode list + Given open url + And wait load page + And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + When turn on demo mode with query params "false" + And wait load page + And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard + And click on cell with value "Monitoring app" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard + And hover "MLRun_Logo" component on "commonPagesHeader" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "Monitoring app" value + And wait load page + Then verify "All_Applications_Title" element visibility on "Monitoring_App" wizard + Then "All_Applications_Title" element on "Monitoring_App" should contains "All Applications" value + Then verify "Endpoints_Stats_Title" element visibility on "Monitoring_App" wizard + Then "Endpoints_Stats_Title" element on "Monitoring_App" should contains "Endpoints" value + Then verify "Endpoints_Batch_SubTitle" element visibility on "Monitoring_App" wizard + Then "Endpoints_Batch_SubTitle" element on "Monitoring_App" should contains "Batch" value + Then verify "Endpoints_Batch_Counter" element visibility on "Monitoring_App" wizard + Then verify "Endpoints_RealTime_SubTitle" element visibility on "Monitoring_App" wizard + Then "Endpoints_RealTime_SubTitle" element on "Monitoring_App" should contains "Real-time" value + Then verify "Endpoints_RealTime_Counter" element visibility on "Monitoring_App" wizard + And wait load page + Then click on "Endpoints_Batch_Counter" element on "Monitoring_App" wizard + And wait load page + Then verify redirection to "projects/default/models/model-endpoints?me-mode=batch" + Then verify breadcrumbs "tab" label should be equal "Models" value + Then verify "Models_Tab_Selector" on "Models" wizard should contains "Models"."Tab_List" + Then verify "Model Endpoints" tab is active in "Models_Tab_Selector" on "Models" wizard + Then verify "Table_FilterBy_Button" element visibility on "Model_Endpoints" wizard + Then verify "Table_FilterBy_Button" element on "Model_Endpoints" wizard should display hover tooltip "Common_Tooltips"."FilterBy_Button_1" + Then click on "Table_FilterBy_Button" element on "Model_Endpoints" wizard + Then verify "Table_Label_Filter_Input" element visibility on "FilterBy_Popup" wizard + Then verify "Mode_Filter_Dropdown" element visibility on "FilterBy_Popup" wizard + Then verify "Mode_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "Batch" + Then verify "Mode_Filter_Dropdown" dropdown element on "FilterBy_Popup" wizard should contains "Dropdown_Options"."Endpoint_Mode_Filter_Options" + And wait load page + Then verify "Apply_Button" element visibility on "FilterBy_Popup" wizard + Then verify "Apply_Button" element on "FilterBy_Popup" wizard is disabled + Then verify "Clear_Button" element visibility on "FilterBy_Popup" wizard + Then verify "Clear_Button" element on "FilterBy_Popup" wizard is enabled + Then navigate back + And wait load page + Then verify redirection to "projects/default/monitoring-app" + Then verify breadcrumbs "tab" label should be equal "Monitoring app" value + Then verify "Endpoints_Stats_Title" element visibility on "Monitoring_App" wizard + Then verify "Endpoints_RealTime_SubTitle" element visibility on "Monitoring_App" wizard + Then "Endpoints_RealTime_SubTitle" element on "Monitoring_App" should contains "Real-time" value + Then verify "Endpoints_RealTime_Counter" element visibility on "Monitoring_App" wizard + And wait load page + Then click on "Endpoints_RealTime_Counter" element on "Monitoring_App" wizard + And wait load page + Then verify redirection to "projects/default/models/model-endpoints?me-mode=realTime" + Then verify breadcrumbs "tab" label should be equal "Models" value + Then verify "Models_Tab_Selector" on "Models" wizard should contains "Models"."Tab_List" + Then verify "Model Endpoints" tab is active in "Models_Tab_Selector" on "Models" wizard + Then verify "Table_FilterBy_Button" element visibility on "Model_Endpoints" wizard + Then verify "Table_FilterBy_Button" element on "Model_Endpoints" wizard should display hover tooltip "Common_Tooltips"."FilterBy_Button_1" + Then click on "Table_FilterBy_Button" element on "Model_Endpoints" wizard + Then verify "Table_Label_Filter_Input" element visibility on "FilterBy_Popup" wizard + Then verify "Mode_Filter_Dropdown" element visibility on "FilterBy_Popup" wizard + Then verify "Mode_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "Real-time" + Then verify "Mode_Filter_Dropdown" dropdown element on "FilterBy_Popup" wizard should contains "Dropdown_Options"."Endpoint_Mode_Filter_Options" + And wait load page + Then verify "Apply_Button" element visibility on "FilterBy_Popup" wizard + Then verify "Apply_Button" element on "FilterBy_Popup" wizard is disabled + Then verify "Clear_Button" element visibility on "FilterBy_Popup" wizard + Then verify "Clear_Button" element on "FilterBy_Popup" wizard is enabled + Then navigate back + And wait load page + Then verify redirection to "projects/default/monitoring-app" + Then verify breadcrumbs "tab" label should be equal "Monitoring app" value + And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard + And click on cell with value "Models" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard + And hover "MLRun_Logo" component on "commonPagesHeader" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "Models" value + And wait load page + And select "Model Endpoints" tab in "Models_Tab_Selector" on "Models" wizard + And wait load page + Then verify "Model Endpoints" tab is active in "Models_Tab_Selector" on "Models" wizard + Then verify "Table_FilterBy_Button" element visibility on "Model_Endpoints" wizard + Then verify "Table_FilterBy_Button" element on "Model_Endpoints" wizard should display hover tooltip "Common_Tooltips"."FilterBy_Button" + Then click on "Table_FilterBy_Button" element on "Model_Endpoints" wizard + Then verify "Table_Label_Filter_Input" element visibility on "FilterBy_Popup" wizard + Then verify "Mode_Filter_Dropdown" element visibility on "FilterBy_Popup" wizard + Then verify "Mode_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" + Then verify "Mode_Filter_Dropdown" dropdown element on "FilterBy_Popup" wizard should contains "Dropdown_Options"."Endpoint_Mode_Filter_Options" + And wait load page + Then verify "Apply_Button" element visibility on "FilterBy_Popup" wizard + Then verify "Apply_Button" element on "FilterBy_Popup" wizard is disabled + Then verify "Clear_Button" element visibility on "FilterBy_Popup" wizard + Then verify "Clear_Button" element on "FilterBy_Popup" wizard is disabled diff --git a/tests/features/projectMonitoring.feature b/tests/features/projectMonitoring.feature index 5ccba9ae2a..0d395de911 100644 --- a/tests/features/projectMonitoring.feature +++ b/tests/features/projectMonitoring.feature @@ -5,38 +5,175 @@ Feature: Project Monitoring Page @MLPM @passive @smoke - Scenario: MLPM002 - Check all mandatory components + Scenario: MLPM002 - Check components on the header details and the project monitoring container Given open url And wait load page And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard And wait load page Then verify breadcrumbs "project" label should be equal "default" value - Then verify "Create_New" element visibility on "Project" wizard + Then verify breadcrumbs "tab" label should be equal "Project monitoring" value + Then verify "Project_Name" element visibility on "Project" wizard + Then "Project_Name" element on "Project" should contains "default" value + Then verify "Created_Details" element visibility on "Project" wizard + Then "Created_Details" element on "Project" should contains "Created: 08/29/2021, 15:21:14 PM" value + Then verify "Owner_Details" element visibility on "Project" wizard + Then "Owner_Details" element on "Project" should contains "Owner: igz_nobody" value + Then verify "Info_Baner_Icon" element visibility on "Project" wizard + Then verify "Info_Baner_Icon" element on "Project" wizard should display hover hint "Label_Hint"."Project_Monitoring_Counters" + Then verify "Quick_Actions" element visibility on "Project" wizard + Then verify "Quick_Actions" dropdown element on "Project" wizard should contains "Project"."Quick_Actions_Options" Then verify "Refresh_Button" element visibility on "Project" wizard - Then verify "Dashboard_Realtime_Functions_Table" element visibility on "Project" wizard - Then verify "Jobs_And_Workflows" element visibility on "Project" wizard + Then verify "Refresh_Button" element on "Project" wizard should display hover tooltip "Common_Tooltips"."Refresh_Button" Then verify "Mono_Values_Cards" element visibility on "Project" wizard - Then verify "Model_Stats_Title" element visibility on "Project" wizard - Then verify "Model_Stats_Tip" element visibility on "Project" wizard - Then verify "Model_Stats_Tip" element on "Project" wizard should display hover hint "Label_Hint"."Model_Stats_Tip" - Then verify "Model_Stats_Counter" element visibility on "Project" wizard - Then verify "FeatureSets_Stats_Title" element visibility on "Project" wizard - Then verify "FeatureSets_Stats_Tip" element visibility on "Project" wizard - Then verify "FeatureSets_Stats_Tip" element on "Project" wizard should display hover hint "Label_Hint"."FeatureSets_Stats_Tip" - Then verify "FeatureSets_Stats_Counter" element visibility on "Project" wizard - Then verify "Artifacts_Stats_Title" element visibility on "Project" wizard - Then verify "Artifacts_Stats_Tip" element visibility on "Project" wizard - Then verify "Artifacts_Stats_Tip" element on "Project" wizard should display hover hint "Label_Hint"."Artifacts_Stats_Tip" - Then verify "Artifacts_Stats_Counter" element visibility on "Project" wizard - Then verify "Alerts_Stats_Title" element visibility on "Project" wizard - Then verify "Alerts_Stats_Total_Number" element visibility on "Project" wizard - Then verify "Alerts_Stats_Endpoint_Number" element visibility on "Project" wizard - Then verify "Alerts_Stats_Jobs_Number" element visibility on "Project" wizard - Then verify "Alerts_Stats_Application_Number" element visibility on "Project" wizard - Then verify "ConsumerGroups_Stats_Title" element visibility on "Project" wizard - Then verify "ConsumerGroups_Stats_Counter" element visibility on "Project" wizard - Then verify "Jobs_Info_Card_Statistics" element visibility on "Project" wizard - Then verify "Real_Time_Functions_Card_Statistics" element visibility on "Project" wizard + Then verify "Artifacts_Stats_Title" element visibility in "Artifacts_Stats_Container" on "Project" wizard + Then "Artifacts_Stats_Title" element in "Artifacts_Stats_Container" on "Project" should contains "Artifacts" value + Then verify "Artifacts_Stats_Counter" element visibility in "Artifacts_Stats_Container" on "Project" wizard + Then verify "Datasets_Counter_Subtitle" element visibility in "Artifacts_Stats_Container" on "Project" wizard + Then "Datasets_Counter_Subtitle" element in "Artifacts_Stats_Container" on "Project" should contains "Datasets" value + Then verify "Datasets_Counter_Number" element visibility in "Artifacts_Stats_Container" on "Project" wizard + Then verify "Documents_Counter_Subtitle" element visibility in "Artifacts_Stats_Container" on "Project" wizard + Then "Documents_Counter_Subtitle" element in "Artifacts_Stats_Container" on "Project" should contains "Documents" value + Then verify "Documents_Counter_Number" element visibility in "Artifacts_Stats_Container" on "Project" wizard + Then verify "LLM_Prompts_Counter_Subtitle" element visibility in "Artifacts_Stats_Container" on "Project" wizard + Then "LLM_Prompts_Counter_Subtitle" element in "Artifacts_Stats_Container" on "Project" should contains "LLM prompt artifacts" value + Then verify "LLM_Prompts_Counter_Number" element visibility in "Artifacts_Stats_Container" on "Project" wizard + Then verify "Other_Artifacts_Counter_Subtitle" element visibility in "Artifacts_Stats_Container" on "Project" wizard + Then "Other_Artifacts_Counter_Subtitle" element in "Artifacts_Stats_Container" on "Project" should contains "Other artifacts" value + Then verify "Other_Artifacts_Counter_Number" element visibility in "Artifacts_Stats_Container" on "Project" wizard + Then verify "Workflows_Stats_Title" element visibility in "Workflows_Stats_Container" on "Project" wizard + Then "Workflows_Stats_Title" element in "Workflows_Stats_Container" on "Project" should contains "Workflows" value + Then verify "Filtering_Time_Period" element visibility in "Workflows_Stats_Container" on "Project" wizard + Then "Filtering_Time_Period" element in "Workflows_Stats_Container" on "Project" should contains "Last 24 hrs" value + Then verify "Workflows_Stats_Counter" element visibility in "Workflows_Stats_Container" on "Project" wizard + Then verify "In_Process_Counter_Subtitle" element visibility in "Workflows_Stats_Container" on "Project" wizard + Then "In_Process_Counter_Subtitle" element in "Workflows_Stats_Container" on "Project" should contains "In process" value + Then verify "In_Process_Counter_Status_Icon" element visibility in "Workflows_Stats_Container" on "Project" wizard + Then verify "In_Process_Counter_Status_Icon" element in "Workflows_Stats_Container" on "Project" wizard should display hover tooltip "Common_Tooltips"."Running_Tip" + Then verify "In_Process_Counter_Number" element visibility in "Workflows_Stats_Container" on "Project" wizard + Then verify "Failed_Counter_Subtitle" element visibility in "Workflows_Stats_Container" on "Project" wizard + Then "Failed_Counter_Subtitle" element in "Workflows_Stats_Container" on "Project" should contains "Failed" value + Then verify "Failed_Counter_Status_Icon" element visibility in "Workflows_Stats_Container" on "Project" wizard + Then verify "Failed_Counter_Status_Icon" element in "Workflows_Stats_Container" on "Project" wizard should display hover tooltip "Common_Tooltips"."Failed_Worflows" + Then verify "Failed_Counter_Number" element visibility in "Workflows_Stats_Container" on "Project" wizard + Then verify "Succeeded_Counter_Subtitle" element visibility in "Workflows_Stats_Container" on "Project" wizard + Then "Succeeded_Counter_Subtitle" element in "Workflows_Stats_Container" on "Project" should contains "Succeeded" value + Then verify "Succeeded_Counter_Status_Icon" element visibility in "Workflows_Stats_Container" on "Project" wizard + Then verify "In_Process_Counter_Status_Icon" element in "Workflows_Stats_Container" on "Project" wizard should display hover tooltip "Common_Tooltips"."Running_Tip" + Then verify "Succeeded_Counter_Status_Icon" element in "Workflows_Stats_Container" on "Project" wizard should display hover tooltip "Common_Tooltips"."Succeeded" + Then verify "Succeeded_Counter_Number" element visibility in "Workflows_Stats_Container" on "Project" wizard + Then verify "Scheduled_Stats_Title" element visibility in "Scheduled_Stats_Container" on "Project" wizard + Then "Scheduled_Stats_Title" element in "Scheduled_Stats_Container" on "Project" should contains "Scheduled" value + Then verify "Filtering_Time_Period" element visibility in "Scheduled_Stats_Container" on "Project" wizard + Then "Filtering_Time_Period" element in "Scheduled_Stats_Container" on "Project" should contains "Next 24 hrs" value + Then verify "Scheduled_Stats_Counter" element visibility in "Scheduled_Stats_Container" on "Project" wizard + Then verify "Jobs_Counter_Subtitle" element visibility in "Scheduled_Stats_Container" on "Project" wizard + Then "Jobs_Counter_Subtitle" element in "Scheduled_Stats_Container" on "Project" should contains "Jobs" value + Then verify "Jobs_Counter_Number" element visibility in "Scheduled_Stats_Container" on "Project" wizard + Then verify "Workflows_Counter_Subtitle" element visibility in "Scheduled_Stats_Container" on "Project" wizard + Then "Workflows_Counter_Subtitle" element in "Scheduled_Stats_Container" on "Project" should contains "Workflows" value + Then verify "Workflows_Counter_Number" element visibility in "Scheduled_Stats_Container" on "Project" wizard + Then verify "Models_Stats_Title" element visibility in "Models_Stats_Container" on "Project" wizard + Then "Models_Stats_Title" element in "Models_Stats_Container" on "Project" should contains "Models" value + Then verify "Model_Stats_Counter" element visibility in "Models_Stats_Container" on "Project" wizard + Then verify "Monitoring_App_Stats_Title" element visibility in "Monitoring_App_Stats_Container" on "Project" wizard + Then "Monitoring_App_Stats_Title" element in "Monitoring_App_Stats_Container" on "Project" should contains "Monitoring apps" value + Then verify "Monitoring_App_Running_Stats_Counter" element visibility in "Monitoring_App_Stats_Container" on "Project" wizard + Then verify "Monitoring_App_Running_Counter_Subtitle" element visibility in "Monitoring_App_Stats_Container" on "Project" wizard + Then "Monitoring_App_Running_Counter_Subtitle" element in "Monitoring_App_Stats_Container" on "Project" should contains "Running" value + Then verify "Monitoring_App_Running_Counter_Status_Icon" element visibility in "Monitoring_App_Stats_Container" on "Project" wizard + Then verify "Monitoring_App_Running_Counter_Status_Icon" element in "Monitoring_App_Stats_Container" on "Project" wizard should display hover tooltip "Common_Tooltips"."Running" + Then verify "Monitoring_App_Failed_Stats_Counter" element visibility in "Monitoring_App_Stats_Container" on "Project" wizard + Then verify "Monitoring_App_Failed_Counter_Subtitle" element visibility in "Monitoring_App_Stats_Container" on "Project" wizard + Then "Monitoring_App_Failed_Counter_Subtitle" element in "Monitoring_App_Stats_Container" on "Project" should contains "Failed" value + Then verify "Monitoring_App_Failed_Counter_Status_Icon" element visibility in "Monitoring_App_Stats_Container" on "Project" wizard + Then verify "Monitoring_App_Failed_Counter_Status_Icon" element in "Monitoring_App_Stats_Container" on "Project" wizard should display hover tooltip "Common_Tooltips"."Failed_Tip" + Then verify "Alerts_Stats_Title" element visibility in "Alerts_Stats_Container" on "Project" wizard + Then "Alerts_Stats_Title" element in "Alerts_Stats_Container" on "Project" should contains "Alerts" value + Then verify "Alerts_Stats_Title_Icon" element visibility in "Alerts_Stats_Container" on "Project" wizard + Then verify "Filtering_Time_Period" element visibility in "Alerts_Stats_Container" on "Project" wizard + Then "Filtering_Time_Period" element in "Alerts_Stats_Container" on "Project" should contains "Last 24 hrs" value + Then verify "Alerts_Stats_Counter" element visibility in "Alerts_Stats_Container" on "Project" wizard + Then verify "Alerts_Stats_Endpoint_Subtitle" element visibility in "Alerts_Stats_Container" on "Project" wizard + Then "Alerts_Stats_Endpoint_Subtitle" element in "Alerts_Stats_Container" on "Project" should contains "Endpoint" value + Then verify "Alerts_Stats_Endpoint_Counter" element visibility in "Alerts_Stats_Container" on "Project" wizard + Then verify "Alerts_Stats_Jobs_Subtitle" element visibility in "Alerts_Stats_Container" on "Project" wizard + Then "Alerts_Stats_Jobs_Subtitle" element in "Alerts_Stats_Container" on "Project" should contains "Jobs" value + Then verify "Alerts_Stats_Jobs_Counter" element visibility in "Alerts_Stats_Container" on "Project" wizard + Then verify "Alerts_Stats_Application_Subtitle" element visibility in "Alerts_Stats_Container" on "Project" wizard + Then "Alerts_Stats_Application_Subtitle" element in "Alerts_Stats_Container" on "Project" should contains "Application" value + Then verify "Alerts_Stats_Application_Counter" element visibility in "Alerts_Stats_Container" on "Project" wizard + + @MLPM + @passive + @smoke + Scenario: MLPM023 - Check components on on the header details and the statistics section + Given open url + And wait load page + And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + Then verify breadcrumbs "project" label should be equal "default" value + Then verify breadcrumbs "tab" label should be equal "Project monitoring" value + Then verify "Project_Name" element visibility on "Project" wizard + Then "Project_Name" element on "Project" should contains "default" value + Then verify "Created_Details" element visibility on "Project" wizard + Then "Created_Details" element on "Project" should contains "Created: 08/29/2021, 15:21:14 PM" value + Then verify "Owner_Details" element visibility on "Project" wizard + Then "Owner_Details" element on "Project" should contains "Owner: igz_nobody" value + Then verify "Info_Baner_Icon" element visibility on "Project" wizard + Then verify "Info_Baner_Icon" element on "Project" wizard should display hover hint "Label_Hint"."Project_Monitoring_Counters" + Then verify "Quick_Actions" element visibility on "Project" wizard + Then verify "Quick_Actions" dropdown element on "Project" wizard should contains "Project"."Quick_Actions_Options" + Then verify "Refresh_Button" element visibility on "Project" wizard + Then verify "Refresh_Button" element on "Project" wizard should display hover tooltip "Common_Tooltips"."Refresh_Button" + Then verify "Runs_Statistic_Table" element visibility on "Project" wizard + Then verify visibility of header column "title" in "Runs_Statistic_Table" table on "Project" wizard + Then check "Runs" header value in "title" column in "Runs_Statistic_Table" table on "Project" wizard + Then verify "Runs_Statistic_Section_Title_Tip" element visibility in "Runs_Statistic_Section_Container" on "Project" wizard + Then verify "Runs_Statistic_Section_Title_Tip" element in "Runs_Statistic_Section_Container" on "Project" wizard should display hover hint "Label_Hint"."Runs_Statistic_Section_Title_Tip" + Then verify visibility of header column "time_period" in "Runs_Statistic_Table" table on "Project" wizard + Then check "Last 24 hrs" header value in "time_period" column in "Runs_Statistic_Table" table on "Project" wizard + Then verify visibility of header column "in_process_counter_number" in "Runs_Statistic_Table" table on "Project" wizard + Then verify visibility of header column "in_process_counter_subtitle" in "Runs_Statistic_Table" table on "Project" wizard + Then check "In Process" header value in "in_process_counter_subtitle" column in "Runs_Statistic_Table" table on "Project" wizard + Then verify visibility of header column "in_process_counter_icon" in "Runs_Statistic_Table" table on "Project" wizard + Then verify "In_Process_Counter_Subtitle" element in "Runs_Statistic_Section_Container" on "Project" wizard should display hover tooltip "Common_Tooltips"."In_Process_Jobs" + Then verify visibility of header column "failed_counter_number" in "Runs_Statistic_Table" table on "Project" wizard + Then verify visibility of header column "failed_counter_subtitle" in "Runs_Statistic_Table" table on "Project" wizard + Then check "Failed" header value in "failed_counter_subtitle" column in "Runs_Statistic_Table" table on "Project" wizard + Then verify visibility of header column "failed_counter_icon" in "Runs_Statistic_Table" table on "Project" wizard + Then verify "Failed_Counter_Subtitle" element in "Runs_Statistic_Section_Container" on "Project" wizard should display hover tooltip "Common_Tooltips"."Failed_Jobs" + Then verify visibility of header column "succeeded_counter_number" in "Runs_Statistic_Table" table on "Project" wizard + Then verify visibility of header column "succeeded_counter_subtitle" in "Runs_Statistic_Table" table on "Project" wizard + Then check "Succeeded" header value in "succeeded_counter_subtitle" column in "Runs_Statistic_Table" table on "Project" wizard + Then verify visibility of header column "succeeded_counter_icon" in "Runs_Statistic_Table" table on "Project" wizard + Then verify "Succeeded_Counter_Subtitle" element in "Runs_Statistic_Section_Container" on "Project" wizard should display hover tooltip "Common_Tooltips"."Succeeded" + Then verify "Recent_Text" element visibility in "Runs_Statistic_Section_Container" on "Project" wizard + Then "Recent_Text" element in "Runs_Statistic_Section_Container" on "Project" should contains "Recent jobs" value + Then "Recent_Text_Sm" element in "Runs_Statistic_Section_Container" on "Project" should contains "(last 7 days)" value + Then check "erann-test" value in "name" column in "Runs_Statistic_Table" table on "Project" wizard + When scroll to the element with "erann-test" value in "name" column in "Runs_Statistic_Table" table on "Project" wizard + And wait load page + Then verify "All_Jobs_Link" element visibility in "Runs_Statistic_Section_Container" on "Project" wizard + Then "All_Jobs_Link" element in "Runs_Statistic_Section_Container" on "Project" should contains "All jobs" value + Then verify "Realtime_Functions_Nuclio_Table" element visibility on "Project" wizard + Then verify visibility of header column "title" in "Realtime_Functions_Nuclio_Table" table on "Project" wizard + Then check "Real-time functions (Nuclio)" header value in "title" column in "Realtime_Functions_Nuclio_Table" table on "Project" wizard + Then verify visibility of header column "running_counter_number" in "Realtime_Functions_Nuclio_Table" table on "Project" wizard + Then check "Running" header value in "running_counter_subtitle" column in "Realtime_Functions_Nuclio_Table" table on "Project" wizard + Then verify visibility of header column "running_counter_icon" in "Realtime_Functions_Nuclio_Table" table on "Project" wizard + Then verify visibility of header column "failed_counter_number" in "Realtime_Functions_Nuclio_Table" table on "Project" wizard + Then check "Failed" header value in "failed_counter_subtitle" column in "Realtime_Functions_Nuclio_Table" table on "Project" wizard + Then verify visibility of header column "failed_counter_icon" in "Realtime_Functions_Nuclio_Table" table on "Project" wizard + Then verify "Running_Counter_Subtitle" element in "Realtime_Functions_Nuclio_Statistic_Section" on "Project" wizard should display hover tooltip "Common_Tooltips"."Running" + Then verify "Failed_Counter_Subtitle" element in "Realtime_Functions_Nuclio_Statistic_Section" on "Project" wizard should display hover tooltip "Common_Tooltips"."Failed_Tip" + Then verify visibility of header column "api_gateways_counter_number" in "Realtime_Functions_Nuclio_Table" table on "Project" wizard + Then check "API gateways" header value in "api_gateways_counter_subtitle" column in "Realtime_Functions_Nuclio_Table" table on "Project" wizard + Then verify visibility of header column "consumer_groups_counter_number" in "Realtime_Functions_Nuclio_Table" table on "Project" wizard + Then check "Consumer groups" header value in "consumer_groups_counter_subtitle" column in "Realtime_Functions_Nuclio_Table" table on "Project" wizard + Then "Recent_Text" element in "Realtime_Functions_Nuclio_Statistic_Section" on "Project" should contains "Recent real-time functions" value + Then check "cat-vs-dog-classification-tf2-serving" value in "name" column in "Realtime_Functions_Nuclio_Table" table on "Project" wizard + Then verify "All_Realtime_Functions_Link" element visibility in "Realtime_Functions_Nuclio_Statistic_Section" on "Project" wizard + Then "All_Realtime_Functions_Link" element in "Realtime_Functions_Nuclio_Statistic_Section" on "Project" should contains "All real-time functions" value When hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard Then verify "General_Info_Quick_Links" element visibility on "commonPagesHeader" wizard @@ -58,13 +195,11 @@ Feature: Project Monitoring Page Then verify "Pin_Quick_Link_Button" element visibility on "commonPagesHeader" wizard Then verify "General_Info_Quick_Panel" element visibility on "commonPagesHeader" wizard Then verify "Project_Monitoring_Button" element visibility on "commonPagesHeader" wizard - Then verify "Quick_actions_Button" element visibility on "commonPagesHeader" wizard Then verify "Feature_Store_Button" element visibility on "commonPagesHeader" wizard Then verify "Datasets_Button" element visibility on "commonPagesHeader" wizard Then verify "Documents_Button" element visibility on "commonPagesHeader" wizard Then verify "Artifacts_Button" element visibility on "commonPagesHeader" wizard Then verify "Models_Button" element visibility on "commonPagesHeader" wizard - Then verify "Monitoring_App_Button" element visibility on "commonPagesHeader" wizard Then verify "Jobs_And_Workflows_Button" element visibility on "commonPagesHeader" wizard Then verify "ML_Functions_Button" element visibility on "commonPagesHeader" wizard Then verify "Real_Time_Functions_Button" element visibility on "commonPagesHeader" wizard @@ -78,8 +213,6 @@ Feature: Project Monitoring Page Then verify "General_Info_Quick_Panel" element visibility on "commonPagesHeader" wizard Then verify "Project_Monitoring_Button" element invisibility on "commonPagesHeader" wizard Then verify "Project_Monitoring_Icon" element visibility on "commonPagesHeader" wizard - Then verify "Quick_actions_Button" element invisibility on "commonPagesHeader" wizard - Then verify "Quick_actions_Icon" element visibility on "commonPagesHeader" wizard Then verify "Feature_Store_Button" element invisibility on "commonPagesHeader" wizard Then verify "Feature_Store_Icon" element visibility on "commonPagesHeader" wizard Then verify "Datasets_Button" element invisibility on "commonPagesHeader" wizard @@ -90,8 +223,6 @@ Feature: Project Monitoring Page Then verify "Artifacts_Icon" element visibility on "commonPagesHeader" wizard Then verify "Models_Button" element invisibility on "commonPagesHeader" wizard Then verify "Models_Icon" element visibility on "commonPagesHeader" wizard - Then verify "Monitoring_App_Button" element invisibility on "commonPagesHeader" wizard - Then verify "Monitoring_App_Icon" element visibility on "commonPagesHeader" wizard Then verify "Jobs_And_Workflows_Button" element invisibility on "commonPagesHeader" wizard Then verify "Jobs_And_Workflows_Icon" element visibility on "commonPagesHeader" wizard Then verify "ML_Functions_Button" element invisibility on "commonPagesHeader" wizard @@ -136,20 +267,12 @@ Feature: Project Monitoring Page And select "Secrets" tab in "Project_Settings_Tab_Selector" on "Project_Settings_General_Tab" wizard And wait load page Then "Navigation_Bar" on "commonPagesHeader" wizard should be "pinned" - #check navigation between pages Project monitoring and Quick-actions due to instance links - Then click on "Project_Monitoring_Button" element on "commonPagesHeader" wizard - Then click on "Project_Quick_Actions_Instance" element on "commonPagesHeader" wizard - Then verify "Quick_actions_Active" not input element on "commonPagesHeader" wizard is active - Then click on "Project_Monitoring_First_Instance" element on "commonPagesHeader" wizard - Then verify "Project_Monitoring_Active" not input element on "commonPagesHeader" wizard is active - Then click on "Project_Quick_Actions_Instance" element on "commonPagesHeader" wizard - Then verify "Quick_actions_Active" not input element on "commonPagesHeader" wizard is active - Then click on "Project_Monitoring_Second_Instance" element on "commonPagesHeader" wizard - Then verify "Project_Monitoring_Active" not input element on "commonPagesHeader" wizard is active #check visibility of menu buttons in demo mode When turn on demo mode with query params "false" And wait load page And wait load page + Then verify "Monitoring_App_Button" element visibility on "commonPagesHeader" wizard + Then verify "Monitoring_App_Icon" element visibility on "commonPagesHeader" wizard Then verify "LLM_Prompts_Button" element visibility on "commonPagesHeader" wizard Then verify "LLM_Prompts_Icon" element visibility on "commonPagesHeader" wizard @@ -174,9 +297,9 @@ Feature: Project Monitoring Page And wait load page And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard And wait load page - Then verify "Create_New" element visibility on "Project" wizard - Then verify "Create_New" dropdown element on "Project" wizard should contains "Project"."Create_New_Options" - Then select "Register artifact" option in "Create_New" dropdown on "Project" wizard + Then verify "Quick_Actions" element visibility on "Project" wizard + Then verify "Quick_Actions" dropdown element on "Project" wizard should contains "Project"."Quick_Actions_Options" + Then select "Register artifact" option in "Quick_Actions" dropdown on "Project" wizard Then "Title" element on "Register_File_Popup" should contains "Register Artifact" value Then "Form_Text" component on "Register_File_Popup" should contains "Register_Artifact"."Form_Text" Then "Form_Subtext" component on "Register_File_Popup" should contains "Register_Artifact"."Form_Subtext" @@ -227,9 +350,9 @@ Feature: Project Monitoring Page And wait load page And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard And wait load page - Then verify "Create_New" element visibility on "Project" wizard - Then verify "Create_New" dropdown element on "Project" wizard should contains "Project"."Create_New_Options_Demo" - Then select "Register model" option in "Create_New" dropdown on "Project" wizard + Then verify "Quick_Actions" element visibility on "Project" wizard + Then verify "Quick_Actions" dropdown element on "Project" wizard should contains "Project"."Quick_Actions_Options_Demo" + Then select "Register model" option in "Quick_Actions" dropdown on "Project" wizard Then "Title" element on "Register_Model_Popup" should contains "Register Model" value Then verify "Cross_Cancel_Button" element visibility on "Register_Model_Popup" wizard Then verify "New_File_Name_Input" element visibility on "Register_Model_Popup" wizard @@ -271,9 +394,9 @@ Feature: Project Monitoring Page And wait load page And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard And wait load page - Then verify "Create_New" element visibility on "Project" wizard - Then verify "Create_New" dropdown element on "Project" wizard should contains "Project"."Create_New_Options" - Then select "Register dataset" option in "Create_New" dropdown on "Project" wizard + Then verify "Quick_Actions" element visibility on "Project" wizard + Then verify "Quick_Actions" dropdown element on "Project" wizard should contains "Project"."Quick_Actions_Options" + Then select "Register dataset" option in "Quick_Actions" dropdown on "Project" wizard Then "Title" element on "Register_Dataset" should contains "Register Dataset" value Then "Form_Text" component on "Register_Dataset" should contains "Register_Dataset"."Form_Text" Then "Form_Subtext" component on "Register_Dataset" should contains "Register_Dataset"."Form_Subtext" @@ -316,9 +439,9 @@ Feature: Project Monitoring Page And wait load page And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard And wait load page - Then verify "Create_New" element visibility on "Project" wizard - Then verify "Create_New" dropdown element on "Project" wizard should contains "Project"."Create_New_Options" - Then select "Batch run" option in "Create_New" dropdown on "Project" wizard + Then verify "Quick_Actions" element visibility on "Project" wizard + Then verify "Quick_Actions" dropdown element on "Project" wizard should contains "Project"."Quick_Actions_Options" + Then select "Batch run" option in "Quick_Actions" dropdown on "Project" wizard And wait load page Then verify "Title" element visibility on "Modal_Wizard_Form" wizard Then "Title" element on "Modal_Wizard_Form" should contains "Batch Run" value @@ -402,20 +525,338 @@ Feature: Project Monitoring Page Then verify "Parallel_Runs_Number_Input" element visibility on "Modal_Wizard_Form" wizard Then verify "Dask_Clutter_URL_Input" element visibility on "Modal_Wizard_Form" wizard Then "Teardown_Checkbox" element should be unchecked on "Modal_Wizard_Form" wizard - + + @MLPM + @passive + @smoke + Scenario: MLPM029 - Check the Secret name validation in the Resources step on the Batch run wizard + Given open url + And wait load page + And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + Then verify "Quick_Actions" element visibility on "Project" wizard + Then verify "Quick_Actions" dropdown element on "Project" wizard should contains "Project"."Quick_Actions_Options" + Then select "Batch run" option in "Quick_Actions" dropdown on "Project" wizard + And wait load page + Then verify "Title" element visibility on "Modal_Wizard_Form" wizard + Then "Title" element on "Modal_Wizard_Form" should contains "Batch Run" value + Then verify "Cross_Close_Button" element visibility on "Modal_Wizard_Form" wizard + Then verify "Wizard_Steps_Content" element visibility on "Modal_Wizard_Form" wizard + And click on row root with value "aggregate" in "name" column in "Functions_Table" table on "Modal_Wizard_Form" wizard + Then "Function_Title" element on "Modal_Wizard_Form" should contains "aggregate" value + And click on "Step_5_Button" element on "commonPagesHeader" wizard + Then "Function_Title" element on "Modal_Wizard_Form" should contains "aggregate" value + Then "Title" element on "Modal_Wizard_Form" should contains "Batch Run" value + Then verify "Form_Header_Resources" element visibility on "commonPagesHeader" wizard + Then "Form_Header_Resources" element on "commonPagesHeader" should contains "Resources" value + Then verify "Volumes_Subheader" element visibility in "Resources_Accordion" on "Modal_Wizard_Form" wizard + Then verify "Volumes_Subheader" element in "Resources_Accordion" on "Modal_Wizard_Form" wizard should display hint "Label_Hint"."New_Job_Volumes" + When add new volume rows to "Volume_Paths_Table" table in "Resources_Accordion" on "Modal_Wizard_Form" wizard using nontable inputs + | Volume_Paths_Table_Type_Dropdown | Volume_Paths_Table_Volume_Name_Input | Volume_Paths_Table_Path_Input | Volume_Paths_Table_Secret_Name_Input | Add_New_Row_Button | + | Secret | | | mlrun-project-secrets-defaultinv | yes | + Then verify "Volume_Paths_Table_Volume_Name_Input" element in "Resources_Accordion" on "Modal_Wizard_Form" wizard should display hover warning "Input_Hint"."Input_Field_Require" + Then verify "Volume_Paths_Table_Path_Input" element in "Resources_Accordion" on "Modal_Wizard_Form" wizard should display hover warning "Input_Hint"."Input_Field_Require" + Then verify "Volume_Paths_Table_Path_Input" element in "Resources_Accordion" on "Modal_Wizard_Form" wizard should display hint "Input_Hint"."Mount_Path_Hint" + Then verify "Volume_Paths_Table_Secret_Name_Input" in "Resources_Accordion" on "Modal_Wizard_Form" wizard should display options "Input_Hint"."Secret_Name_Rule_Options" + When click on "Delete_New_Row_Button" element in "Resources_Accordion" on "Modal_Wizard_Form" wizard + When add new volume rows to "Volume_Paths_Table" table in "Resources_Accordion" on "Modal_Wizard_Form" wizard using nontable inputs + | Volume_Paths_Table_Type_Dropdown | Volume_Paths_Table_Volume_Name_Input | Volume_Paths_Table_Path_Input | Volume_Paths_Table_Secret_Name_Input | Add_New_Row_Button | + | Secret | test | test | mlrun-project-secrets-default | yes | + Then verify values in "Volume_Paths_Table" table in "Resources_Accordion" on "Modal_Wizard_Form" wizard + | type | volume_name | path | + | Secret | test | test | + When click on data "remove_btn" in "Volume_Paths_Table" table in "Resources_Accordion" on "Modal_Wizard_Form" wizard + | type | + | Secret | + When add new volume rows to "Volume_Paths_Table" table in "Resources_Accordion" on "Modal_Wizard_Form" wizard using nontable inputs + | Volume_Paths_Table_Type_Dropdown | Volume_Paths_Table_Volume_Name_Input | Volume_Paths_Table_Path_Input | Volume_Paths_Table_Secret_Name_Input | Add_New_Row_Button | + | Secret | | | mlrun-auth-secrets. | yes | + Then verify "Volume_Paths_Table_Volume_Name_Input" element in "Resources_Accordion" on "Modal_Wizard_Form" wizard should display hover warning "Input_Hint"."Input_Field_Require" + Then verify "Volume_Paths_Table_Path_Input" element in "Resources_Accordion" on "Modal_Wizard_Form" wizard should display hover warning "Input_Hint"."Input_Field_Require" + Then verify "Volume_Paths_Table_Path_Input" element in "Resources_Accordion" on "Modal_Wizard_Form" wizard should display hint "Input_Hint"."Mount_Path_Hint" + Then verify "Volume_Paths_Table_Secret_Name_Input" in "Resources_Accordion" on "Modal_Wizard_Form" wizard should display options "Input_Hint"."Secret_Name_Rule_Options" + When click on "Delete_New_Row_Button" element in "Resources_Accordion" on "Modal_Wizard_Form" wizard + When add new volume rows to "Volume_Paths_Table" table in "Resources_Accordion" on "Modal_Wizard_Form" wizard using nontable inputs + | Volume_Paths_Table_Type_Dropdown | Volume_Paths_Table_Volume_Name_Input | Volume_Paths_Table_Path_Input | Volume_Paths_Table_Secret_Name_Input | Add_New_Row_Button | + | Secret | test | test | mlrun-auth-secrets | yes | + Then verify values in "Volume_Paths_Table" table in "Resources_Accordion" on "Modal_Wizard_Form" wizard + | type | volume_name | path | + | Secret | test | test | + When click on data "remove_btn" in "Volume_Paths_Table" table in "Resources_Accordion" on "Modal_Wizard_Form" wizard + | type | + | Secret | + Then verify "Cross_Close_Button" element visibility on "Modal_Wizard_Form" wizard + And click on "Cross_Close_Button" element on "Modal_Wizard_Form" wizard + And wait load page + Then verify "Quick_Actions" element visibility on "Project" wizard + Then verify "Quick_Actions" dropdown element on "Project" wizard should contains "Project"."Quick_Actions_Options" + + @MLPM + @passive + @smoke + Scenario: MLPM030 - Check the Secret name validation in the Advanced step on the Batch run wizard + Given open url + And wait load page + And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + Then verify "Quick_Actions" element visibility on "Project" wizard + Then verify "Quick_Actions" dropdown element on "Project" wizard should contains "Project"."Quick_Actions_Options" + Then select "Batch run" option in "Quick_Actions" dropdown on "Project" wizard + And wait load page + Then verify "Title" element visibility on "Modal_Wizard_Form" wizard + Then "Title" element on "Modal_Wizard_Form" should contains "Batch Run" value + Then verify "Cross_Close_Button" element visibility on "Modal_Wizard_Form" wizard + Then verify "Wizard_Steps_Content" element visibility on "Modal_Wizard_Form" wizard + And click on row root with value "erann-job-func" in "name" column in "Functions_Table" table on "Modal_Wizard_Form" wizard + Then "Function_Title" element on "Modal_Wizard_Form" should contains "erann-job-func" value + And click on "Step_6_Button" element on "commonPagesHeader" wizard + Then "Function_Title" element on "Modal_Wizard_Form" should contains "erann-job-func" value + Then "Title" element on "Modal_Wizard_Form" should contains "Batch Run" value + Then verify "Form_Header_Advanced" element visibility on "commonPagesHeader" wizard + Then "Form_Header_Advanced" element on "commonPagesHeader" should contains "Advanced" value + Then "Accordion_Advanced_Subheader" element on "Modal_Wizard_Form" should contains "Environment variables" value + Then verify "Advanced_Environment_Variables_Table" element visibility on "Modal_Wizard_Form" wizard + When add data to "Advanced_Environment_Variables_Table" table on "Modal_Wizard_Form" wizard with several inputs + | name_input | type_dropdown | value_input | value_input_key | + | name1 | Secret | mlrun-project-secrets-defaultinv | sectretKey1 | + Then verify "Env_Variables_Table_Secret_Name_Input" in "Advanced_Accordion" on "Modal_Wizard_Form" wizard should display options "Input_Hint"."Secret_Name_Rule_Options" + When click on "Delete_New_Row_Button" element in "Advanced_Accordion" on "Modal_Wizard_Form" wizard + When add data to "Advanced_Environment_Variables_Table" table on "Modal_Wizard_Form" wizard with several inputs + | name_input | type_dropdown | value_input | value_input_key | + | name1 | Secret | mlrun-project-secrets-default | sectretKey1 | + Then verify data in "Advanced_Environment_Variables_Table" table on "Modal_Wizard_Form" wizard + | name_verify | type_dropdown_verify | value_verify | + | name1 | secret | mlrun-project-secrets-default:sectretKey1 | + When click on "delete_btn" in "Advanced_Environment_Variables_Table" table on "Modal_Wizard_Form" wizard with offset "false" + | name_verify | + | name1 | + When add data to "Advanced_Environment_Variables_Table" table on "Modal_Wizard_Form" wizard with several inputs + | name_input | type_dropdown | value_input | value_input_key | + | name1 | Secret | mlrun-auth-secrets. | sectretKey1 | + Then verify "Env_Variables_Table_Secret_Name_Input" in "Advanced_Accordion" on "Modal_Wizard_Form" wizard should display options "Input_Hint"."Secret_Name_Rule_Options" + When click on "Delete_New_Row_Button" element in "Advanced_Accordion" on "Modal_Wizard_Form" wizard + When add data to "Advanced_Environment_Variables_Table" table on "Modal_Wizard_Form" wizard with several inputs + | name_input | type_dropdown | value_input | value_input_key | + | name1 | Secret | mlrun-auth-secrets | sectretKey1 | + Then verify data in "Advanced_Environment_Variables_Table" table on "Modal_Wizard_Form" wizard + | name_verify | type_dropdown_verify | value_verify | + | name1 | secret | mlrun-auth-secrets:sectretKey1 | + When click on "delete_btn" in "Advanced_Environment_Variables_Table" table on "Modal_Wizard_Form" wizard with offset "false" + | name_verify | + | name1 | + Then verify "Cross_Close_Button" element visibility on "Modal_Wizard_Form" wizard + And click on "Cross_Close_Button" element on "Modal_Wizard_Form" wizard + And wait load page + Then verify "Quick_Actions" element visibility on "Project" wizard + Then verify "Quick_Actions" dropdown element on "Project" wizard should contains "Project"."Quick_Actions_Options" + + @MLPM + @passive + @smoke + Scenario: MLPM031 - Check all mandatory components on Batch inference in Advanced section + Given open url + And wait load page + And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + Then verify "Quick_Actions" element visibility on "Project" wizard + Then verify "Quick_Actions" dropdown element on "Project" wizard should contains "Project"."Quick_Actions_Options" + Then select "Batch inference" option in "Quick_Actions" dropdown on "Project" wizard + And wait load page + Then verify "Title" element visibility on "Modal_Wizard_Form" wizard + Then "Title" element on "Modal_Wizard_Form" should contains "Batch Inference" value + Then verify "Cross_Close_Button" element visibility on "Modal_Wizard_Form" wizard + Then verify "Wizard_Steps_Content" element visibility on "Modal_Wizard_Form" wizard + Then "Function_Title" element on "Modal_Wizard_Form" should contains "batch-inference-v2" value + And click on "Step_5_Button" element on "commonPagesHeader" wizard + Then "Function_Title" element on "Modal_Wizard_Form" should contains "batch-inference-v2" value + Then "Preview_text" element on "Modal_Wizard_Form" should contains "Tech Preview" value + Then "Title" element on "Modal_Wizard_Form" should contains "Batch Inference" value + Then verify "Form_Header_Advanced" element visibility on "commonPagesHeader" wizard + Then "Form_Header_Advanced" element on "commonPagesHeader" should contains "Advanced" value + Then "Accordion_Advanced_Subheader" element on "Modal_Wizard_Form" should contains "Environment variables" value + Then verify "Advanced_Environment_Variables_Table" element visibility on "Modal_Wizard_Form" wizard + Then verify "Next_Button" element on "Modal_Wizard_Form" wizard is disabled + Then verify "Back_Button" element on "Modal_Wizard_Form" wizard is enabled + Then "Next_Button" element on "Modal_Wizard_Form" should contains "Next" value + Then "Back_Button" element on "Modal_Wizard_Form" should contains "Back" value + Then "Infer_Now_Button" element on "Modal_Wizard_Form" should contains "Infer now" value + Then "Schedule_Infer_Button" element on "Modal_Wizard_Form" should contains "Schedule Infer" value + Then verify "Accordion_Advanced_Subheader" element visibility on "Modal_Wizard_Form" wizard + Then "Accordion_Advanced_Subheader" element on "Modal_Wizard_Form" should contains "Environment variables" value + Then verify "Advanced_Environment_Variables_Table" element visibility on "Modal_Wizard_Form" wizard + When add data to "Advanced_Environment_Variables_Table" table on "Modal_Wizard_Form" wizard with several inputs + | name_input | type_dropdown | value_input | value_input_key | + | name1 | Value | value1 | | + | name2 | Secret | sectretName1 | sectretKey1 | + | name3 | Secret | sectretName2 | sectretKey2 | + | name4 | Value | value2 | | + | name5 | Secret | sectretName3 | sectretKey3 | + | name6 | Value | value3 | | + | name7 | Secret | sectretName4 | sectretKey4 | + | name8 | Value | value4 | | + Then verify data in "Advanced_Environment_Variables_Table" table on "Modal_Wizard_Form" wizard + | name_verify | type_dropdown_verify | value_verify | + | name1 | value | value1 | + | name2 | secret | sectretName1:sectretKey1 | + | name3 | secret | sectretName2:sectretKey2 | + | name4 | value | value2 | + | name5 | secret | sectretName3:sectretKey3 | + | name6 | value | value3 | + | name7 | secret | sectretName4:sectretKey4 | + | name8 | value | value4 | + When click on "delete_btn" in "Advanced_Environment_Variables_Table" table on "Modal_Wizard_Form" wizard with offset "false" + | name_verify | + | name1 | + | name3 | + | name6 | + Then verify data in "Advanced_Environment_Variables_Table" table on "Modal_Wizard_Form" wizard + | name_verify | type_dropdown_verify | value_verify | + | name2 | secret | sectretName1:sectretKey1 | + | name4 | value | value2 | + | name5 | secret | sectretName3:sectretKey3 | + | name7 | secret | sectretName4:sectretKey4 | + | name8 | value | value4 | + And wait load page + Then edit 1 row in "Advanced_Environment_Variables_Table" key-value table on "Modal_Wizard_Form" wizard + | name_input | value_input | + | edited | edited | + Then verify data in "Advanced_Environment_Variables_Table" table on "Modal_Wizard_Form" wizard + | name_verify | type_dropdown_verify | value_verify | + | name2edited | secret | sectretName1edited:sectretKey1 | + | name4 | value | value2 | + | name5 | secret | sectretName3:sectretKey3 | + | name7 | secret | sectretName4:sectretKey4 | + | name8 | value | value4 | + And wait load page + Then edit 5 row in "Advanced_Environment_Variables_Table" key-value table on "Modal_Wizard_Form" wizard + | name_input | value_input | + | edited | edited | + Then verify data in "Advanced_Environment_Variables_Table" table on "Modal_Wizard_Form" wizard + | name_verify | type_dropdown_verify | value_verify | + | name2edited | secret | sectretName1edited:sectretKey1 | + | name4 | value | value2 | + | name5 | secret | sectretName3:sectretKey3 | + | name7 | secret | sectretName4:sectretKey4 | + | name8edited | value | value4edited | + And wait load page + When click on "delete_btn" in "Advanced_Environment_Variables_Table" table on "Modal_Wizard_Form" wizard with offset "false" + | name_verify | + | name4 | + | name5 | + And wait load page + Then verify "Default_Input_Path_Input" element visibility in "Advanced_Accordion" on "Modal_Wizard_Form" wizard + Then type value "test" to "Default_Input_Path_Input" field on "Advanced_Accordion" on "Modal_Wizard_Form" wizard + Then verify "Default_Artifact_Path_Input" element visibility in "Advanced_Accordion" on "Modal_Wizard_Form" wizard + Then "Default_Artifact_Path_Input" element in "Advanced_Accordion" on "Modal_Wizard_Form" should contains "v3io:///projects/{{run.project}}/artifacts" attribute value + Then verify "Access_Key_Checkbox" element visibility on "Modal_Wizard_Form" wizard + Then uncheck "Access_Key_Checkbox" element on "Modal_Wizard_Form" wizard + Then verify "Access_Key_Input" element visibility on "Modal_Wizard_Form" wizard + Then type value " @" to "Access_Key_Input" field on "Modal_Wizard_Form" wizard + Then verify "Access_Key_Input" on "Modal_Wizard_Form" wizard should display hover warning "Input_Hint"."Input_Field_Invalid" + Then type value "" to "Access_Key_Input" field on "Modal_Wizard_Form" wizard + Then verify "Access_Key_Input" on "Modal_Wizard_Form" wizard should display hover warning "Input_Hint"."Input_Field_Require" + Then check "Access_Key_Checkbox" element on "Modal_Wizard_Form" wizard + When click on "delete_btn" in "Advanced_Environment_Variables_Table" table on "Modal_Wizard_Form" wizard with offset "false" + | name_verify | + | name2edited | + | name7 | + | name8edited | + And wait load page + When add data to "Advanced_Environment_Variables_Table" table on "Modal_Wizard_Form" wizard with several inputs + | name_input | type_dropdown | value_input | value_input_key | + | name1 | Secret | mlrun-project-secrets-defaultinv | sectretKey1 | + Then verify "Env_Variables_Table_Secret_Name_Input" in "Advanced_Accordion" on "Modal_Wizard_Form" wizard should display options "Input_Hint"."Secret_Name_Rule_Options" + When click on "Delete_New_Row_Button" element in "Advanced_Accordion" on "Modal_Wizard_Form" wizard + When add data to "Advanced_Environment_Variables_Table" table on "Modal_Wizard_Form" wizard with several inputs + | name_input | type_dropdown | value_input | value_input_key | + | name1 | Secret | mlrun-project-secrets-default | sectretKey1 | + Then verify data in "Advanced_Environment_Variables_Table" table on "Modal_Wizard_Form" wizard + | name_verify | type_dropdown_verify | value_verify | + | name1 | secret | mlrun-project-secrets-default:sectretKey1 | + When click on "delete_btn" in "Advanced_Environment_Variables_Table" table on "Modal_Wizard_Form" wizard with offset "false" + | name_verify | + | name1 | + When add data to "Advanced_Environment_Variables_Table" table on "Modal_Wizard_Form" wizard with several inputs + | name_input | type_dropdown | value_input | value_input_key | + | name1 | Secret | mlrun-auth-secrets. | sectretKey1 | + Then verify "Env_Variables_Table_Secret_Name_Input" in "Advanced_Accordion" on "Modal_Wizard_Form" wizard should display options "Input_Hint"."Secret_Name_Rule_Options" + When click on "Delete_New_Row_Button" element in "Advanced_Accordion" on "Modal_Wizard_Form" wizard + When add data to "Advanced_Environment_Variables_Table" table on "Modal_Wizard_Form" wizard with several inputs + | name_input | type_dropdown | value_input | value_input_key | + | name1 | Secret | mlrun-auth-secrets | sectretKey1 | + Then verify data in "Advanced_Environment_Variables_Table" table on "Modal_Wizard_Form" wizard + | name_verify | type_dropdown_verify | value_verify | + | name1 | secret | mlrun-auth-secrets:sectretKey1 | + When click on "delete_btn" in "Advanced_Environment_Variables_Table" table on "Modal_Wizard_Form" wizard with offset "false" + | name_verify | + | name1 | + And click on "Step_4_Button" element on "commonPagesHeader" wizard + Then "Function_Title" element on "Modal_Wizard_Form" should contains "batch-inference-v2" value + Then verify "Form_Header_Resources" element visibility on "commonPagesHeader" wizard + Then "Form_Header_Resources" element on "commonPagesHeader" should contains "Resources" value + Then verify "Volumes_Subheader" element visibility in "Resources_Accordion" on "Modal_Wizard_Form" wizard + Then verify "Volumes_Subheader" element in "Resources_Accordion" on "Modal_Wizard_Form" wizard should display hint "Label_Hint"."New_Job_Volumes" + When add new volume rows to "Volume_Paths_Table" table in "Resources_Accordion" on "Modal_Wizard_Form" wizard using nontable inputs + | Volume_Paths_Table_Type_Dropdown | Volume_Paths_Table_Volume_Name_Input | Volume_Paths_Table_Path_Input | Volume_Paths_Table_Secret_Name_Input | Add_New_Row_Button | + | Secret | | | mlrun-project-secrets-defaultinv | yes | + Then verify "Volume_Paths_Table_Volume_Name_Input" element in "Resources_Accordion" on "Modal_Wizard_Form" wizard should display hover warning "Input_Hint"."Input_Field_Require" + Then verify "Volume_Paths_Table_Path_Input" element in "Resources_Accordion" on "Modal_Wizard_Form" wizard should display hover warning "Input_Hint"."Input_Field_Require" + Then verify "Volume_Paths_Table_Path_Input" element in "Resources_Accordion" on "Modal_Wizard_Form" wizard should display hint "Input_Hint"."Mount_Path_Hint" + Then verify "Volume_Paths_Table_Secret_Name_Input" in "Resources_Accordion" on "Modal_Wizard_Form" wizard should display options "Input_Hint"."Secret_Name_Rule_Options" + When click on "Delete_New_Row_Button" element in "Resources_Accordion" on "Modal_Wizard_Form" wizard + When add new volume rows to "Volume_Paths_Table" table in "Resources_Accordion" on "Modal_Wizard_Form" wizard using nontable inputs + | Volume_Paths_Table_Type_Dropdown | Volume_Paths_Table_Volume_Name_Input | Volume_Paths_Table_Path_Input | Volume_Paths_Table_Secret_Name_Input | Add_New_Row_Button | + | Secret | test | test | mlrun-project-secrets-default | yes | + Then verify values in "Volume_Paths_Table" table in "Resources_Accordion" on "Modal_Wizard_Form" wizard + | type | volume_name | path | + | Secret | test | test | + When click on data "remove_btn" in "Volume_Paths_Table" table in "Resources_Accordion" on "Modal_Wizard_Form" wizard + | type | + | Secret | + When add new volume rows to "Volume_Paths_Table" table in "Resources_Accordion" on "Modal_Wizard_Form" wizard using nontable inputs + | Volume_Paths_Table_Type_Dropdown | Volume_Paths_Table_Volume_Name_Input | Volume_Paths_Table_Path_Input | Volume_Paths_Table_Secret_Name_Input | Add_New_Row_Button | + | Secret | | | mlrun-auth-secrets. | yes | + Then verify "Volume_Paths_Table_Volume_Name_Input" element in "Resources_Accordion" on "Modal_Wizard_Form" wizard should display hover warning "Input_Hint"."Input_Field_Require" + Then verify "Volume_Paths_Table_Path_Input" element in "Resources_Accordion" on "Modal_Wizard_Form" wizard should display hover warning "Input_Hint"."Input_Field_Require" + Then verify "Volume_Paths_Table_Path_Input" element in "Resources_Accordion" on "Modal_Wizard_Form" wizard should display hint "Input_Hint"."Mount_Path_Hint" + Then verify "Volume_Paths_Table_Secret_Name_Input" in "Resources_Accordion" on "Modal_Wizard_Form" wizard should display options "Input_Hint"."Secret_Name_Rule_Options" + When click on "Delete_New_Row_Button" element in "Resources_Accordion" on "Modal_Wizard_Form" wizard + When add new volume rows to "Volume_Paths_Table" table in "Resources_Accordion" on "Modal_Wizard_Form" wizard using nontable inputs + | Volume_Paths_Table_Type_Dropdown | Volume_Paths_Table_Volume_Name_Input | Volume_Paths_Table_Path_Input | Volume_Paths_Table_Secret_Name_Input | Add_New_Row_Button | + | Secret | test | test | mlrun-auth-secrets | yes | + Then verify values in "Volume_Paths_Table" table in "Resources_Accordion" on "Modal_Wizard_Form" wizard + | type | volume_name | path | + | Secret | test | test | + When click on data "remove_btn" in "Volume_Paths_Table" table in "Resources_Accordion" on "Modal_Wizard_Form" wizard + | type | + | Secret | + Then verify "Infer_Now_Button" element on "Modal_Wizard_Form" wizard is enabled + And click on "Infer_Now_Button" element on "Modal_Wizard_Form" wizard + And wait load page + And wait load page + Then verify "Notification_Pop_Up" element visibility on "Notification_Popup" wizard + Then "Notification_Pop_Up" element on "Notification_Popup" should contains "The batch run was started" value + And wait load page + Then verify "Notification_Pop_Up_Cross_Close_Button" element visibility on "Notification_Popup" wizard + Then click on "Notification_Pop_Up_Cross_Close_Button" element on "Notification_Popup" wizard + And wait load page + Then value in "name" column with "text" in "Jobs_Monitor_Table" on "Jobs_Monitor_Tab" wizard should contains "batch-inference-v2" + @MLPM @passive @smoke Scenario: MLPM008 - Check all mandatory components on Create ML Function - Job runtime Given open url And wait load page + When turn on demo mode with query params "false" + And wait load page And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard And wait load page - Then verify "Create_New" element visibility on "Project" wizard - Then verify "Create_New" dropdown element on "Project" wizard should contains "Project"."Create_New_Options" + Then verify "Quick_Actions" element visibility on "Project" wizard + Then verify "Quick_Actions" dropdown element on "Project" wizard should contains "Project"."Quick_Actions_Options_Demo" When turn on demo mode with query params "false" And wait load page - Then select "ML function" option in "Create_New" dropdown on "Project" wizard + Then select "ML function" option in "Quick_Actions" dropdown on "Project" wizard Then "Title" element on "Create_ML_Function_Popup" should contains "Create New Function" value And verify "Cross_Cancel_Button" element visibility on "Create_ML_Function_Popup" wizard Then verify "New_Function_Name_Input" element visibility on "Create_ML_Function_Popup" wizard @@ -470,13 +911,15 @@ Feature: Project Monitoring Page Scenario: MLPM009 - Check all mandatory components on Create ML Function - Serving runtime Given open url And wait load page + When turn on demo mode with query params "false" + And wait load page And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard And wait load page - Then verify "Create_New" element visibility on "Project" wizard - Then verify "Create_New" dropdown element on "Project" wizard should contains "Project"."Create_New_Options" + Then verify "Quick_Actions" element visibility on "Project" wizard + Then verify "Quick_Actions" dropdown element on "Project" wizard should contains "Project"."Quick_Actions_Options_Demo" When turn on demo mode with query params "false" And wait load page - Then select "ML function" option in "Create_New" dropdown on "Project" wizard + Then select "ML function" option in "Quick_Actions" dropdown on "Project" wizard Then "Title" element on "Create_ML_Function_Popup" should contains "Create New Function" value And verify "Cross_Cancel_Button" element visibility on "Create_ML_Function_Popup" wizard Then verify "New_Function_Name_Input" element visibility on "Create_ML_Function_Popup" wizard @@ -540,11 +983,13 @@ Feature: Project Monitoring Page Scenario: MLPM010 - Check all mandatory components on Create New Feature Set Given open url And wait load page + When turn on demo mode with query params "false" + And wait load page And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard And wait load page - Then verify "Create_New" element visibility on "Project" wizard - Then verify "Create_New" dropdown element on "Project" wizard should contains "Project"."Create_New_Options" - Then select "Feature set" option in "Create_New" dropdown on "Project" wizard + Then verify "Quick_Actions" element visibility on "Project" wizard + Then verify "Quick_Actions" dropdown element on "Project" wizard should contains "Project"."Quick_Actions_Options_Demo" + Then select "Feature set" option in "Quick_Actions" dropdown on "Project" wizard Then verify "Cross_Close_Button" element visibility on "New_Feature_Set" wizard Then verify "Feature_Set_Name_Input" element visibility on "New_Feature_Set" wizard Then verify "Version_Input" element visibility on "New_Feature_Set" wizard @@ -583,12 +1028,12 @@ Feature: Project Monitoring Page @MLPM @passive @smoke - Scenario: MLPM011 - Check Project Counter redirection to Models page + Scenario: MLPM011 - Check the redirection from Models counter to Models page Given open url And wait load page And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard And wait load page - Then click on "Model_Stats_Counter" element on "Project" wizard + When click on "Model_Stats_Counter" element in "Models_Stats_Container" on "Project" wizard And wait load page Then verify "Table_Name_Filter_Input" element visibility on "Models" wizard Then click on "Table_FilterBy_Button" element on "Models" wizard @@ -605,13 +1050,17 @@ Feature: Project Monitoring Page @MLPM @passive @smoke - Scenario: MLPM012 - Check Project Counter redirection to Feature Sets page + #TODO: Create Feature set from the Quick Actions dropdown menu + Scenario: MLPM012 - Check the redirection to Feature sets page during creating the Feature set Given open url And wait load page + When turn on demo mode with query params "false" + And wait load page And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard And wait load page - Then click on "FeatureSets_Stats_Counter" element on "Project" wizard + Then select "Feature set" option in "Quick_Actions" dropdown on "Project" wizard And wait load page + Then verify "Cross_Close_Button" element visibility on "New_Feature_Set" wizard Then verify "Feature_Store_Tab_Selector" on "Feature_Store_Feature_Sets_Tab" wizard should contains "Feature_Store"."Tab_List" Then verify "Feature Sets" tab is active in "Feature_Store_Tab_Selector" on "Feature_Store_Feature_Sets_Tab" wizard Then verify "Table_Refresh_Button" element visibility on "Feature_Store_Feature_Sets_Tab" wizard @@ -639,12 +1088,12 @@ Feature: Project Monitoring Page @MLPM @passive @smoke - Scenario: MLPM013 - Check Project Counter redirection to Artifacts page + Scenario: MLPM013 - Check the redirection from Other artifacts counter to Artifacts page Given open url And wait load page And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard And wait load page - Then click on "Artifacts_Stats_Counter" element on "Project" wizard + When click on "Other_Artifacts_Counter_Number" element in "Artifacts_Stats_Container" on "Project" wizard And wait load page Then verify "Table_Name_Filter_Input" element visibility on "Files" wizard Then click on "Table_FilterBy_Button" element on "Files" wizard @@ -655,6 +1104,74 @@ Feature: Project Monitoring Page Then verify "Files_Table" element visibility on "Files" wizard Then verify "Register_File_Button" element visibility on "Files" wizard Then "Register_File_Button" element on "Files" should contains "Register artifact" value + + @MLPM + @passive + @smoke + Scenario: MLPM024 - Check the redirection from Datasets counter to Datasets page + Given open url + And wait load page + And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + When click on "Datasets_Counter_Number" element in "Artifacts_Stats_Container" on "Project" wizard + And wait load page + Then verify "Table_Name_Filter_Input" element visibility on "Datasets" wizard + Then verify "Table_FilterBy_Button" element visibility on "Datasets" wizard + Then click on "Table_FilterBy_Button" element on "Datasets" wizard + Then "Title" element on "FilterBy_Popup" should contains "Filter by" value + Then verify "Table_Label_Filter_Input" element visibility on "FilterBy_Popup" wizard + Then verify "Table_Tree_Filter_Dropdown" element visibility on "FilterBy_Popup" wizard + Then verify "Table_Tree_Filter_Dropdown" dropdown element on "FilterBy_Popup" wizard should contains "Dropdown_Options"."Tag_Filer_Options_Main_Table" + Then click on "Title" element on "FilterBy_Popup" wizard + Then verify "Show_Iterations_Checkbox" element visibility on "FilterBy_Popup" wizard + Then "Checkbox_Label" element on "FilterBy_Popup" should contains "Show best iteration only" value + Then verify "Clear_Button" element visibility on "FilterBy_Popup" wizard + Then verify "Apply_Button" element visibility on "FilterBy_Popup" wizard + Then verify "Table_Refresh_Button" element visibility on "Datasets" wizard + Then verify "Datasets_Table" element visibility on "Datasets" wizard + + @MLPM + @passive + @smoke + Scenario: MLPM025 - Check the redirection from Documents counter to Documents page + Given open url + And wait load page + And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + When click on "Documents_Counter_Number" element in "Artifacts_Stats_Container" on "Project" wizard + And wait load page + Then verify "Table_Name_Filter_Input" element visibility on "Documents" wizard + Then verify "Table_FilterBy_Button" element visibility on "Documents" wizard + Then verify "Table_FilterBy_Button" element on "Documents" wizard should display hover tooltip "Common_Tooltips"."FilterBy_Button" + Then click on "Table_FilterBy_Button" element on "Documents" wizard + Then "Title" element on "FilterBy_Popup" should contains "Filter by" value + Then verify "Table_Label_Filter_Input" element visibility on "FilterBy_Popup" wizard + Then verify "Table_Tree_Filter_Dropdown" element visibility on "FilterBy_Popup" wizard + Then verify "Table_Tree_Filter_Dropdown" dropdown element on "FilterBy_Popup" wizard should contains "Dropdown_Options"."Tag_Filer_Options_Main_Table" + Then click on "Title" element on "FilterBy_Popup" wizard + Then verify "Show_Iterations_Checkbox" element visibility on "FilterBy_Popup" wizard + Then "Checkbox_Label" element on "FilterBy_Popup" should contains "Show best iteration only" value + Then verify "Clear_Button" element visibility on "FilterBy_Popup" wizard + Then verify "Clear_Button" element on "FilterBy_Popup" wizard is disabled + Then verify "Apply_Button" element visibility on "FilterBy_Popup" wizard + Then verify "Apply_Button" element on "FilterBy_Popup" wizard is disabled + Then verify "Table_Refresh_Button" element visibility on "Documents" wizard + Then verify "Table_Refresh_Button" element on "Documents" wizard should display hover tooltip "Common_Tooltips"."Refresh_Button" + Then verify "Documents_Table" element visibility on "Documents" wizard + + @MLPM + @passive + @smoke + #TODO: Add components check on LLM prompts page + Scenario: MLPM026 - Check the redirection from LLM prompts counter to LLM prompts page + Given open url + And wait load page + And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + When click on "LLM_Prompts_Counter_Number" element in "Artifacts_Stats_Container" on "Project" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "LLM prompts" value + Then verify redirection to "projects/default/llm-prompts?bePage=1&fePage=1" @MLPM @passive @@ -664,13 +1181,27 @@ Feature: Project Monitoring Page And wait load page And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard And wait load page - Then click on cell with value "Running jobs" in "name" column in "Jobs_Info_Card_Statistics" table on "Project" wizard + When click on "In_Process_Counter_Subtitle" element in "Runs_Statistic_Section_Container" on "Project" wizard And wait load page Then verify "Jobs_Tab_Selector" on "Jobs_Monitor_Tab" wizard should contains "Jobs_And_Workflows"."Tab_List" Then verify "Monitor Jobs" tab is active in "Jobs_Tab_Selector" on "Jobs_Monitor_Tab" wizard Then verify "Table_Name_Filter_Input" element visibility on "Jobs_Monitor_Tab" wizard Then verify "Date_Picker_Filter_Dropdown" element visibility on "Jobs_Monitor_Tab" wizard + Then verify "Date_Picker_Filter_Dropdown" dropdown on "Jobs_Monitor_Tab" wizard selected option value "Any time" Then verify "Table_FilterBy_Button" element visibility on "Jobs_Monitor_Tab" wizard + Then click on "Table_FilterBy_Button" element on "Jobs_Monitor_Tab" wizard + Then verify "Status_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "4 items selected" + Then verify "Type_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" + And wait load page + Then click on "Status_Filter_Element" element on "FilterBy_Popup" wizard + Then "Status_All_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Status_Aborting_Checkbox" element should be checked on "FilterBy_Popup" wizard + Then "Status_Jobs_Running_Checkbox" element should be checked on "FilterBy_Popup" wizard + Then "Status_Pending_Checkbox" element should be checked on "FilterBy_Popup" wizard + Then "Status_Pending_retry_Checkbox" element should be checked on "FilterBy_Popup" wizard + Then "Status_Aborted_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Status_Jobs_Error_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Status_Jobs_Completed_Checkbox" element should be unchecked on "FilterBy_Popup" wizard Then verify "Batch_Run_Button" element visibility on "Jobs_Monitor_Tab" wizard Then "Batch_Run_Button" element on "Jobs_Monitor_Tab" should contains "Batch run" value Then verify "Resource_Monitoring_Button" element visibility on "Jobs_Monitor_Tab" wizard @@ -678,26 +1209,221 @@ Feature: Project Monitoring Page Then "Auto_Refresh_Checkbox" element should be unchecked on "Jobs_Monitor_Tab" wizard Then verify "Table_Refresh_Button" element visibility on "Jobs_Monitor_Tab" wizard Then verify "Jobs_Monitor_Table" element visibility on "Jobs_Monitor_Tab" wizard + Then navigate back + And wait load page + When click on "Failed_Counter_Subtitle" element in "Runs_Statistic_Section_Container" on "Project" wizard + And wait load page + Then verify "Jobs_Tab_Selector" on "Jobs_Monitor_Tab" wizard should contains "Jobs_And_Workflows"."Tab_List" + Then verify "Monitor Jobs" tab is active in "Jobs_Tab_Selector" on "Jobs_Monitor_Tab" wizard + Then verify "Table_Name_Filter_Input" element visibility on "Jobs_Monitor_Tab" wizard + Then verify "Date_Picker_Filter_Dropdown" element visibility on "Jobs_Monitor_Tab" wizard + Then verify "Date_Picker_Filter_Dropdown" dropdown on "Jobs_Monitor_Tab" wizard selected option value "Past 24 hours" + Then verify "Table_FilterBy_Button" element visibility on "Jobs_Monitor_Tab" wizard + Then click on "Table_FilterBy_Button" element on "Jobs_Monitor_Tab" wizard + Then verify "Status_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "Aborted, Error" + Then verify "Type_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" + Then verify "Batch_Run_Button" element visibility on "Jobs_Monitor_Tab" wizard + Then "Batch_Run_Button" element on "Jobs_Monitor_Tab" should contains "Batch run" value + Then verify "Resource_Monitoring_Button" element visibility on "Jobs_Monitor_Tab" wizard + Then verify "Auto_Refresh_Checkbox" element visibility on "Jobs_Monitor_Tab" wizard + Then "Auto_Refresh_Checkbox" element should be unchecked on "Jobs_Monitor_Tab" wizard + Then verify "Table_Refresh_Button" element visibility on "Jobs_Monitor_Tab" wizard + Then navigate back + And wait load page + When click on "Succeeded_Counter_Subtitle" element in "Runs_Statistic_Section_Container" on "Project" wizard + And wait load page + Then verify "Jobs_Tab_Selector" on "Jobs_Monitor_Tab" wizard should contains "Jobs_And_Workflows"."Tab_List" + Then verify "Monitor Jobs" tab is active in "Jobs_Tab_Selector" on "Jobs_Monitor_Tab" wizard + Then verify "Table_Name_Filter_Input" element visibility on "Jobs_Monitor_Tab" wizard + Then verify "Date_Picker_Filter_Dropdown" element visibility on "Jobs_Monitor_Tab" wizard + Then verify "Date_Picker_Filter_Dropdown" dropdown on "Jobs_Monitor_Tab" wizard selected option value "Past 24 hours" + Then verify "Table_FilterBy_Button" element visibility on "Jobs_Monitor_Tab" wizard + Then click on "Table_FilterBy_Button" element on "Jobs_Monitor_Tab" wizard + Then verify "Status_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "Completed" + Then verify "Type_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" + Then verify "Batch_Run_Button" element visibility on "Jobs_Monitor_Tab" wizard + Then "Batch_Run_Button" element on "Jobs_Monitor_Tab" should contains "Batch run" value + Then verify "Resource_Monitoring_Button" element visibility on "Jobs_Monitor_Tab" wizard + Then verify "Auto_Refresh_Checkbox" element visibility on "Jobs_Monitor_Tab" wizard + Then "Auto_Refresh_Checkbox" element should be unchecked on "Jobs_Monitor_Tab" wizard + Then verify "Table_Refresh_Button" element visibility on "Jobs_Monitor_Tab" wizard - @MLPM @passive @smoke - Scenario: MLPM015 - Check Project Counter redirection to Schedules tab + Scenario: MLPM015 - Check the redirection from Scheduled counter to Schedule tab Given open url And wait load page And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard And wait load page - Then click on cell with value "Scheduled" in "name" column in "Jobs_Info_Card_Statistics" table on "Project" wizard + When click on "Scheduled_Stats_Counter" element in "Scheduled_Stats_Container" on "Project" wizard + And wait load page + Then verify "Schedule" tab is active in "Jobs_Tab_Selector" on "Jobs_Monitor_Tab" wizard + Then verify "Table_Name_Filter_Input" element visibility on "Schedule_Monitor_Tab" wizard + Then verify "Date_Picker_Filter_Dropdown" element visibility on "Schedule_Monitor_Tab" wizard + Then verify "Date_Picker_Filter_Dropdown" dropdown on "Schedule_Monitor_Tab" wizard selected option value "Next 24 hours" + Then verify "Table_FilterBy_Button" element visibility on "Schedule_Monitor_Tab" wizard + Then click on "Table_FilterBy_Button" element on "Schedule_Monitor_Tab" wizard + Then verify "Type_Filter_Dropdown_Schedule" dropdown on "FilterBy_Popup" wizard selected option value "All" + Then click on "Type_Filter_Element" element on "FilterBy_Popup" wizard + And wait load page + Then "Type_All_Checkbox" element should be checked on "FilterBy_Popup" wizard + Then "Type_Job_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Workflow_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Spark_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Horovod_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Dask_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Databricks_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then click on "Type_Filter_Element" element on "FilterBy_Popup" wizard + And wait load page + Then verify "Batch_Run_Button" element visibility on "Schedule_Monitor_Tab" wizard + Then "Batch_Run_Button" element on "Schedule_Monitor_Tab" should contains "Batch run" value + Then verify "Table_Refresh_Button" element visibility on "Schedule_Monitor_Tab" wizard + Then verify "Schedule_Monitor_Table" element visibility on "Schedule_Monitor_Tab" wizard + Then navigate back + And wait load page + When click on "Jobs_Counter_Number" element in "Scheduled_Stats_Container" on "Project" wizard And wait load page Then verify "Schedule" tab is active in "Jobs_Tab_Selector" on "Jobs_Monitor_Tab" wizard Then verify "Table_Name_Filter_Input" element visibility on "Schedule_Monitor_Tab" wizard Then verify "Date_Picker_Filter_Dropdown" element visibility on "Schedule_Monitor_Tab" wizard + Then verify "Date_Picker_Filter_Dropdown" dropdown on "Schedule_Monitor_Tab" wizard selected option value "Next 24 hours" Then verify "Table_FilterBy_Button" element visibility on "Schedule_Monitor_Tab" wizard + Then verify "Table_FilterBy_Button" element on "Schedule_Monitor_Tab" wizard should display hover tooltip "Common_Tooltips"."FilterBy_Button_1" + Then click on "Table_FilterBy_Button" element on "Schedule_Monitor_Tab" wizard + Then verify "Type_Filter_Dropdown_Schedule" dropdown on "FilterBy_Popup" wizard selected option value "5 items selected" + Then click on "Type_Filter_Element" element on "FilterBy_Popup" wizard + And wait load page + Then "Type_All_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Job_Checkbox" element should be checked on "FilterBy_Popup" wizard + Then "Type_Workflow_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Spark_Checkbox" element should be checked on "FilterBy_Popup" wizard + Then "Type_Horovod_Checkbox" element should be checked on "FilterBy_Popup" wizard + Then "Type_Dask_Checkbox" element should be checked on "FilterBy_Popup" wizard + Then "Type_Databricks_Checkbox" element should be checked on "FilterBy_Popup" wizard + Then click on "Type_Filter_Element" element on "FilterBy_Popup" wizard + And wait load page Then verify "Batch_Run_Button" element visibility on "Schedule_Monitor_Tab" wizard Then "Batch_Run_Button" element on "Schedule_Monitor_Tab" should contains "Batch run" value Then verify "Table_Refresh_Button" element visibility on "Schedule_Monitor_Tab" wizard Then verify "Schedule_Monitor_Table" element visibility on "Schedule_Monitor_Tab" wizard + Then click on breadcrumbs "project" label on "commonPagesHeader" wizard + And wait load page + When click on "Workflows_Counter_Number" element in "Scheduled_Stats_Container" on "Project" wizard + And wait load page + Then verify "Schedule" tab is active in "Jobs_Tab_Selector" on "Jobs_Monitor_Tab" wizard + Then verify "Table_Name_Filter_Input" element visibility on "Schedule_Monitor_Tab" wizard + Then verify "Date_Picker_Filter_Dropdown" element visibility on "Schedule_Monitor_Tab" wizard + Then verify "Date_Picker_Filter_Dropdown" dropdown on "Schedule_Monitor_Tab" wizard selected option value "Next 24 hours" + Then verify "Table_FilterBy_Button" element visibility on "Schedule_Monitor_Tab" wizard + Then verify "Table_FilterBy_Button" element on "Schedule_Monitor_Tab" wizard should display hover tooltip "Common_Tooltips"."FilterBy_Button_1" + Then click on "Table_FilterBy_Button" element on "Schedule_Monitor_Tab" wizard + Then verify "Type_Filter_Dropdown_Schedule" dropdown on "FilterBy_Popup" wizard selected option value "Workflow" + Then click on "Type_Filter_Element" element on "FilterBy_Popup" wizard + And wait load page + Then "Type_All_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Job_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Workflow_Checkbox" element should be checked on "FilterBy_Popup" wizard + Then "Type_Spark_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Horovod_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Dask_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then "Type_Databricks_Checkbox" element should be unchecked on "FilterBy_Popup" wizard + Then click on "Type_Filter_Element" element on "FilterBy_Popup" wizard + And wait load page + Then verify "Batch_Run_Button" element visibility on "Schedule_Monitor_Tab" wizard + Then "Batch_Run_Button" element on "Schedule_Monitor_Tab" should contains "Batch run" value + Then verify "Table_Refresh_Button" element visibility on "Schedule_Monitor_Tab" wizard + And verify "No_Data_Message" element visibility on "commonPagesHeader" wizard + Then "No_Data_Message" component on "commonPagesHeader" should be equal "No_Data_Message"."Common_Message_Scheduled_Type" + + @MLPM + @passive + @smoke + Scenario: MLPM027 - Check the redirection from Workflows counter to Monitor Workflows tab + Given open url + And wait load page + And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + When click on "Workflows_Stats_Counter" element in "Workflows_Stats_Container" on "Project" wizard + And wait load page + Then verify "Monitor Workflows" tab is active in "Jobs_Tab_Selector" on "Jobs_Monitor_Tab" wizard + Then verify "Table_Name_Filter_Input" element visibility on "Workflows_Monitor_Tab" wizard + Then verify "Date_Picker_Filter_Dropdown" element visibility on "Workflows_Monitor_Tab" wizard + Then verify "Date_Picker_Filter_Dropdown" dropdown on "Schedule_Monitor_Tab" wizard selected option value "Past 24 hours" + Then verify "Table_FilterBy_Button" element visibility on "Workflows_Monitor_Tab" wizard + Then click on "Table_FilterBy_Button" element on "Workflows_Monitor_Tab" wizard + Then verify "Status_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" + Then verify "Table_Refresh_Button" element visibility on "Workflows_Monitor_Tab" wizard + And verify "No_Data_Message" element visibility on "commonPagesHeader" wizard + Then "No_Data_Message" component on "commonPagesHeader" should be equal "No_Data_Message"."Common_Message_Monitoring_Workflow" + Then navigate back + And wait load page + When click on "In_Process_Counter_Number" element in "Workflows_Stats_Container" on "Project" wizard + And wait load page + Then verify "Monitor Workflows" tab is active in "Jobs_Tab_Selector" on "Jobs_Monitor_Tab" wizard + Then verify "Table_Name_Filter_Input" element visibility on "Workflows_Monitor_Tab" wizard + Then verify "Date_Picker_Filter_Dropdown" element visibility on "Workflows_Monitor_Tab" wizard + Then verify "Date_Picker_Filter_Dropdown" dropdown on "Schedule_Monitor_Tab" wizard selected option value "Any time" + Then verify "Table_FilterBy_Button" element visibility on "Workflows_Monitor_Tab" wizard + Then click on "Table_FilterBy_Button" element on "Workflows_Monitor_Tab" wizard + Then verify "Status_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "Running, Terminating" + Then verify "Table_Refresh_Button" element visibility on "Workflows_Monitor_Tab" wizard + And verify "No_Data_Message" element visibility on "commonPagesHeader" wizard + Then "No_Data_Message" component on "commonPagesHeader" should be equal "No_Data_Message"."Common_Message_Monitoring_Workflow_Status" + Then click on breadcrumbs "project" label on "commonPagesHeader" wizard + And wait load page + When click on "Failed_Counter_Number" element in "Workflows_Stats_Container" on "Project" wizard + And wait load page + Then verify "Monitor Workflows" tab is active in "Jobs_Tab_Selector" on "Jobs_Monitor_Tab" wizard + Then verify "Table_Name_Filter_Input" element visibility on "Workflows_Monitor_Tab" wizard + Then verify "Date_Picker_Filter_Dropdown" element visibility on "Workflows_Monitor_Tab" wizard + Then verify "Date_Picker_Filter_Dropdown" dropdown on "Schedule_Monitor_Tab" wizard selected option value "Past 24 hours" + Then verify "Table_FilterBy_Button" element visibility on "Workflows_Monitor_Tab" wizard + Then click on "Table_FilterBy_Button" element on "Workflows_Monitor_Tab" wizard + Then verify "Status_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "Error, Failed" + Then verify "Table_Refresh_Button" element visibility on "Workflows_Monitor_Tab" wizard + And verify "No_Data_Message" element visibility on "commonPagesHeader" wizard + Then "No_Data_Message" component on "commonPagesHeader" should be equal "No_Data_Message"."Common_Message_Jobs_Monitoring_Status" + Then navigate back + And wait load page + When click on "Succeeded_Counter_Number" element in "Workflows_Stats_Container" on "Project" wizard + And wait load page + Then verify "Monitor Workflows" tab is active in "Jobs_Tab_Selector" on "Jobs_Monitor_Tab" wizard + Then verify "Table_Name_Filter_Input" element visibility on "Workflows_Monitor_Tab" wizard + Then verify "Date_Picker_Filter_Dropdown" element visibility on "Workflows_Monitor_Tab" wizard + Then verify "Date_Picker_Filter_Dropdown" dropdown on "Schedule_Monitor_Tab" wizard selected option value "Past 24 hours" + Then verify "Table_FilterBy_Button" element visibility on "Workflows_Monitor_Tab" wizard + Then click on "Table_FilterBy_Button" element on "Workflows_Monitor_Tab" wizard + Then verify "Status_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "Completed" + Then verify "Table_Refresh_Button" element visibility on "Workflows_Monitor_Tab" wizard + And verify "No_Data_Message" element visibility on "commonPagesHeader" wizard + Then "No_Data_Message" component on "commonPagesHeader" should be equal "No_Data_Message"."Common_Message_Jobs_Monitoring_Status" + + @MLPM + @passive + @smoke + #TODO: Add components check on LLM prompts page + Scenario: MLPM028 - Check the redirection from Monitoring App counter to Monitoring app page + Given open url + And wait load page + And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + When click on "Monitoring_App_Running_Stats_Counter" element in "Monitoring_App_Stats_Container" on "Project" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "Monitoring app" value + Then verify redirection to "projects/default/monitoring-app" + Then verify "Date_Picker_Filter_Dropdown" element visibility on "Monitoring_App" wizard + Then verify "Date_Picker_Filter_Dropdown" dropdown on "Monitoring_App" wizard selected option value "Past 24 hours" + Then verify "Refresh_Button" element visibility on "Monitoring_App" wizard + Then navigate back + And wait load page + When click on "Monitoring_App_Failed_Stats_Counter" element in "Monitoring_App_Stats_Container" on "Project" wizard + And wait load page + Then verify breadcrumbs "tab" label should be equal "Monitoring app" value + Then verify redirection to "projects/default/monitoring-app" + Then verify "Date_Picker_Filter_Dropdown" element visibility on "Monitoring_App" wizard + Then verify "Date_Picker_Filter_Dropdown" dropdown on "Monitoring_App" wizard selected option value "Past 24 hours" + Then verify "Refresh_Button" element visibility on "Monitoring_App" wizard @MLPM @passive @@ -726,13 +1452,13 @@ Feature: Project Monitoring Page @MLPM @passive @smoke - Scenario: MLPM016 - Check redirect to Jobs and workflows page using See All link + Scenario: MLPM016 - Check redirect to Jobs and workflows page using All jobs link Given open url And wait load page And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard And wait load page Then verify breadcrumbs "project" label should be equal "default" value - Then select "Batch run" option in "Create_New" dropdown on "Project" wizard + Then select "Batch run" option in "Quick_Actions" dropdown on "Project" wizard And wait load page And click on row root with value "test" in "name" column in "Functions_Table" table on "Modal_Wizard_Form" wizard And wait load page @@ -750,9 +1476,10 @@ Feature: Project Monitoring Page Then click on "Project_Monitoring_Button" element on "commonPagesHeader" wizard And hover "MLRun_Logo" component on "commonPagesHeader" wizard And wait load page - Then verify "Recent_text" element visibility on "Project" wizard - Then verify "Create_New" dropdown element on "Project" wizard should contains "Project"."Create_New_Options" - Then click on "See_All_Jobs_Link" element on "Project" wizard + Then verify "Recent_Text" element visibility in "Runs_Statistic_Section_Container" on "Project" wizard + Then verify "Quick_Actions" dropdown element on "Project" wizard should contains "Project"."Quick_Actions_Options" + Then verify "All_Jobs_Link" element visibility in "Runs_Statistic_Section_Container" on "Project" wizard + When click on "All_Jobs_Link" element in "Runs_Statistic_Section_Container" on "Project" wizard And wait load page Then verify breadcrumbs "tab" label should be equal "Jobs and workflows" value Then verify "Jobs_Tab_Selector" on "Jobs_Monitor_Tab" wizard should contains "Jobs_And_Workflows"."Tab_List" @@ -774,8 +1501,8 @@ Feature: Project Monitoring Page And wait load page And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard And wait load page - And save to context "name" column and "href" attribute on 1 row from "Jobs_And_Workflows" table on "Project" wizard - When click on cell with row index 1 in "name" column in "Jobs_And_Workflows" table on "Project" wizard + And save to context "name" column and "href" attribute on 1 row from "Runs_Statistic_Table" table on "Project" wizard + When click on cell with row index 1 in "name" column in "Runs_Statistic_Table" table on "Project" wizard And wait load page Then verify "Arrow_Back" element visibility on "Jobs_Monitor_Tab_Info_Pane" wizard Then verify "Header" element visibility on "Jobs_Monitor_Tab_Info_Pane" wizard @@ -796,7 +1523,7 @@ Feature: Project Monitoring Page And wait load page And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard And wait load page - Then click on "ConsumerGroups_Stats_Counter" element on "Project" wizard + When click on "ConsumerGroups_Stats_Counter" element in "Realtime_Functions_Nuclio_Statistic_Section" on "Project" wizard And wait load page Then "Title" element on "Consumer_Groups" should contains "Consumer groups (v3io stream)" value Then "Description" element on "Consumer_Groups" should contains "This report displays the project's consumer groups for Iguazio v3io streams" value @@ -806,13 +1533,11 @@ Feature: Project Monitoring Page Then click on "Arrow_Back" element on "Consumer_Groups" wizard And wait load page Then verify breadcrumbs "project" label should be equal "default" value - Then verify "Create_New" element visibility on "Project" wizard + Then verify "Quick_Actions" element visibility on "Project" wizard Then verify "Refresh_Button" element visibility on "Project" wizard - Then verify "Dashboard_Realtime_Functions_Table" element visibility on "Project" wizard - Then verify "Jobs_And_Workflows" element visibility on "Project" wizard + Then verify "Realtime_Functions_Nuclio_Table" element visibility on "Project" wizard + Then verify "Runs_Statistic_Table" element visibility on "Project" wizard Then verify "Mono_Values_Cards" element visibility on "Project" wizard - Then verify "Jobs_Info_Card_Statistics" element visibility on "Project" wizard - Then verify "Real_Time_Functions_Card_Statistics" element visibility on "Project" wizard @MLPM @passive @@ -822,15 +1547,15 @@ Feature: Project Monitoring Page And wait load page And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard And wait load page - Then click on "ConsumerGroups_Stats_Counter" element on "Project" wizard + When click on "ConsumerGroups_Stats_Counter" element in "Realtime_Functions_Nuclio_Statistic_Section" on "Project" wizard And wait load page Then verify "Search_Input" element visibility on "Consumer_Groups" wizard Then verify "Consumer_Groups_Table" element visibility on "Consumer_Groups" wizard - Then type value "C" to "Search_Input" field on "Consumer_Groups" wizard + Then type value "c" to "Search_Input" field on "Consumer_Groups" wizard Then value in "consumer_group_name" column with "text" in "Consumer_Groups_Table" on "Consumer_Groups" wizard should contains "C" - Then type value "CONSUMER" to "Search_Input" field on "Consumer_Groups" wizard + Then type value "consumer" to "Search_Input" field on "Consumer_Groups" wizard Then value in "consumer_group_name" column with "text" in "Consumer_Groups_Table" on "Consumer_Groups" wizard should contains "Consumer" - Then type value "randomText" to "Search_Input" field on "Consumer_Groups" wizard + Then type value "randomtext" to "Search_Input" field on "Consumer_Groups" wizard Then check "ConsumerGroup1" value not in "consumer_group_name" column in "Consumer_Groups_Table" table on "Consumer_Groups" wizard @MLPM @@ -841,13 +1566,14 @@ Feature: Project Monitoring Page And wait load page And click on row root with value "churn-project-admin" in "name" column in "Projects_Table" table on "Projects" wizard And wait load page - Then click on "ConsumerGroups_Stats_Counter" element on "Project" wizard + When click on "ConsumerGroups_Stats_Counter" element in "Realtime_Functions_Nuclio_Statistic_Section" on "Project" wizard And wait load page And verify "No_Data_Message" element visibility on "commonPagesHeader" wizard Then "No_Data_Message" component on "commonPagesHeader" should contains "No_Data_Message"."No_Consumer_Group_Yet" Then select "project" with "default" value in breadcrumbs menu And wait load page - Then click on "ConsumerGroups_Stats_Counter" element on "Project" wizard + When click on "ConsumerGroups_Stats_Counter" element in "Realtime_Functions_Nuclio_Statistic_Section" on "Project" wizard + And wait load page And wait load page And save to context "consumer_group_name" column and "href" attribute on 1 row from "Consumer_Groups_Table" table on "Consumer_Groups" wizard And click on cell with row index 1 in "consumer_group_name" column in "Consumer_Groups_Table" table on "Consumer_Groups" wizard @@ -871,18 +1597,18 @@ Feature: Project Monitoring Page And wait load page And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard And wait load page - Then click on "ConsumerGroups_Stats_Counter" element on "Project" wizard + When click on "ConsumerGroups_Stats_Counter" element in "Realtime_Functions_Nuclio_Statistic_Section" on "Project" wizard And wait load page And click on cell with row index 1 in "consumer_group_name" column in "Consumer_Groups_Table" table on "Consumer_Groups" wizard And wait load page Then verify "Search_Input" element visibility on "Consumer_Groups" wizard Then verify "Shard_Lags_Table" element visibility on "Consumer_Groups" wizard - Then type value "SHARD" to "Search_Input" field on "Consumer_Groups" wizard + Then type value "shard" to "Search_Input" field on "Consumer_Groups" wizard Then click on "Refresh_Button" element on "Consumer_Groups" wizard Then value in "shard_name" column with "text" in "Shard_Lags_Table" on "Consumer_Groups" wizard should contains "shard" Then type value "shard-id-0" to "Search_Input" field on "Consumer_Groups" wizard Then value in "shard_name" column with "text" in "Shard_Lags_Table" on "Consumer_Groups" wizard should contains "shard-id-0" - Then type value "randomText" to "Search_Input" field on "Consumer_Groups" wizard + Then type value "randomtext" to "Search_Input" field on "Consumer_Groups" wizard Then check "shard-id-0" value not in "shard_name" column in "Shard_Lags_Table" table on "Consumer_Groups" wizard @MLPM @@ -892,7 +1618,7 @@ Feature: Project Monitoring Page And wait load page And click on row root with value "auto-generated-data" in "name" column in "Projects_Table" table on "Projects" wizard And wait load page - Then click on "Alerts_Stats_Total_Number" element on "Project" wizard + When click on "Alerts_Stats_Counter" element in "Alerts_Stats_Container" on "Project" wizard And wait load page Then verify "Search_By_Name_Filter_Input" element visibility on "Alerts" wizard Then verify "Date_Picker_Filter_Dropdown" element visibility on "Alerts" wizard @@ -915,7 +1641,7 @@ Feature: Project Monitoring Page Then verify "Event_Type_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" Then click on breadcrumbs "project" label on "commonPagesHeader" wizard And wait load page - Then click on "Alerts_Stats_Endpoint_Number" element on "Project" wizard + When click on "Alerts_Stats_Endpoint_Counter" element in "Alerts_Stats_Container" on "Project" wizard And wait load page Then verify "Search_By_Name_Filter_Input" element visibility on "Alerts" wizard Then verify "Date_Picker_Filter_Dropdown" element visibility on "Alerts" wizard @@ -937,7 +1663,7 @@ Feature: Project Monitoring Page Then verify "Event_Type_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" Then click on breadcrumbs "project" label on "commonPagesHeader" wizard And wait load page - Then click on "Alerts_Stats_Jobs_Number" element on "Project" wizard + When click on "Alerts_Stats_Jobs_Counter" element in "Alerts_Stats_Container" on "Project" wizard And wait load page Then verify "Search_By_Name_Filter_Input" element visibility on "Alerts" wizard Then verify "Date_Picker_Filter_Dropdown" element visibility on "Alerts" wizard @@ -958,7 +1684,7 @@ Feature: Project Monitoring Page Then verify "Event_Type_Filter_Dropdown" dropdown on "FilterBy_Popup" wizard selected option value "All" Then click on breadcrumbs "project" label on "commonPagesHeader" wizard And wait load page - Then click on "Alerts_Stats_Application_Number" element on "Project" wizard + When click on "Alerts_Stats_Application_Counter" element in "Alerts_Stats_Container" on "Project" wizard And wait load page Then verify "Search_By_Name_Filter_Input" element visibility on "Alerts" wizard Then verify "Date_Picker_Filter_Dropdown" element visibility on "Alerts" wizard diff --git a/tests/features/projectsPage.feature b/tests/features/projectsPage.feature index 663a6bd9a3..0f434d3502 100644 --- a/tests/features/projectsPage.feature +++ b/tests/features/projectsPage.feature @@ -5,7 +5,6 @@ Feature: Projects Page @MLPr @passive @smoke - #TODO: last two steps are unstable on small screen extensions because scroll change the screen coordinates, it needs another solution Scenario: MLPr001 - Check all mandatory components Given open url And wait load page @@ -91,6 +90,8 @@ Feature: Projects Page Scenario: MLPr005 - Verify all mandatory components on Archive ML Project Given open url And wait load page + When scroll to the element with "churn-project-admin" value in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page Then select "Archive" option in action menu on "Projects" wizard in "Projects_Table" table at row with "churn-project-admin" value in "name" column Then verify if "Common_Popup" popup dialog appears Then "Description" component on "Common_Popup" should contains "Descriptions"."Archive_Project" @@ -105,6 +106,8 @@ Feature: Projects Page Scenario: MLPr006 - Verify all mandatory components on Delete existing ML Project Given open url And wait load page + When scroll to the element with "churn-project-admin" value in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page Then select "Delete" option in action menu on "Projects" wizard in "Projects_Table" table at row with "churn-project-admin" value in "name" column And wait load page Then verify if "Common_Popup" popup dialog appears @@ -144,12 +147,16 @@ Feature: Projects Page Then "Description" component on "Common_Popup" should be equal "Descriptions"."Delete_Project_Confirm_Message" Then click on "Delete_Button" element on "Common_Popup" wizard And wait load page + And select "Archived" tab in "Projects_Tab_Selector" on "Projects" wizard + Then verify "Archived" tab is active in "Projects_Tab_Selector" on "Projects" wizard Then verify "Notification_Pop_Up" element visibility on "Notification_Popup" wizard Then "Notification_Pop_Up" element on "Notification_Popup" should contains "Project deletion in progress" value And wait load page Then verify "Notification_Pop_Up_Cross_Close_Button" element visibility on "Notification_Popup" wizard Then click on "Notification_Pop_Up_Cross_Close_Button" element on "Notification_Popup" wizard And wait load page + And select "Active" tab in "Projects_Tab_Selector" on "Projects" wizard + Then verify "Active" tab is active in "Projects_Tab_Selector" on "Projects" wizard Then verify if "Notification_Popup" popup dialog appears Then verify "Notification_Pop_Up" element visibility on "Notification_Popup" wizard Then "Notification_Pop_Up" element on "Notification_Popup" should contains "Project \"empty-project\" was deleted successfully" value @@ -160,6 +167,7 @@ Feature: Projects Page @MLPr @sanity @smoke + #TODO: update "Labels_Value" options rules Scenario: MLPr007 - Create new ML Project with description Given open url And wait load page @@ -172,10 +180,15 @@ Feature: Projects Page And click on "Add_Label_Button" element on "Create_New_Project" wizard Then type value "/" to "Labels_Key" field on "Create_New_Project" wizard Then verify labels warning should display options "Input_Hint"."Projects_Labels_Warning_Key" + Then type value "/" to "Labels_Value" field on "Create_New_Project" wizard + Then verify labels warning should display options "Input_Hint"."Projects_Labels_Warning_Value" Then verify "Labels_Key" options rules on "Create_New_Project" wizard with labels + And wait load page + Then type into "Description_Input" on "Create_New_Project" popup dialog "automation test description new" value Then type value "/" to "Labels_Value" field on "Create_New_Project" wizard Then verify labels warning should display options "Input_Hint"."Projects_Labels_Warning_Value" - Then verify "Labels_Value" options rules on "Create_New_Project" wizard with labels + # Then verify "Labels_Value" options rules on "Create_New_Project" wizard with labels + And wait load page Then type value "/" to "Labels_Key" field on "Create_New_Project" wizard Then type value "/" to "Labels_Value" field on "Create_New_Project" wizard When click on "Title" element on "Create_New_Project" wizard @@ -212,12 +225,16 @@ Feature: Projects Page Then select "Delete" option in action menu on "Projects" wizard in "Projects_Table" table at row with "automation-test-name2" value in "name" column Then verify if "Common_Popup" popup dialog appears Then click on "Delete_Button" element on "Common_Popup" wizard + And select "Archived" tab in "Projects_Tab_Selector" on "Projects" wizard + Then verify "Archived" tab is active in "Projects_Tab_Selector" on "Projects" wizard And wait load page Then verify "Notification_Pop_Up" element visibility on "Notification_Popup" wizard Then "Notification_Pop_Up" element on "Notification_Popup" should contains "Project deletion in progress" value Then verify "Notification_Pop_Up_Cross_Close_Button" element visibility on "Notification_Popup" wizard Then click on "Notification_Pop_Up_Cross_Close_Button" element on "Notification_Popup" wizard And wait load page + And select "Active" tab in "Projects_Tab_Selector" on "Projects" wizard + Then verify "Active" tab is active in "Projects_Tab_Selector" on "Projects" wizard And wait load page Then verify if "Notification_Popup" popup dialog appears Then verify "Notification_Pop_Up" element visibility on "Notification_Popup" wizard @@ -252,10 +269,14 @@ Feature: Projects Page Then check "automation-test-name7" value in "name" column in "Projects_Table" table on "Projects" wizard Then select "Unarchive" option in action menu on "Projects" wizard in "Projects_Table" table at row with "automation-test-name7" value in "name" column And wait load page + Then select "Unarchive" option in action menu on "Projects" wizard in "Projects_Table" table at row with "hedi-proj" value in "name" column And wait load page Then "No_Archived_Projects_Message" element on "Projects" should contains "No archived projects." value Then click on "Active_Projects_Button" element on "Projects" wizard Then check "automation-test-name7" value in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page + Then check "hedi-proj" value in "name" column in "Projects_Table" table on "Projects" wizard + And wait load page @MLPr @passive @@ -263,6 +284,7 @@ Feature: Projects Page Scenario: MLPr011 - Verify View YAML action Given open url And wait load page + When scroll to the element with "default" value in "name" column in "Projects_Table" table on "Projects" wizard Then select "View YAML" option in action menu on "Projects" wizard in "Projects_Table" table at row with "default" value in "name" column Then verify if "View_YAML" popup dialog appears Then verify "Cross_Cancel_Button" element visibility on "View_YAML" wizard @@ -299,17 +321,13 @@ Feature: Projects Page And click on row root with value "navigation-test" in "name" column in "Projects_Table" table on "Projects" wizard And wait load page And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard - And click on cell with value "Quick actions" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard - And hover "MLRun_Logo" component on "commonPagesHeader" wizard - And wait load page - Then verify value should equal "navigation-test" in "Header_Name_Label" on "Demo_Project" wizard - And hover "Project_Navigation_Toggler" component on "commonPagesHeader" wizard Then click on "Pin_Quick_Link_Button" element on "commonPagesHeader" wizard And click on cell with value "Project monitoring" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard And wait load page Then verify breadcrumbs "tab" label should be equal "Project monitoring" value And click on cell with value "Feature store" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard And wait load page + And wait load page Then verify breadcrumbs "tab" label should be equal "Feature store" value And click on cell with value "Datasets" in "link" column in "General_Info_Quick_Links" table on "commonPagesHeader" wizard And wait load page @@ -340,8 +358,10 @@ Feature: Projects Page Then verify "Monitoring_Container" element visibility in "Projects_Monitoring_Container" on "Projects" wizard Then verify "Monitoring_Container_Title" element visibility in "Projects_Monitoring_Container" on "Projects" wizard Then "Monitoring_Container_Title" element in "Projects_Monitoring_Container" on "Projects" should contains "Monitoring" value + Then verify "Monitoring_Artifacts_Box" element visibility in "Projects_Monitoring_Container" on "Projects" wizard Then verify "Monitoring_Jobs_Box" element visibility in "Projects_Monitoring_Container" on "Projects" wizard Then verify "Monitoring_Workflows_Box" element visibility in "Projects_Monitoring_Container" on "Projects" wizard + Then verify "Monitoring_Models_Box" element visibility in "Projects_Monitoring_Container" on "Projects" wizard Then verify "Monitoring_Scheduled_Box" element visibility in "Projects_Monitoring_Container" on "Projects" wizard Then verify "Monitoring_Alerts_Box" element visibility in "Projects_Monitoring_Container" on "Projects" wizard And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard @@ -351,8 +371,10 @@ Feature: Projects Page Then navigate back And wait load page Then verify "Monitoring_Container" element visibility in "Projects_Monitoring_Container" on "Projects" wizard + Then verify "Monitoring_Artifacts_Box" element visibility in "Projects_Monitoring_Container" on "Projects" wizard Then verify "Monitoring_Jobs_Box" element visibility in "Projects_Monitoring_Container" on "Projects" wizard Then verify "Monitoring_Workflows_Box" element visibility in "Projects_Monitoring_Container" on "Projects" wizard + Then verify "Monitoring_Models_Box" element visibility in "Projects_Monitoring_Container" on "Projects" wizard Then verify "Monitoring_Scheduled_Box" element visibility in "Projects_Monitoring_Container" on "Projects" wizard Then verify "Monitoring_Alerts_Box" element visibility in "Projects_Monitoring_Container" on "Projects" wizard And click on row root with value "default" in "name" column in "Projects_Table" table on "Projects" wizard @@ -361,11 +383,42 @@ Feature: Projects Page Then click on breadcrumbs "projectsPage" label on "commonPagesHeader" wizard And wait load page Then verify "Monitoring_Container" element visibility in "Projects_Monitoring_Container" on "Projects" wizard + Then verify "Monitoring_Artifacts_Box" element visibility in "Projects_Monitoring_Container" on "Projects" wizard Then verify "Monitoring_Jobs_Box" element visibility in "Projects_Monitoring_Container" on "Projects" wizard Then verify "Monitoring_Workflows_Box" element visibility in "Projects_Monitoring_Container" on "Projects" wizard + Then verify "Monitoring_Models_Box" element visibility in "Projects_Monitoring_Container" on "Projects" wizard Then verify "Monitoring_Scheduled_Box" element visibility in "Projects_Monitoring_Container" on "Projects" wizard Then verify "Monitoring_Alerts_Box" element visibility in "Projects_Monitoring_Container" on "Projects" wizard + @MLPr + @smoke + Scenario: MLPr022 - Check the components in the Artifacts and Models counter boxes + Given open url + And wait load page + Then verify "Monitoring_Container" element visibility in "Projects_Monitoring_Container" on "Projects" wizard + Then verify "Monitoring_Container_Title" element visibility in "Projects_Monitoring_Container" on "Projects" wizard + Then "Monitoring_Container_Title" element in "Projects_Monitoring_Container" on "Projects" should contains "Monitoring" value + Then verify "Monitoring_Artifacts_Box" element visibility in "Projects_Monitoring_Container" on "Projects" wizard + Then verify "Monitoring_Artifacts_Box_Title" element visibility in "Monitoring_Artifacts_Box" on "Projects" wizard + Then "Monitoring_Artifacts_Box_Title" element in "Monitoring_Artifacts_Box" on "Projects" should contains "Artifacts" value + Then verify "Total_Counter_Number" element visibility in "Monitoring_Artifacts_Box" on "Projects" wizard + Then verify "Counter_Datasets_Number" element visibility in "Monitoring_Artifacts_Box" on "Projects" wizard + Then verify "Counter_Datasets_Subtitle" element visibility in "Monitoring_Artifacts_Box" on "Projects" wizard + Then "Counter_Datasets_Subtitle" element in "Monitoring_Artifacts_Box" on "Projects" should contains "Datasets" value + Then verify "Counter_Documents_Number" element visibility in "Monitoring_Artifacts_Box" on "Projects" wizard + Then verify "Counter_Documents_Subtitle" element visibility in "Monitoring_Artifacts_Box" on "Projects" wizard + Then "Counter_Documents_Subtitle" element in "Monitoring_Artifacts_Box" on "Projects" should contains "Documents" value + Then verify "Counter_LLM_Prompt_Number" element visibility in "Monitoring_Artifacts_Box" on "Projects" wizard + Then verify "Counter_LLM_Prompt_Subtitle" element visibility in "Monitoring_Artifacts_Box" on "Projects" wizard + Then "Counter_LLM_Prompt_Subtitle" element in "Monitoring_Artifacts_Box" on "Projects" should contains "LLM prompt artifacts" value + Then verify "Counter_Other_Artifacts_Number" element visibility in "Monitoring_Artifacts_Box" on "Projects" wizard + Then verify "Counter_Other_Artifacts_Subtitle" element visibility in "Monitoring_Artifacts_Box" on "Projects" wizard + Then "Counter_Other_Artifacts_Subtitle" element in "Monitoring_Artifacts_Box" on "Projects" should contains "Other artifacts" value + Then verify "Monitoring_Models_Box" element visibility in "Projects_Monitoring_Container" on "Projects" wizard + Then verify "Monitoring_Models_Title" element visibility in "Monitoring_Models_Box" on "Projects" wizard + Then "Monitoring_Models_Title" element in "Monitoring_Models_Box" on "Projects" should contains "Models" value + Then verify "Total_Counter_Number" element visibility in "Monitoring_Models_Box" on "Projects" wizard + @MLPr @smoke Scenario: MLPr016 - Check components on Jobs counter box @@ -376,15 +429,15 @@ Feature: Projects Page Then "Monitoring_Container_Title" element in "Projects_Monitoring_Container" on "Projects" should contains "Monitoring" value Then verify "Monitoring_Jobs_Box" element visibility in "Projects_Monitoring_Container" on "Projects" wizard Then verify "Monitoring_Jobs_Box_Title" element visibility in "Monitoring_Jobs_Box" on "Projects" wizard - Then "Monitoring_Jobs_Box_Title" element in "Monitoring_Jobs_Box" on "Projects" should contains "Jobs" value + Then "Monitoring_Jobs_Box_Title" element in "Monitoring_Jobs_Box" on "Projects" should contains "Runs" value + Then verify "Monitoring_Jobs_Box_Title_Tip" element visibility in "Monitoring_Jobs_Box" on "Projects" wizard + Then verify "Monitoring_Jobs_Box_Title_Tip" element in "Monitoring_Jobs_Box" on "Projects" wizard should display hover hint "Common_Tooltips"."Monitoring_Jobs_Box_Title_Tip" Then verify "Filtering_Time_Period" element visibility in "Monitoring_Jobs_Box" on "Projects" wizard - Then "Filtering_Time_Period" element in "Monitoring_Jobs_Box" on "Projects" should contains "Past 24 hours" value - Then verify "Total_Counter_Title" element visibility in "Monitoring_Jobs_Box" on "Projects" wizard - Then "Total_Counter_Title" element in "Monitoring_Jobs_Box" on "Projects" should contains "Total" value + Then "Filtering_Time_Period" element in "Monitoring_Jobs_Box" on "Projects" should contains "Last 24 hrs" value Then verify "Total_Counter_Number" element visibility in "Monitoring_Jobs_Box" on "Projects" wizard Then verify "Counter_Running_Status_Number" element visibility in "Monitoring_Jobs_Box" on "Projects" wizard Then verify "Counter_Running_Status_Subtitle" element visibility in "Monitoring_Jobs_Box" on "Projects" wizard - Then "Counter_Running_Status_Subtitle" element in "Monitoring_Jobs_Box" on "Projects" should contains "In Process" value + Then "Counter_Running_Status_Subtitle" element in "Monitoring_Jobs_Box" on "Projects" should contains "In process" value Then verify "Counter_Running_Status_Icon" element visibility in "Monitoring_Jobs_Box" on "Projects" wizard Then verify "Counter_Running_Status_Icon" element in "Monitoring_Jobs_Box" on "Projects" wizard should display hover tooltip "Common_Tooltips"."In_Process_Jobs" Then verify "Counter_Failed_Status_Number" element visibility in "Monitoring_Jobs_Box" on "Projects" wizard @@ -396,30 +449,31 @@ Feature: Projects Page Then verify "Counter_Completed_Status_Subtitle" element visibility in "Monitoring_Jobs_Box" on "Projects" wizard Then "Counter_Completed_Status_Subtitle" element in "Monitoring_Jobs_Box" on "Projects" should contains "Succeeded" value Then verify "Counter_Completed_Status_Icon" element visibility in "Monitoring_Jobs_Box" on "Projects" wizard + Then verify "Counter_Running_Status_Icon" element in "Monitoring_Jobs_Box" on "Projects" wizard should display hover tooltip "Common_Tooltips"."In_Process_Jobs" Then verify "Counter_Completed_Status_Icon" element in "Monitoring_Jobs_Box" on "Projects" wizard should display hover tooltip "Common_Tooltips"."Succeeded" Then "Counter_Completed_Status_Number" element in "Monitoring_Jobs_Box" on "Projects" should contains "1" value When click on "Counter_Running_Status_Number" element in "Monitoring_Jobs_Box" on "Projects" wizard And wait load page - Then verify redirection to "projects/*/jobs-monitoring/jobs?state=running%2Cpending%2Caborting&dates=anyTime&bePage=1&fePage=1" + Then verify redirection to "projects/*/jobs-monitoring/jobs?state=running%2Cpending%2CpendingRetry%2Caborting&dates=anyTime&bePage=1&fePage=1" Then navigate back And wait load page When click on "Counter_Failed_Status_Number" element in "Monitoring_Jobs_Box" on "Projects" wizard And wait load page - Then verify redirection to "projects/*/jobs-monitoring/jobs?state=error%2Caborted&bePage=1&fePage=1" + Then verify redirection to "projects/*/jobs-monitoring/jobs?state=error%2Caborted&dates=past24hours&bePage=1&fePage=1" Then verify breadcrumbs "cross" label should be equal "Jobs monitoring" value Then verify breadcrumbs "projectsPage" label should be equal "Projects" value Then navigate back And wait load page When click on "Counter_Completed_Status_Number" element in "Monitoring_Jobs_Box" on "Projects" wizard And wait load page - Then verify redirection to "projects/*/jobs-monitoring/jobs?state=completed&bePage=1&fePage=1" + Then verify redirection to "projects/*/jobs-monitoring/jobs?state=completed&dates=past24hours&bePage=1&fePage=1" Then verify breadcrumbs "cross" label should be equal "Jobs monitoring" value Then verify breadcrumbs "projectsPage" label should be equal "Projects" value Then navigate back And wait load page When click on "Total_Counter_Number" element in "Monitoring_Jobs_Box" on "Projects" wizard And wait load page - Then verify redirection to "projects/*/jobs-monitoring/jobs?state=all&bePage=1&fePage=1" + Then verify redirection to "projects/*/jobs-monitoring/jobs?state=all&dates=past24hours&bePage=1&fePage=1" Then verify breadcrumbs "cross" label should be equal "Jobs monitoring" value Then verify breadcrumbs "projectsPage" label should be equal "Projects" value Then navigate back @@ -438,15 +492,13 @@ Feature: Projects Page Then verify "Monitoring_Workflows_Box_Title" element visibility in "Monitoring_Workflows_Box" on "Projects" wizard Then "Monitoring_Workflows_Box_Title" element in "Monitoring_Workflows_Box" on "Projects" should contains "Workflows" value Then verify "Filtering_Time_Period" element visibility in "Monitoring_Workflows_Box" on "Projects" wizard - Then "Filtering_Time_Period" element in "Monitoring_Workflows_Box" on "Projects" should contains "Past 24 hours" value - Then verify "Total_Counter_Title" element visibility in "Monitoring_Workflows_Box" on "Projects" wizard - Then "Total_Counter_Title" element in "Monitoring_Workflows_Box" on "Projects" should contains "Total" value + Then "Filtering_Time_Period" element in "Monitoring_Workflows_Box" on "Projects" should contains "Last 24 hrs" value Then verify "Total_Counter_Number" element visibility in "Monitoring_Workflows_Box" on "Projects" wizard - Then verify "Counter_Running_Status_Number" element visibility in "Monitoring_Workflows_Box" on "Projects" wizard - Then verify "Counter_Running_Status_Subtitle" element visibility in "Monitoring_Workflows_Box" on "Projects" wizard - Then "Counter_Running_Status_Subtitle" element in "Monitoring_Workflows_Box" on "Projects" should contains "In Process" value - Then verify "Counter_Running_Status_Icon" element visibility in "Monitoring_Workflows_Box" on "Projects" wizard - Then verify "Counter_Running_Status_Icon" element in "Monitoring_Workflows_Box" on "Projects" wizard should display hover tooltip "Common_Tooltips"."In_Process_Workflows" + Then verify "Counter_In_Process_Status_Number" element visibility in "Monitoring_Workflows_Box" on "Projects" wizard + Then verify "Counter_In_Process_Status_Subtitle" element visibility in "Monitoring_Workflows_Box" on "Projects" wizard + Then "Counter_In_Process_Status_Subtitle" element in "Monitoring_Workflows_Box" on "Projects" should contains "In process" value + Then verify "Counter_In_Process_Status_Icon" element visibility in "Monitoring_Workflows_Box" on "Projects" wizard + Then verify "Counter_In_Process_Status_Icon" element in "Monitoring_Workflows_Box" on "Projects" wizard should display hover tooltip "Common_Tooltips"."Running_Tip" Then verify "Counter_Failed_Status_Number" element visibility in "Monitoring_Workflows_Box" on "Projects" wizard Then verify "Counter_Failed_Status_Subtitle" element visibility in "Monitoring_Workflows_Box" on "Projects" wizard Then "Counter_Failed_Status_Subtitle" element in "Monitoring_Workflows_Box" on "Projects" should contains "Failed" value @@ -456,30 +508,31 @@ Feature: Projects Page Then verify "Counter_Completed_Status_Subtitle" element visibility in "Monitoring_Workflows_Box" on "Projects" wizard Then "Counter_Completed_Status_Subtitle" element in "Monitoring_Workflows_Box" on "Projects" should contains "Succeeded" value Then verify "Counter_Completed_Status_Icon" element visibility in "Monitoring_Workflows_Box" on "Projects" wizard + Then verify "Counter_In_Process_Status_Icon" element in "Monitoring_Workflows_Box" on "Projects" wizard should display hover tooltip "Common_Tooltips"."Running_Tip" Then verify "Counter_Completed_Status_Icon" element in "Monitoring_Workflows_Box" on "Projects" wizard should display hover tooltip "Common_Tooltips"."Succeeded" - When click on "Counter_Running_Status_Number" element in "Monitoring_Workflows_Box" on "Projects" wizard + When click on "Counter_In_Process_Status_Number" element in "Monitoring_Workflows_Box" on "Projects" wizard And wait load page - Then verify redirection to "projects/*/jobs-monitoring/workflows?state=running&dates=anyTime" + Then verify redirection to "projects/*/jobs-monitoring/workflows?state=running%2Cterminating&dates=anyTime" Then verify breadcrumbs "cross" label should be equal "Jobs monitoring" value Then verify breadcrumbs "projectsPage" label should be equal "Projects" value Then navigate back And wait load page When click on "Counter_Failed_Status_Number" element in "Monitoring_Workflows_Box" on "Projects" wizard And wait load page - Then verify redirection to "projects/*/jobs-monitoring/workflows?state=error%2Cfailed" + Then verify redirection to "projects/*/jobs-monitoring/workflows?state=error%2Cfailed&dates=past24hours" Then verify breadcrumbs "cross" label should be equal "Jobs monitoring" value Then verify breadcrumbs "projectsPage" label should be equal "Projects" value Then navigate back And wait load page When click on "Counter_Completed_Status_Number" element in "Monitoring_Workflows_Box" on "Projects" wizard And wait load page - Then verify redirection to "projects/*/jobs-monitoring/workflows?state=completed" + Then verify redirection to "projects/*/jobs-monitoring/workflows?state=completed&dates=past24hours" Then verify breadcrumbs "cross" label should be equal "Jobs monitoring" value Then verify breadcrumbs "projectsPage" label should be equal "Projects" value Then navigate back And wait load page When click on "Total_Counter_Number" element in "Monitoring_Workflows_Box" on "Projects" wizard - Then verify redirection to "projects/*/jobs-monitoring/workflows?state=all" + Then verify redirection to "projects/*/jobs-monitoring/workflows?state=all&dates=past24hours" Then verify breadcrumbs "cross" label should be equal "Jobs monitoring" value Then verify breadcrumbs "projectsPage" label should be equal "Projects" value Then navigate back @@ -498,32 +551,31 @@ Feature: Projects Page Then verify "Monitoring_Scheduled_Box_Title" element visibility in "Monitoring_Scheduled_Box" on "Projects" wizard Then "Monitoring_Scheduled_Box_Title" element in "Monitoring_Scheduled_Box" on "Projects" should contains "Scheduled" value Then verify "Filtering_Time_Period" element visibility in "Monitoring_Scheduled_Box" on "Projects" wizard - Then "Filtering_Time_Period" element in "Monitoring_Scheduled_Box" on "Projects" should contains "Next 24 hours" value + Then "Filtering_Time_Period" element in "Monitoring_Scheduled_Box" on "Projects" should contains "Next 24 hrs" value Then verify "Total_Job_Counter_Title" element visibility in "Monitoring_Scheduled_Box" on "Projects" wizard Then "Total_Job_Counter_Title" element in "Monitoring_Scheduled_Box" on "Projects" should contains "Jobs" value Then verify "Total_Workflows_Counter_Title" element visibility in "Monitoring_Scheduled_Box" on "Projects" wizard Then "Total_Workflows_Counter_Title" element in "Monitoring_Scheduled_Box" on "Projects" should contains "Workflows" value Then verify "Total_Job_Counter_Number" element visibility in "Monitoring_Scheduled_Box" on "Projects" wizard Then verify "Total_Workflows_Counter_Number" element visibility in "Monitoring_Scheduled_Box" on "Projects" wizard - Then verify "Total_Scheduled_Title" element visibility in "Monitoring_Scheduled_Box" on "Projects" wizard - Then "Total_Scheduled_Title" element in "Monitoring_Scheduled_Box" on "Projects" should contains "Total" value Then verify "Total_Scheduled_Number" element visibility in "Monitoring_Scheduled_Box" on "Projects" wizard When click on "Total_Scheduled_Number" element in "Monitoring_Scheduled_Box" on "Projects" wizard - Then verify redirection to "projects/*/jobs-monitoring/scheduled?type=all" + And wait load page + Then verify redirection to "projects/*/jobs-monitoring/scheduled?type=all&dates=next24hours" Then verify breadcrumbs "cross" label should be equal "Jobs monitoring" value Then verify breadcrumbs "projectsPage" label should be equal "Projects" value And wait load page Then navigate back And wait load page When click on "Total_Workflows_Counter_Number" element in "Monitoring_Scheduled_Box" on "Projects" wizard - Then verify redirection to "projects/*/jobs-monitoring/scheduled?type=workflow" + Then verify redirection to "projects/*/jobs-monitoring/scheduled?type=workflow&dates=next24hours" Then verify breadcrumbs "cross" label should be equal "Jobs monitoring" value Then verify breadcrumbs "projectsPage" label should be equal "Projects" value And wait load page Then navigate back And wait load page When click on "Total_Job_Counter_Number" element in "Monitoring_Scheduled_Box" on "Projects" wizard - Then verify redirection to "projects/*/jobs-monitoring/scheduled?type=job" + Then verify redirection to "projects/*/jobs-monitoring/scheduled?type=job%2Cspark%2Cmpijob%2Cdask%2Cdatabricks&dates=next24hours" Then verify breadcrumbs "cross" label should be equal "Jobs monitoring" value Then verify breadcrumbs "projectsPage" label should be equal "Projects" value And wait load page @@ -544,7 +596,7 @@ Feature: Projects Page Then "Monitoring_Alerts_Box_Title" element in "Monitoring_Alerts_Box" on "Projects" should contains "Alerts" value Then verify "Monitoring_Alerts_Box_Title_Icon" element visibility in "Monitoring_Alerts_Box" on "Projects" wizard Then verify "Filtering_Time_Period" element visibility in "Monitoring_Alerts_Box" on "Projects" wizard - Then "Filtering_Time_Period" element in "Monitoring_Alerts_Box" on "Projects" should contains "Past 24 hours" value + Then "Filtering_Time_Period" element in "Monitoring_Alerts_Box" on "Projects" should contains "Last 24 hrs" value Then verify "Total_Endpoint_Counter_Title" element visibility in "Monitoring_Alerts_Box" on "Projects" wizard Then "Total_Endpoint_Counter_Title" element in "Monitoring_Alerts_Box" on "Projects" should contains "Endpoint" value Then verify "Total_Endpoint_Counter_Number" element visibility in "Monitoring_Alerts_Box" on "Projects" wizard @@ -554,11 +606,10 @@ Feature: Projects Page Then verify "Total_Application_Counter_Title" element visibility in "Monitoring_Alerts_Box" on "Projects" wizard Then "Total_Application_Counter_Title" element in "Monitoring_Alerts_Box" on "Projects" should contains "Application" value Then verify "Total_Application_Counter_Number" element visibility in "Monitoring_Alerts_Box" on "Projects" wizard - Then verify "Total_Alerts_Title" element visibility in "Monitoring_Alerts_Box" on "Projects" wizard - Then "Total_Alerts_Title" element in "Monitoring_Alerts_Box" on "Projects" should contains "Total" value Then verify "Total_Alerts_Number" element visibility in "Monitoring_Alerts_Box" on "Projects" wizard Then "Total_Alerts_Number" element in "Monitoring_Alerts_Box" on "Projects" should contains "39" value When click on "Total_Alerts_Number" element in "Monitoring_Alerts_Box" on "Projects" wizard + And wait load page Then verify redirection to "projects/*/alerts-monitoring?bePage=1&fePage=1" Then verify breadcrumbs "cross" label should be equal "Alerts monitoring" value Then verify breadcrumbs "projectsPage" label should be equal "Projects" value @@ -596,8 +647,18 @@ Feature: Projects Page Then verify "Monitoring_Container" element visibility in "Projects_Monitoring_Container" on "Projects" wizard Then verify "Monitoring_Container_Title" element visibility in "Projects_Monitoring_Container" on "Projects" wizard Then "Monitoring_Container_Title" element in "Projects_Monitoring_Container" on "Projects" should contains "Monitoring" value + Then verify "Monitoring_Artifacts_Box" element visibility in "Projects_Monitoring_Container" on "Projects" wizard + Then "Total_Counter_Number" element in "Monitoring_Artifacts_Box" on "Projects" should contains "13,145" value + Then verify "Counter_Datasets_Number" element visibility in "Monitoring_Artifacts_Box" on "Projects" wizard + Then "Counter_Datasets_Number" element in "Monitoring_Artifacts_Box" on "Projects" should contains "34" value + Then verify "Counter_Documents_Number" element visibility in "Monitoring_Artifacts_Box" on "Projects" wizard + Then "Counter_Documents_Number" element in "Monitoring_Artifacts_Box" on "Projects" should contains "23" value + Then verify "Counter_LLM_Prompt_Number" element visibility in "Monitoring_Artifacts_Box" on "Projects" wizard + Then "Counter_LLM_Prompt_Number" element in "Monitoring_Artifacts_Box" on "Projects" should contains "58" value + Then verify "Counter_Other_Artifacts_Number" element visibility in "Monitoring_Artifacts_Box" on "Projects" wizard + Then "Counter_Other_Artifacts_Number" element in "Monitoring_Artifacts_Box" on "Projects" should contains "13,030" value Then verify "Monitoring_Jobs_Box_Title" element visibility in "Monitoring_Jobs_Box" on "Projects" wizard - Then "Monitoring_Jobs_Box_Title" element in "Monitoring_Jobs_Box" on "Projects" should contains "Jobs" value + Then "Monitoring_Jobs_Box_Title" element in "Monitoring_Jobs_Box" on "Projects" should contains "Runs" value Then verify "Total_Counter_Number" element visibility in "Monitoring_Jobs_Box" on "Projects" wizard Then verify "Counter_Running_Status_Number" element visibility in "Monitoring_Jobs_Box" on "Projects" wizard Then verify "Counter_Failed_Status_Number" element visibility in "Monitoring_Jobs_Box" on "Projects" wizard @@ -607,9 +668,9 @@ Feature: Projects Page Then verify "Monitoring_Workflows_Box_Title" element visibility in "Monitoring_Workflows_Box" on "Projects" wizard Then "Monitoring_Workflows_Box_Title" element in "Monitoring_Workflows_Box" on "Projects" should contains "Workflows" value Then verify "Total_Counter_Number" element visibility in "Monitoring_Workflows_Box" on "Projects" wizard - Then "Total_Counter_Number" element in "Monitoring_Workflows_Box" on "Projects" should contains "3" value - Then verify "Counter_Running_Status_Number" element visibility in "Monitoring_Workflows_Box" on "Projects" wizard - Then "Counter_Running_Status_Number" element in "Monitoring_Workflows_Box" on "Projects" should contains "0" value + Then "Total_Counter_Number" element in "Monitoring_Workflows_Box" on "Projects" should contains "4" value + Then verify "Counter_In_Process_Status_Number" element visibility in "Monitoring_Workflows_Box" on "Projects" wizard + Then "Counter_In_Process_Status_Number" element in "Monitoring_Workflows_Box" on "Projects" should contains "1" value Then verify "Counter_Failed_Status_Number" element visibility in "Monitoring_Workflows_Box" on "Projects" wizard Then "Counter_Failed_Status_Number" element in "Monitoring_Workflows_Box" on "Projects" should contains "1" value Then verify "Counter_Completed_Status_Number" element visibility in "Monitoring_Workflows_Box" on "Projects" wizard @@ -623,6 +684,9 @@ Feature: Projects Page Then "Total_Workflows_Counter_Number" element in "Monitoring_Scheduled_Box" on "Projects" should contains "1" value Then verify "Total_Scheduled_Number" element visibility in "Monitoring_Scheduled_Box" on "Projects" wizard Then "Total_Scheduled_Number" element in "Monitoring_Scheduled_Box" on "Projects" should contains "8" value + Then verify "Monitoring_Models_Box" element visibility in "Projects_Monitoring_Container" on "Projects" wizard + Then verify "Monitoring_Models_Title" element visibility in "Monitoring_Models_Box" on "Projects" wizard + Then "Total_Counter_Number" element in "Monitoring_Models_Box" on "Projects" should contains "13,019" value Then verify "Monitoring_Alerts_Box" element visibility in "Projects_Monitoring_Container" on "Projects" wizard Then verify "Monitoring_Alerts_Box_Title" element visibility in "Monitoring_Alerts_Box" on "Projects" wizard Then "Monitoring_Alerts_Box_Title" element in "Monitoring_Alerts_Box" on "Projects" should contains "Alerts" value diff --git a/tests/features/quickActions.feature b/tests/features/quickActions.feature index 3ec06b0022..dffc53b5d6 100644 --- a/tests/features/quickActions.feature +++ b/tests/features/quickActions.feature @@ -3,7 +3,6 @@ Feature: Quick actions Page Testcases that verifies functionality on MLRun Quick actions Page @MLPH - @smoke Scenario: MLPH001 - Check all mandatory components on Project Home * set tear-down property "project" created with "automation-test-1002" value * create "automation-test-1002" MLRun Project with code 201 @@ -84,7 +83,6 @@ Feature: Quick actions Page | Monitoring | @MLPH - @smoke Scenario: MLPH002 - Verify behaviour on Register Model Popup on Project Home Page Given open url And wait load page @@ -139,7 +137,6 @@ Feature: Quick actions Page Then check "v3io:///target/" value in "path" column in "Overview_Table" table on "Models_Info_Pane" wizard @MLPH - @smoke @passive Scenario: MLPH003 - Check all mandatory components on Create New Feature Set on Project Home Page Given open url @@ -191,7 +188,6 @@ Feature: Quick actions Page @MLPH @passive - @smoke Scenario: MLPH004 - Check all mandatory components on Register Dataset Popup on Project Home Page Given open url And wait load page @@ -250,7 +246,6 @@ Feature: Quick actions Page @MLPH @passive - @smoke Scenario: MLPH005 - Check all mandatory components on Create ML Function on Project Home Page * set tear-down property "project" created with "automation-test-1003" value * create "automation-test-1003" MLRun Project with code 201 @@ -285,7 +280,6 @@ Feature: Quick actions Page @MLPH @passive - @smoke Scenario: MLPH006 - Check all mandatory components on Batch run wizard Given open url And wait load page @@ -452,7 +446,6 @@ Feature: Quick actions Page @MLPH @passive - @smoke Scenario: MLPH008 - Check all mandatory components on Create a Feature Vector Popup on Project Home Page Given open url And wait load page @@ -477,7 +470,6 @@ Feature: Quick actions Page @MLPH @passive - @smoke Scenario: MLPH009 - Check all mandatory components on Feature Set tab on Project Home Page Given open url And wait load page @@ -520,7 +512,6 @@ Feature: Quick actions Page @MLPH @passive - @smoke Scenario: MLPH010 - Check all mandatory components on Files tab on Project Home Page Given open url And wait load page @@ -547,7 +538,6 @@ Feature: Quick actions Page @MLPH @passive - @smoke Scenario: MLPH011 - Check all mandatory components on Datasets tab on Project Home Page Given open url And wait load page @@ -573,7 +563,6 @@ Feature: Quick actions Page @MLPH @passive - @smoke Scenario: MLPH012 - Check all mandatory components on Feature Vectors tab on Project Home Page Given open url And wait load page @@ -603,7 +592,6 @@ Feature: Quick actions Page @MLPH @passive - @smoke Scenario: MLPH013 - Check all mandatory components on ML Functions tab on Project Home Page Given open url And wait load page @@ -639,7 +627,6 @@ Feature: Quick actions Page @MLPH @passive - @smoke Scenario: MLPH014 - Check all mandatory components on Monitor Jobs tab on Project Home Page Given open url And wait load page @@ -681,7 +668,6 @@ Feature: Quick actions Page @MLPH @passive - @smoke Scenario: MLPH015 - Check all mandatory components on Models tab on Project Home Page Given open url And wait load page @@ -712,7 +698,6 @@ Feature: Quick actions Page @MLPH @passive - @smoke Scenario: MLPH016 - Check all mandatory components on Monitor Workflows tab on Project Home Page Given open url And wait load page @@ -735,7 +720,6 @@ Feature: Quick actions Page @MLPH @passive - @smoke Scenario: MLPH017 - Check all mandatory components on Models Endpoint tab on Project Home Page Given open url And wait load page @@ -772,7 +756,6 @@ Feature: Quick actions Page @MLPH @passive - @smoke Scenario: MLPH018 - Check all mandatory components on Real-Time Piplines tab on Project Home Page Given open url And wait load page @@ -793,7 +776,6 @@ Feature: Quick actions Page @MLPH @passive - @smoke Scenario: MLPH019 - Check all mandatory components on Monitoring tab on Project Home Page Given open url And wait load page @@ -819,7 +801,6 @@ Feature: Quick actions Page Then verify "General_Info_Quick_Links" element visibility on "commonPagesHeader" wizard @MLPH - @smoke Scenario: MLPH020 - Check all mandatory components on Batch inference in Advanced section Given open url And wait load page @@ -934,7 +915,6 @@ Feature: Quick actions Page @MLPH @inProgress - @smoke Scenario: MLPH023 - Check components - batch inference_v2, preview text, path type Given open url And wait load page @@ -961,7 +941,6 @@ Feature: Quick actions Page #TODO: check Data Inputs path type (Data_Inputs_Inference_Table) @MLPH - @smoke Scenario: MLPH024 - Check Train model wizard opens up Given open url And wait load page diff --git a/tests/features/step-definitions/steps.js b/tests/features/step-definitions/steps.js index fd47318b1d..8acef5ff23 100644 --- a/tests/features/step-definitions/steps.js +++ b/tests/features/step-definitions/steps.js @@ -50,6 +50,7 @@ import { generatePath, determineFileAccess, verifyClassDisabled, + verifyClassEnabled, checkComponentHintTextWithHover, putToTestContextElementValue } from '../common/actions/common.action' @@ -144,10 +145,10 @@ When('turn on demo mode with query params {string}', async function(state) { await navigateToPage(this.driver, `${url}${state === 'true' ? '&' : '?'}mode=demo`) }) -When('turn on staging mode', async function() { +When('turn on staging mode with query params {string}', async function(state) { const url = await this.driver.getCurrentUrl() - await navigateToPage(this.driver, `${url}?mode=staging`) + await navigateToPage(this.driver, `${url}${state === 'true' ? '&' : '?'}mode=staging`) }) Then('turn Off MLRun CE mode', async function() { @@ -422,6 +423,16 @@ Then( } ) +Then( + 'verify {string} element on {string} wizard is enabled by class name', + async function(inputField, wizardName) { + await verifyClassEnabled( + this.driver, + pageObjects[wizardName][inputField] + ) + } +) + When( 'type searchable fragment {string} into {string} on {string} wizard', async function(subName, inputGroup, wizard) { @@ -821,14 +832,14 @@ When( pageObjects[wizardName][dropdownName], optionValue ) - await this.driver.sleep(200) + await this.driver.sleep(1000) await pickUpCustomDatetimeRange( this.driver, pageObjects[wizardName][datetimePicker], fromDatetime, toDatetime ) - await this.driver.sleep(200) + await this.driver.sleep(2500) await applyDatetimePickerRange( this.driver, pageObjects[wizardName][datetimePicker] @@ -891,6 +902,14 @@ Then( } ) +Then( + 'verify visibility of header column {string} in {string} table on {string} wizard', + async function (columnName, tableName, wizardName) { + const locator = pageObjects[wizardName][tableName]['headerSorters'][columnName] + await componentIsVisible(this.driver, locator) + } +) + Then('verify {string} element visibility on {string} wizard', async function( component, wizard @@ -1111,6 +1130,18 @@ Then( } ) +Then( + 'verify {string} element in {string} on {string} wizard should display hover hint {string}.{string}', + async function(inputField, accordion, wizard, constStorage, constValue) { + await checkComponentHintTextWithHover( + this.driver, + pageObjects[wizard][accordion][inputField], + pageObjects['commonPagesHeader']['Common_Hint'], + pageObjectsConsts[constStorage][constValue] + ) + } +) + Then( 'verify {string} on {string} wizard should display {string}.{string} in {string}', async function(inputField, wizard, constStorage, constValue, commonTipType) { diff --git a/tests/features/step-definitions/table.steps.js b/tests/features/step-definitions/table.steps.js index 3c815e38a6..e876497c58 100644 --- a/tests/features/step-definitions/table.steps.js +++ b/tests/features/step-definitions/table.steps.js @@ -52,6 +52,7 @@ import { isContainsSubstringInColumnDropdownCellsOverlay, isContainsSubstringInColumnTooltipCells, isContainsValueInColumn, + isContainsValueInHeaderColumn, isDatetimeCelsValueInRange, isNotContainsValueInColumn, putToTestContextCellParameters @@ -82,6 +83,15 @@ Then( } ) +Then( + 'check {string} header value in {string} column in {string} table on {string} wizard', + async function (value, column, table, wizard) { + await waitPageLoad(this.driver, pageObjects['commonPagesHeader']['loader']) + + await isContainsValueInHeaderColumn(this.driver, pageObjects[wizard][table], column, value) + } +) + Then( 'check {string} value not in {string} column in {string} table on {string} wizard', async function (value, column, table, wizard) { @@ -90,6 +100,14 @@ Then( } ) +When( + 'scroll to the {string} element on {string} wizard', + async function (component, wizard) { + await waiteUntilComponent(this.driver, pageObjects[wizard][component]) + await scrollToElement(this.driver, pageObjects[wizard][component]) + } +) + When( 'scroll to the element with {string} value in {string} column in {string} table on {string} wizard', async function (value, columnName, table, wizard) { @@ -1063,6 +1081,34 @@ When( } ) +When( + 'click on data {string} in {string} table in {string} on {string} wizard', + async function (field, tableName, accordion, wizardName, dataTable) { + const column = dataTable['rawTable'][0][0] + const rows = dataTable.rows() + + for (const row_indx in rows) { + const arr = await findRowIndexesByColumnValue( + this.driver, + pageObjects[wizardName][accordion][tableName], + column, + rows[row_indx][0] + ) + const indx = arr[0] - pageObjects[wizardName][accordion][tableName].offset + + await hoverComponent( + this.driver, + pageObjects[wizardName][accordion][tableName]['tableFields'][field](indx + 1), + false + ) + await clickOnComponent( + this.driver, + pageObjects[wizardName][accordion][tableName]['tableFields'][field](indx + 1) + ) + } + } +) + When( 'click on data {string} in {string} table on {string} wizard', async function (field, tableName, wizardName, dataTable) { @@ -2017,7 +2063,7 @@ When( this.driver, pageObjects[wizardName][graphName].nodesTable.tableFields['name'](index) ) - await this.driver.sleep(250) + await this.driver.sleep(350) await isComponentContainsClass( this.driver, pageObjects[wizardName][graphName].nodesTable.rowRoot(index), @@ -2026,6 +2072,19 @@ When( } ) +When( + 'click on node with index {int} in {string} column in {string} graph on {string} wizard', + async function (index, column, graphName, wizard) { + await clickOnComponent(this.driver, pageObjects[wizard][graphName].nodesTable.tableFields[column](index)) + await this.driver.sleep(250) + await isComponentContainsClass( + this.driver, + pageObjects[wizard][graphName].nodesTable.rowRoot(index), + 'selected' + ) + } +) + When( 'save to context {string} column and {string} attribute on {int} row from {string} table on {string} wizard', async function (columnName, attributeName, rowIndex, tableName, wizardName) { diff --git a/tests/features/support/world.js b/tests/features/support/world.js index 75a0fbad11..af6f2827db 100644 --- a/tests/features/support/world.js +++ b/tests/features/support/world.js @@ -23,8 +23,8 @@ import firefox from 'selenium-webdriver/firefox' import { setWorldConstructor, setDefaultTimeout } from '@cucumber/cucumber' import { timeout, browser, headless, screen_size } from '../../config' -require('chromedriver') -require('geckodriver') +import 'chromedriver' +import 'geckodriver' class World { constructor({ attach, log, parameters }) { diff --git a/tests/mockServer/data/alerts.json b/tests/mockServer/data/alerts.json index c59b57c0c8..463e99522f 100644 --- a/tests/mockServer/data/alerts.json +++ b/tests/mockServer/data/alerts.json @@ -55,10 +55,10 @@ { "id": 10, "name": "mm-app-failure", - "project": "kate-project-mm", + "project": "default", "severity": "medium", "activation_time": "2024-12-17T09:52:19.580000+00:00", - "entity_id": "kate-project-mm_myApp", + "entity_id": "default-mm_myApp", "entity_kind": "model-monitoring-application", "criteria": { "count": 1, @@ -317,7 +317,7 @@ "name": "alert-name-uqbxb-proj-default", "project": "default", "severity": "high", - "activation_time": "2025-05-31T15:50:55.190000+00:00", + "activation_time": "2025-10-22T15:50:55.190000+00:00", "entity_id": "a7c95783e6a726a1a233e581ea898ba33fa7e342.rujmfi.result.data_drift_test", "entity_kind": "model-endpoint-result", "criteria": { @@ -343,7 +343,7 @@ "name": "alert-name-jukmn-proj-default", "project": "default", "severity": "high", - "activation_time": "2025-05-31T15:50:54.207000+00:00", + "activation_time": "2025-10-22T15:50:54.207000+00:00", "entity_id": "a7c95783e6a726a1a233e581ea898ba33fa7e342.hskoyl.result.data_drift_test", "entity_kind": "model-endpoint-result", "criteria": { @@ -369,7 +369,7 @@ "name": "alert-name-uqbxb-proj-default", "project": "default", "severity": "high", - "activation_time": "2025-05-31T15:48:57.907000+00:00", + "activation_time": "2025-10-22T15:48:57.907000+00:00", "entity_id": "a7c95783e6a726a1a233e581ea898ba33fa7e342.rujmfi.result.data_drift_test", "entity_kind": "model-endpoint-result", "criteria": { @@ -395,7 +395,7 @@ "name": "alert-name-jukmn-proj-default", "project": "default", "severity": "high", - "activation_time": "2025-05-31T15:48:56.440000+00:00", + "activation_time": "2025-10-22T15:48:56.440000+00:00", "entity_id": "a7c95783e6a726a1a233e581ea898ba33fa7e342.hskoyl.result.data_drift_test", "entity_kind": "model-endpoint-result", "criteria": { @@ -415,6 +415,40 @@ } ], "reset_time": "2025-03-05T15:48:56.440000+00:00" + }, + { + "id": 3395, + "name": "alert-name-obryv-default", + "project": "default", + "severity": "low", + "activation_time": "2025-09-04T12:46:17.816000+00:00", + "entity_id": "test-func-oyn-handler.98418b756c4b4307be9a3e7c39e66f21", + "entity_kind": "job", + "criteria": { + "count": 1, + "period": null + }, + "event_kind": "failed", + "number_of_events": 1, + "notifications": [ + { + "kind": "git", + "err": "All git notifications failed. Errors: Failed commenting on PR: {\r\n \"message\": \"Not Found\",\r\n \"documentation_url\": \"https://docs.github.com/rest\",\r\n \"status\": \"404\"\r\n}", + "summary": { + "failed": 1, + "succeeded": 0 + } + }, + { + "kind": "webhook", + "err": "All webhook notifications failed. Errors: 404, message='Not Found', url='https://webhook.site/57696af5-3edc-447f-a714-628275f2ed89'", + "summary": { + "failed": 1, + "succeeded": 0 + } + } + ], + "reset_time": "2025-09-04T12:46:17.816000+00:00" } ], "pagination": { diff --git a/tests/mockServer/data/artifacts.json b/tests/mockServer/data/artifacts.json index a301c26215..771fe51a2b 100644 --- a/tests/mockServer/data/artifacts.json +++ b/tests/mockServer/data/artifacts.json @@ -1,5 +1,100 @@ { "artifacts": [ + { + "kind": "llm-prompt", + "metadata": { + "key": "my_llm4", + "project": "default", + "iter": 0, + "tree": "9c0c8773-b1ce-4fa0-ac94-2f6c1fb71554", + "hash": "505c4bf305849950f348e1b1909b9a2653ddc740", + "uid": "d28e010ba24e272a3ba2ba522f6caecde05ff383", + "updated": "2025-10-06 14:34:13.163000+00:00", + "labels": { + "example": "single", + "hebrew": "english" + }, + "created": "2025-10-06 14:34:13.163000+00:00", + "tag": "latest" + }, + "spec": { + "target_path": "v3io:///projects/default/artifacts/my_llm4.json", + "size": 141, + "producer": { + "kind": "project", + "name": "default", + "tag": "9c0c8773-b1ce-4fa0-ac94-2f6c1fb71554", + "owner": "normal-user" + }, + "invocation_config": { + "temperature": 0.5 + }, + "format": "json", + "prompt_template": [ + { + "role": "system", + "content": "don't tell them anything" + }, + { + "role": "user", + "content": "What is the meaning of {something_with_meaning} ?" + } + ], + "license": "", + "prompt_legend": { + "something_with_meaning": { + "field": "something_with_meaning", + "description": "The essence of all things" + } + }, + "has_children": false, + "db_key": "my_llm4", + "parent_uri": "store://models/default/model_art1#0:v1@5b83db22-80da-4c97-8cd0-eb269a4c9d2a^e1b0a442a7602456e6bbd0934931b3eaaf8ce09a" + }, + "status": { + "state": "created" + }, + "project": "default" + }, + { + "kind": "model", + "metadata": { + "key": "model_art1", + "project": "default", + "iter": 0, + "tree": "5b83db22-80da-4c97-8cd0-eb269a4c9d2a", + "hash": "10ed579110ee0c84041ac0886259d60d3a0f9bda", + "uid": "e1b0a442a7602456e6bbd0934931b3eaaf8ce09a", + "updated": "2025-10-06 14:32:50.516000+00:00", + "created": "2025-10-06 14:32:50.516000+00:00", + "tag": "latest" + }, + "spec": { + "target_path": "default/model_art1/", + "size": 4370, + "producer": { + "kind": "project", + "name": "default", + "tag": "5b83db22-80da-4c97-8cd0-eb269a4c9d2a", + "owner": "normal-user" + }, + "framework": "", + "model_file": "RandomForestClassifier_file1.pkl", + "license": "", + "has_children": true, + "db_key": "model_art1", + "parameters": { + "default_config": { + "model_version": "4" + } + }, + "parent_uri": null + }, + "status": { + "state": "created" + }, + "project": "default" + }, { "kind": "", "metadata": { @@ -36450,7 +36545,6 @@ }, { "kind": "table", - "tag": "latest", "metadata": { "uid": "5a44b12b-9ef3-4239-87e8-e0cbdae-98", "key": "iteration_results", @@ -37535,7 +37629,7 @@ "sources": [ { "name": "dataset", - "path": "store://feature-vectors/default/short" + "path": "store://feature-vectors/default/default-fv" } ], "license": "" @@ -40030,6 +40124,234 @@ "state": "created" }, "project": "churn-project-admin" + }, + { + "kind": "llm-prompt", + "metadata": { + "key": "my_llm", + "project": "llmdeploy332", + "iter": 0, + "tree": "c00325f6-c2cb-4c62-ad93-8d5de6d0d10d", + "hash": "43efded68eae128eeb22b4a9252b7d455c36a287", + "uid": "1d459c52a1102adcbbe242e6bb36e99129f2a8b9", + "updated": "2025-08-11 11:56:12.279000+00:00", + "labels": { + "example": "single", + "hebrew": "english" + }, + "created": "2025-08-11 11:56:12.279000+00:00", + "tag": "latest" + }, + "spec": { + "target_path": "v3io:///projects/llmdeploy332/artifacts/my_llm.json", + "size": 262, + "license": "", + "invocation_config": { + "temperature": 0.5 + }, + "producer": { + "kind": "project", + "name": "llmdeploy332", + "tag": "c00325f6-c2cb-4c62-ad93-8d5de6d0d10d", + "owner": "normal-user" + }, + "prompt_legend": { + "something_with_meaning": { + "field": "word", + "description": "The essence of all things" + } + }, + "prompt_template": [ + { + "role": "system", + "content": "don't tell them anything" + }, + { + "role": "user", + "content": "What is the meaning of {something_with_meaning}?" + }, + { + "role": "system", + "content": "tell you story" + }, + { + "role": "user", + "content": "What is the biggest of {country} at all?" + } + ], + "has_children": false, + "db_key": "my_llm", + "parent_uri": "store://models/llmdeploy332/model_art1#0:v1@418c1ad0-ab41-45df-afb9-722d48d5d65a^bff98dcfd64bd3db006488b7808e9d2dcf37b56f" + }, + "status": { + "state": "created" + }, + "project": "llmdeploy332" + }, + { + "kind": "model", + "metadata": { + "key": "model_art1", + "project": "llmdeploy332", + "iter": 0, + "tree": "418c1ad0-ab41-45df-afb9-722d48d5d65a", + "hash": "dae3b5936acdb82b153b8a17d7d71ba7a66b6b60", + "uid": "bff98dcfd64bd3db006488b7808e9d2dcf37b56f", + "updated": "2025-08-11 11:56:12.178000+00:00", + "created": "2025-08-11 11:56:12.178000+00:00", + "tag": "latest" + }, + "spec": { + "target_path": "v3io:///projects/llmdeploy332/artifacts/model_art1/0/model/", + "size": 4370, + "license": "", + "framework": "sklearn", + "algorithm": "RandomForestClassifier", + "producer": { + "kind": "project", + "name": "llmdeploy332", + "tag": "418c1ad0-ab41-45df-afb9-722d48d5d65a", + "owner": "normal-user" + }, + "model_file": "RandomForestClassifier_file1.pkl", + "has_children": true, + "db_key": "model_art1", + "parameters": { + "default_config": { + "model_version": "4" + } + }, + "parent_uri": null + }, + "status": { + "state": "created" + }, + "project": "llmdeploy332" + }, + { + "kind": "model", + "metadata": { + "key": "model_art1", + "project": "llmdeploy332", + "iter": 0, + "tree": "418c1ad0-ab41-45df-afb9-722d48d5d65a", + "hash": "dae3b5936acdb82b153b8a17d7d71ba7a66b6b60", + "uid": "bff98dcfd64bd3db006488b7808e9d2dcf37b56f", + "updated": "2025-08-11 11:56:12.178000+00:00", + "created": "2025-08-11 11:56:12.178000+00:00", + "tag": "v1" + }, + "spec": { + "target_path": "v3io:///projects/llmdeploy332/artifacts/model_art1/0/model/", + "size": 4370, + "license": "", + "framework": "", + "producer": { + "kind": "project", + "name": "llmdeploy332", + "tag": "418c1ad0-ab41-45df-afb9-722d48d5d65a", + "owner": "normal-user" + }, + "model_file": "RandomForestClassifier_file1.pkl", + "has_children": true, + "db_key": "model_art1", + "parameters": { + "default_config": { + "model_version": "4" + } + }, + "parent_uri": null + }, + "status": { + "state": "created" + }, + "project": "llmdeploy332" + }, + { + "kind": "llm-prompt", + "metadata": { + "key": "my_llm", + "project": "llmdeploy335", + "iter": 0, + "tree": "9dea0dcc-8251-4f4e-94a8-c76b9a64db45", + "hash": "b18c9d7f42c212330a52d6a6d093e37e9fad2491", + "uid": "dc193ddf0914485f8c49d734d4cf8e240dcae118", + "updated": "2025-08-27 14:29:33.222000+00:00", + "labels": { + "example": "single", + "hebrew": "english" + }, + "created": "2025-08-27 14:29:33.222000+00:00", + "tag": "latest" + }, + "spec": { + "src_path": "my_llm.txt", + "target_path": "v3io:///projects/llmdeploy335/artifacts/my_llm.txt", + "size": 173, + "description": "my first promt description for testing", + "prompt_legend": { + "something_with_meaning": { + "field": "something_with_meaning", + "description": "The essence of all things" + } + }, + "has_children": false, + "license": "", + "producer": { + "kind": "project", + "name": "llmdeploy335", + "tag": "9dea0dcc-8251-4f4e-94a8-c76b9a64db45", + "owner": "normal-user" + }, + "invocation_config": { + "temperature": 0.5 + }, + "db_key": "my_llm", + "parent_uri": "store://models/llmdeploy335/model_art1#0:v1@47e2a43f-07fc-4e60-970b-10e10dcd2daf^0a571c5752ee1eb1efdf74c435088ee80b0c521b" + }, + "status": { + "state": "created" + }, + "project": "llmdeploy335" + }, + { + "kind": "model", + "metadata": { + "key": "model_art1", + "project": "llmdeploy335", + "iter": 0, + "tree": "47e2a43f-07fc-4e60-970b-10e10dcd2daf", + "hash": "dae3b5936acdb82b153b8a17d7d71ba7a66b6b60", + "uid": "0a571c5752ee1eb1efdf74c435088ee80b0c521b", + "updated": "2025-08-27 14:29:33.058000+00:00", + "created": "2025-08-27 14:29:33.058000+00:00", + "tag": "latest" + }, + "spec": { + "target_path": "v3io:///projects/llmdeploy332/artifacts/model_art1/0/model/", + "size": 4370, + "framework": "", + "has_children": true, + "license": "", + "producer": { + "kind": "project", + "name": "llmdeploy335", + "tag": "47e2a43f-07fc-4e60-970b-10e10dcd2daf", + "owner": "normal-user" + }, + "model_file": "RandomForestClassifier_file1.pkl", + "db_key": "model_art1", + "parameters": { + "default_config": { + "model_version": "4" + } + }, + "parent_uri": null + }, + "status": { + "state": "created" + }, + "project": "llmdeploy335" } ] -} \ No newline at end of file +} diff --git a/tests/mockServer/data/featureVectors.json b/tests/mockServer/data/featureVectors.json index f5a3a35b77..cd973f5f91 100644 --- a/tests/mockServer/data/featureVectors.json +++ b/tests/mockServer/data/featureVectors.json @@ -7973,6 +7973,2341 @@ } } } - } + }, + { + "kind": "FeatureVector", + "metadata": { + "name": "transactions-fraud", + "project": "churn-project-admin", + "tag": "latest", + "labels": {}, + "updated": "2025-09-30T15:57:17.432089+00:00", + "created": "2025-09-30T15:56:50.695000", + "uid": null + }, + "spec": { + "description": "Predicting a fraudulent transaction", + "graph": { + "engine": "async", + "track_models": false + }, + "features": [ + "events.*", + "transactions.amount_max_2h", + "transactions.amount_sum_2h", + "transactions.amount_count_2h", + "transactions.amount_avg_2h", + "transactions.amount_max_12h", + "transactions.amount_sum_12h", + "transactions.amount_count_12h", + "transactions.amount_avg_12h", + "transactions.amount_max_24h", + "transactions.amount_sum_24h", + "transactions.amount_count_24h", + "transactions.amount_avg_24h", + "transactions.es_transportation_sum_14d", + "transactions.es_health_sum_14d", + "transactions.es_otherservices_sum_14d", + "transactions.es_food_sum_14d", + "transactions.es_hotelservices_sum_14d", + "transactions.es_barsandrestaurants_sum_14d", + "transactions.es_tech_sum_14d", + "transactions.es_sportsandtoys_sum_14d", + "transactions.es_wellnessandbeauty_sum_14d", + "transactions.es_hyper_sum_14d", + "transactions.es_fashion_sum_14d", + "transactions.es_home_sum_14d", + "transactions.es_travel_sum_14d", + "transactions.es_leisure_sum_14d", + "transactions.gender_F", + "transactions.gender_M", + "transactions.step", + "transactions.amount", + "transactions.timestamp_hour", + "transactions.timestamp_day_of_week" + ], + "label_feature": "labels.label" + }, + "status": { + "state": "created", + "label_column": "label", + "stats": { + "event_password_change": { + "count": 82092, + "mean": 0.38064610437070606, + "min": 0, + "25%": 0, + "50%": 0, + "75%": 1, + "max": 1, + "std": 0.4855486787827919, + "hist": [ + [ + 50844, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 31248 + ], + [ + 0, + 0.05, + 0.1, + 0.15000000000000002, + 0.2, + 0.25, + 0.30000000000000004, + 0.35000000000000003, + 0.4, + 0.45, + 0.5, + 0.55, + 0.6000000000000001, + 0.65, + 0.7000000000000001, + 0.75, + 0.8, + 0.8500000000000001, + 0.9, + 0.9500000000000001, + 1 + ] + ] + }, + "event_details_change": { + "count": 82092, + "mean": 0.2858743848365249, + "min": 0, + "25%": 0, + "50%": 0, + "75%": 1, + "max": 1, + "std": 0.4518326103856129, + "hist": [ + [ + 58624, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 23468 + ], + [ + 0, + 0.05, + 0.1, + 0.15000000000000002, + 0.2, + 0.25, + 0.30000000000000004, + 0.35000000000000003, + 0.4, + 0.45, + 0.5, + 0.55, + 0.6000000000000001, + 0.65, + 0.7000000000000001, + 0.75, + 0.8, + 0.8500000000000001, + 0.9, + 0.9500000000000001, + 1 + ] + ] + }, + "event_login": { + "count": 82092, + "mean": 0.3334795107927691, + "min": 0, + "25%": 0, + "50%": 0, + "75%": 1, + "max": 1, + "std": 0.47145904837053226, + "hist": [ + [ + 54716, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 27376 + ], + [ + 0, + 0.05, + 0.1, + 0.15000000000000002, + 0.2, + 0.25, + 0.30000000000000004, + 0.35000000000000003, + 0.4, + 0.45, + 0.5, + 0.55, + 0.6000000000000001, + 0.65, + 0.7000000000000001, + 0.75, + 0.8, + 0.8500000000000001, + 0.9, + 0.9500000000000001, + 1 + ] + ] + }, + "amount_max_2h": { + "count": 10000, + "mean": 82.167229, + "min": 0.05, + "25%": 39.9275, + "50%": 53.205, + "75%": 69.55, + "max": 7635.41, + "std": 233.1742143601985, + "hist": [ + [ + 9845, + 84, + 29, + 19, + 2, + 3, + 0, + 0, + 7, + 0, + 4, + 1, + 0, + 0, + 2, + 0, + 0, + 0, + 0, + 4 + ], + [ + 0.05, + 381.818, + 763.5859999999999, + 1145.3539999999998, + 1527.1219999999998, + 1908.8899999999999, + 2290.658, + 2672.426, + 3054.194, + 3435.962, + 3817.73, + 4199.498, + 4581.266, + 4963.034, + 5344.802, + 5726.57, + 6108.338, + 6490.106, + 6871.874, + 7253.642, + 7635.41 + ] + ] + }, + "amount_sum_2h": { + "count": 10000, + "mean": 175.44363499999997, + "min": 0.05, + "25%": 86.5375, + "50%": 139.82999999999998, + "75%": 208.88500000000002, + "max": 7731.7, + "std": 255.86760733153568, + "hist": [ + [ + 9532, + 377, + 48, + 9, + 10, + 4, + 2, + 0, + 0, + 7, + 3, + 2, + 0, + 0, + 2, + 0, + 0, + 0, + 0, + 4 + ], + [ + 0.05, + 386.6325, + 773.2149999999999, + 1159.7975, + 1546.3799999999999, + 1932.9624999999999, + 2319.545, + 2706.1275, + 3092.71, + 3479.2925, + 3865.875, + 4252.4574999999995, + 4639.04, + 5025.6225, + 5412.205, + 5798.787499999999, + 6185.37, + 6571.9525, + 6958.535, + 7345.117499999999, + 7731.7 + ] + ] + }, + "amount_count_2h": { + "count": 10000, + "mean": 4.8871, + "min": 1, + "25%": 3, + "50%": 5, + "75%": 6, + "max": 15, + "std": 2.314581888577696, + "hist": [ + [ + 484, + 997, + 1526, + 0, + 1753, + 1625, + 0, + 1334, + 948, + 0, + 618, + 366, + 180, + 0, + 86, + 44, + 0, + 23, + 13, + 3 + ], + [ + 1, + 1.7, + 2.4, + 3.0999999999999996, + 3.8, + 4.5, + 5.199999999999999, + 5.8999999999999995, + 6.6, + 7.3, + 8, + 8.7, + 9.399999999999999, + 10.1, + 10.799999999999999, + 11.5, + 12.2, + 12.899999999999999, + 13.6, + 14.299999999999999, + 15 + ] + ] + }, + "amount_avg_2h": { + "count": 10000, + "mean": 38.61512201386391, + "min": 0.05, + "25%": 22.85108333333333, + "50%": 29.39089285714286, + "75%": 37.98785714285715, + "max": 5468.17, + "std": 99.12880723644561, + "hist": [ + [ + 9945, + 32, + 8, + 3, + 0, + 4, + 0, + 4, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1 + ], + [ + 0.05, + 273.456, + 546.862, + 820.268, + 1093.674, + 1367.08, + 1640.486, + 1913.892, + 2187.2980000000002, + 2460.704, + 2734.11, + 3007.516, + 3280.9220000000005, + 3554.3280000000004, + 3827.7340000000004, + 4101.14, + 4374.546, + 4647.952, + 4921.358, + 5194.764, + 5468.17 + ] + ] + }, + "amount_max_12h": { + "count": 10000, + "mean": 217.180914, + "min": 0.05, + "25%": 72.2, + "50%": 97.41, + "75%": 183.97, + "max": 7635.41, + "std": 574.7305154744495, + "hist": [ + [ + 9357, + 296, + 97, + 97, + 5, + 26, + 0, + 0, + 38, + 0, + 23, + 16, + 0, + 0, + 19, + 0, + 0, + 0, + 0, + 26 + ], + [ + 0.05, + 381.818, + 763.5859999999999, + 1145.3539999999998, + 1527.1219999999998, + 1908.8899999999999, + 2290.658, + 2672.426, + 3054.194, + 3435.962, + 3817.73, + 4199.498, + 4581.266, + 4963.034, + 5344.802, + 5726.57, + 6108.338, + 6490.106, + 6871.874, + 7253.642, + 7635.41 + ] + ] + }, + "amount_sum_12h": { + "count": 10000, + "mean": 987.761435, + "min": 0.05, + "25%": 688.1524999999999, + "50%": 943.855, + "75%": 1163.3075000000001, + "max": 9266.04, + "std": 706.9679061427487, + "hist": [ + [ + 1252, + 3562, + 4195, + 624, + 145, + 46, + 27, + 24, + 17, + 29, + 27, + 9, + 11, + 5, + 1, + 0, + 0, + 6, + 3, + 17 + ], + [ + 0.05, + 463.3495000000001, + 926.6490000000001, + 1389.9485000000002, + 1853.2480000000003, + 2316.5475000000006, + 2779.8470000000007, + 3243.1465000000007, + 3706.446000000001, + 4169.745500000001, + 4633.045000000001, + 5096.344500000001, + 5559.644000000001, + 6022.943500000001, + 6486.243000000001, + 6949.542500000001, + 7412.8420000000015, + 7876.1415000000015, + 8339.441, + 8802.7405, + 9266.04 + ] + ] + }, + "amount_count_12h": { + "count": 10000, + "mean": 27.5866, + "min": 1, + "25%": 22, + "50%": 30, + "75%": 35, + "max": 52, + "std": 10.668012049492107, + "hist": [ + [ + 279, + 301, + 189, + 330, + 248, + 394, + 263, + 487, + 425, + 814, + 1097, + 849, + 1389, + 938, + 1064, + 443, + 321, + 99, + 55, + 15 + ], + [ + 1, + 3.55, + 6.1, + 8.649999999999999, + 11.2, + 13.75, + 16.299999999999997, + 18.849999999999998, + 21.4, + 23.95, + 26.5, + 29.049999999999997, + 31.599999999999998, + 34.15, + 36.699999999999996, + 39.25, + 41.8, + 44.349999999999994, + 46.9, + 49.449999999999996, + 52 + ] + ] + }, + "amount_avg_12h": { + "count": 10000, + "mean": 39.690992824939386, + "min": 0.05, + "25%": 27.973053724456165, + "50%": 31.49118154158215, + "75%": 36.44510416666667, + "max": 5468.17, + "std": 77.19114246739247, + "hist": [ + [ + 9909, + 77, + 6, + 3, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1 + ], + [ + 0.05, + 273.456, + 546.862, + 820.268, + 1093.674, + 1367.08, + 1640.486, + 1913.892, + 2187.2980000000002, + 2460.704, + 2734.11, + 3007.516, + 3280.9220000000005, + 3554.3280000000004, + 3827.7340000000004, + 4101.14, + 4374.546, + 4647.952, + 4921.358, + 5194.764, + 5468.17 + ] + ] + }, + "amount_max_24h": { + "count": 10000, + "mean": 289.69621199999995, + "min": 0.05, + "25%": 86.41, + "50%": 147.62, + "75%": 228.89, + "max": 7635.41, + "std": 685.5336807658961, + "hist": [ + [ + 9055, + 397, + 129, + 169, + 10, + 49, + 0, + 0, + 62, + 0, + 32, + 25, + 0, + 0, + 44, + 0, + 0, + 0, + 0, + 28 + ], + [ + 0.05, + 381.818, + 763.5859999999999, + 1145.3539999999998, + 1527.1219999999998, + 1908.8899999999999, + 2290.658, + 2672.426, + 3054.194, + 3435.962, + 3817.73, + 4199.498, + 4581.266, + 4963.034, + 5344.802, + 5726.57, + 6108.338, + 6490.106, + 6871.874, + 7253.642, + 7635.41 + ] + ] + }, + "amount_sum_24h": { + "count": 10000, + "mean": 1690.288283, + "min": 0.05, + "25%": 1022.9075000000001, + "50%": 1759.455, + "75%": 2179.6399999999994, + "max": 10144.09, + "std": 1044.6191477481475, + "hist": [ + [ + 1190, + 1291, + 1516, + 2608, + 2403, + 532, + 179, + 61, + 61, + 26, + 31, + 37, + 1, + 11, + 14, + 11, + 0, + 0, + 0, + 28 + ], + [ + 0.05, + 507.25200000000007, + 1014.4540000000001, + 1521.6560000000002, + 2028.8580000000002, + 2536.0600000000004, + 3043.2620000000006, + 3550.4640000000004, + 4057.6660000000006, + 4564.868, + 5072.070000000001, + 5579.272000000001, + 6086.474000000001, + 6593.676000000001, + 7100.878000000001, + 7608.080000000001, + 8115.282000000001, + 8622.484, + 9129.686, + 9636.888, + 10144.09 + ] + ] + }, + "amount_count_24h": { + "count": 10000, + "mean": 47.6612, + "min": 1, + "25%": 28, + "50%": 54, + "75%": 67, + "max": 90, + "std": 23.04833480175332, + "hist": [ + [ + 444, + 367, + 433, + 356, + 441, + 371, + 488, + 359, + 452, + 408, + 401, + 565, + 522, + 986, + 950, + 1244, + 699, + 423, + 80, + 11 + ], + [ + 1, + 5.45, + 9.9, + 14.350000000000001, + 18.8, + 23.25, + 27.700000000000003, + 32.150000000000006, + 36.6, + 41.050000000000004, + 45.5, + 49.95, + 54.400000000000006, + 58.85, + 63.300000000000004, + 67.75, + 72.2, + 76.65, + 81.10000000000001, + 85.55, + 90 + ] + ] + }, + "amount_avg_24h": { + "count": 10000, + "mean": 39.9029276006047, + "min": 0.05, + "25%": 29.000666666666664, + "50%": 31.887500000000003, + "75%": 36.11239864864865, + "max": 5468.17, + "std": 75.22140915109931, + "hist": [ + [ + 9943, + 45, + 5, + 2, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1 + ], + [ + 0.05, + 273.456, + 546.862, + 820.268, + 1093.674, + 1367.08, + 1640.486, + 1913.892, + 2187.2980000000002, + 2460.704, + 2734.11, + 3007.516, + 3280.9220000000005, + 3554.3280000000004, + 3827.7340000000004, + 4101.14, + 4374.546, + 4647.952, + 4921.358, + 5194.764, + 5468.17 + ] + ] + }, + "es_transportation_sum_14d": { + "count": 10000, + "mean": 54.8019, + "min": 0, + "25%": 24, + "50%": 52, + "75%": 83, + "max": 129, + "std": 34.801493801086735, + "hist": [ + [ + 736, + 570, + 696, + 587, + 655, + 568, + 635, + 504, + 589, + 493, + 487, + 555, + 448, + 498, + 417, + 452, + 370, + 388, + 251, + 101 + ], + [ + 0, + 6.45, + 12.9, + 19.35, + 25.8, + 32.25, + 38.7, + 45.15, + 51.6, + 58.050000000000004, + 64.5, + 70.95, + 77.4, + 83.85000000000001, + 90.3, + 96.75, + 103.2, + 109.65, + 116.10000000000001, + 122.55, + 129 + ] + ] + }, + "es_health_sum_14d": { + "count": 10000, + "mean": 1.377, + "min": 0, + "25%": 0, + "50%": 1, + "75%": 2, + "max": 16, + "std": 1.952755060224534, + "hist": [ + [ + 4715, + 2232, + 806, + 1069, + 0, + 378, + 292, + 80, + 301, + 0, + 65, + 37, + 6, + 7, + 0, + 2, + 2, + 3, + 2, + 3 + ], + [ + 0, + 0.8, + 1.6, + 2.4000000000000004, + 3.2, + 4, + 4.800000000000001, + 5.6000000000000005, + 6.4, + 7.2, + 8, + 8.8, + 9.600000000000001, + 10.4, + 11.200000000000001, + 12, + 12.8, + 13.600000000000001, + 14.4, + 15.200000000000001, + 16 + ] + ] + }, + "es_otherservices_sum_14d": { + "count": 10000, + "mean": 0.116, + "min": 0, + "25%": 0, + "50%": 0, + "75%": 0, + "max": 2, + "std": 0.3492222725135984, + "hist": [ + [ + 8937, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 966, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 97 + ], + [ + 0, + 0.1, + 0.2, + 0.30000000000000004, + 0.4, + 0.5, + 0.6000000000000001, + 0.7000000000000001, + 0.8, + 0.9, + 1, + 1.1, + 1.2000000000000002, + 1.3, + 1.4000000000000001, + 1.5, + 1.6, + 1.7000000000000002, + 1.8, + 1.9000000000000001, + 2 + ] + ] + }, + "es_food_sum_14d": { + "count": 10000, + "mean": 2.624, + "min": 0, + "25%": 0, + "50%": 2, + "75%": 4, + "max": 13, + "std": 2.829456587837715, + "hist": [ + [ + 3197, + 1535, + 0, + 999, + 1140, + 0, + 848, + 708, + 0, + 409, + 380, + 0, + 299, + 256, + 0, + 112, + 28, + 0, + 40, + 49 + ], + [ + 0, + 0.65, + 1.3, + 1.9500000000000002, + 2.6, + 3.25, + 3.9000000000000004, + 4.55, + 5.2, + 5.8500000000000005, + 6.5, + 7.15, + 7.800000000000001, + 8.450000000000001, + 9.1, + 9.75, + 10.4, + 11.05, + 11.700000000000001, + 12.35, + 13 + ] + ] + }, + "es_hotelservices_sum_14d": { + "count": 10000, + "mean": 0.1652, + "min": 0, + "25%": 0, + "50%": 0, + "75%": 0, + "max": 2, + "std": 0.3859065332243528, + "hist": [ + [ + 8403, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1542, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 55 + ], + [ + 0, + 0.1, + 0.2, + 0.30000000000000004, + 0.4, + 0.5, + 0.6000000000000001, + 0.7000000000000001, + 0.8, + 0.9, + 1, + 1.1, + 1.2000000000000002, + 1.3, + 1.4000000000000001, + 1.5, + 1.6, + 1.7000000000000002, + 1.8, + 1.9000000000000001, + 2 + ] + ] + }, + "es_barsandrestaurants_sum_14d": { + "count": 10000, + "mean": 0.7864, + "min": 0, + "25%": 0, + "50%": 0, + "75%": 1, + "max": 5, + "std": 1.110899837899432, + "hist": [ + [ + 5648, + 0, + 0, + 0, + 2195, + 0, + 0, + 0, + 1223, + 0, + 0, + 0, + 555, + 0, + 0, + 0, + 337, + 0, + 0, + 42 + ], + [ + 0, + 0.25, + 0.5, + 0.75, + 1, + 1.25, + 1.5, + 1.75, + 2, + 2.25, + 2.5, + 2.75, + 3, + 3.25, + 3.5, + 3.75, + 4, + 4.25, + 4.5, + 4.75, + 5 + ] + ] + }, + "es_tech_sum_14d": { + "count": 10000, + "mean": 0.1698, + "min": 0, + "25%": 0, + "50%": 0, + "75%": 0, + "max": 3, + "std": 0.414710933682549, + "hist": [ + [ + 8446, + 0, + 0, + 0, + 0, + 0, + 1421, + 0, + 0, + 0, + 0, + 0, + 0, + 122, + 0, + 0, + 0, + 0, + 0, + 11 + ], + [ + 0, + 0.15, + 0.3, + 0.44999999999999996, + 0.6, + 0.75, + 0.8999999999999999, + 1.05, + 1.2, + 1.3499999999999999, + 1.5, + 1.65, + 1.7999999999999998, + 1.95, + 2.1, + 2.25, + 2.4, + 2.55, + 2.6999999999999997, + 2.85, + 3 + ] + ] + }, + "es_sportsandtoys_sum_14d": { + "count": 10000, + "mean": 0.3603, + "min": 0, + "25%": 0, + "50%": 0, + "75%": 1, + "max": 9, + "std": 0.7301624639231821, + "hist": [ + [ + 7454, + 0, + 1799, + 0, + 522, + 0, + 172, + 0, + 39, + 0, + 0, + 3, + 0, + 7, + 0, + 2, + 0, + 1, + 0, + 1 + ], + [ + 0, + 0.45, + 0.9, + 1.35, + 1.8, + 2.25, + 2.7, + 3.15, + 3.6, + 4.05, + 4.5, + 4.95, + 5.4, + 5.8500000000000005, + 6.3, + 6.75, + 7.2, + 7.65, + 8.1, + 8.55, + 9 + ] + ] + }, + "es_wellnessandbeauty_sum_14d": { + "count": 10000, + "mean": 1.4875, + "min": 0, + "25%": 0, + "50%": 1, + "75%": 2, + "max": 14, + "std": 1.7617474635748853, + "hist": [ + [ + 3439, + 2791, + 1820, + 0, + 888, + 413, + 0, + 258, + 224, + 0, + 55, + 31, + 13, + 0, + 35, + 16, + 0, + 8, + 4, + 5 + ], + [ + 0, + 0.7, + 1.4, + 2.0999999999999996, + 2.8, + 3.5, + 4.199999999999999, + 4.8999999999999995, + 5.6, + 6.3, + 7, + 7.699999999999999, + 8.399999999999999, + 9.1, + 9.799999999999999, + 10.5, + 11.2, + 11.899999999999999, + 12.6, + 13.299999999999999, + 14 + ] + ] + }, + "es_hyper_sum_14d": { + "count": 10000, + "mean": 0.7528, + "min": 0, + "25%": 0, + "50%": 0, + "75%": 1, + "max": 6, + "std": 1.0529021893329076, + "hist": [ + [ + 5417, + 0, + 0, + 2764, + 0, + 0, + 1133, + 0, + 0, + 0, + 326, + 0, + 0, + 301, + 0, + 0, + 38, + 0, + 0, + 21 + ], + [ + 0, + 0.3, + 0.6, + 0.8999999999999999, + 1.2, + 1.5, + 1.7999999999999998, + 2.1, + 2.4, + 2.6999999999999997, + 3, + 3.3, + 3.5999999999999996, + 3.9, + 4.2, + 4.5, + 4.8, + 5.1, + 5.3999999999999995, + 5.7, + 6 + ] + ] + }, + "es_fashion_sum_14d": { + "count": 10000, + "mean": 0.7147, + "min": 0, + "25%": 0, + "50%": 0, + "75%": 1, + "max": 8, + "std": 1.019611627428345, + "hist": [ + [ + 5215, + 0, + 3376, + 0, + 0, + 946, + 0, + 166, + 0, + 0, + 217, + 0, + 23, + 0, + 0, + 12, + 0, + 34, + 0, + 11 + ], + [ + 0, + 0.4, + 0.8, + 1.2000000000000002, + 1.6, + 2, + 2.4000000000000004, + 2.8000000000000003, + 3.2, + 3.6, + 4, + 4.4, + 4.800000000000001, + 5.2, + 5.6000000000000005, + 6, + 6.4, + 6.800000000000001, + 7.2, + 7.6000000000000005, + 8 + ] + ] + }, + "es_home_sum_14d": { + "count": 10000, + "mean": 0.2233, + "min": 0, + "25%": 0, + "50%": 0, + "75%": 0, + "max": 5, + "std": 0.5310982174058327, + "hist": [ + [ + 8254, + 0, + 0, + 0, + 1295, + 0, + 0, + 0, + 429, + 0, + 0, + 0, + 14, + 0, + 0, + 0, + 2, + 0, + 0, + 6 + ], + [ + 0, + 0.25, + 0.5, + 0.75, + 1, + 1.25, + 1.5, + 1.75, + 2, + 2.25, + 2.5, + 2.75, + 3, + 3.25, + 3.5, + 3.75, + 4, + 4.25, + 4.5, + 4.75, + 5 + ] + ] + }, + "es_travel_sum_14d": { + "count": 10000, + "mean": 0.0508, + "min": 0, + "25%": 0, + "50%": 0, + "75%": 0, + "max": 2, + "std": 0.2320016001544977, + "hist": [ + [ + 9520, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 452, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 28 + ], + [ + 0, + 0.1, + 0.2, + 0.30000000000000004, + 0.4, + 0.5, + 0.6000000000000001, + 0.7000000000000001, + 0.8, + 0.9, + 1, + 1.1, + 1.2000000000000002, + 1.3, + 1.4000000000000001, + 1.5, + 1.6, + 1.7000000000000002, + 1.8, + 1.9000000000000001, + 2 + ] + ] + }, + "es_leisure_sum_14d": { + "count": 10000, + "mean": 0.0652, + "min": 0, + "25%": 0, + "50%": 0, + "75%": 0, + "max": 2, + "std": 0.29420675682515546, + "hist": [ + [ + 9476, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 396, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 128 + ], + [ + 0, + 0.1, + 0.2, + 0.30000000000000004, + 0.4, + 0.5, + 0.6000000000000001, + 0.7000000000000001, + 0.8, + 0.9, + 1, + 1.1, + 1.2000000000000002, + 1.3, + 1.4000000000000001, + 1.5, + 1.6, + 1.7000000000000002, + 1.8, + 1.9000000000000001, + 2 + ] + ] + }, + "gender_F": { + "count": 10000, + "mean": 0.4552, + "min": 0, + "25%": 0, + "50%": 0, + "75%": 1, + "max": 1, + "std": 0.498013816852683, + "hist": [ + [ + 5448, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 4552 + ], + [ + 0, + 0.05, + 0.1, + 0.15000000000000002, + 0.2, + 0.25, + 0.30000000000000004, + 0.35000000000000003, + 0.4, + 0.45, + 0.5, + 0.55, + 0.6000000000000001, + 0.65, + 0.7000000000000001, + 0.75, + 0.8, + 0.8500000000000001, + 0.9, + 0.9500000000000001, + 1 + ] + ] + }, + "gender_M": { + "count": 10000, + "mean": 0.5448, + "min": 0, + "25%": 0, + "50%": 1, + "75%": 1, + "max": 1, + "std": 0.498013816852683, + "hist": [ + [ + 4552, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5448 + ], + [ + 0, + 0.05, + 0.1, + 0.15000000000000002, + 0.2, + 0.25, + 0.30000000000000004, + 0.35000000000000003, + 0.4, + 0.45, + 0.5, + 0.55, + 0.6000000000000001, + 0.65, + 0.7000000000000001, + 0.75, + 0.8, + 0.8500000000000001, + 0.9, + 0.9500000000000001, + 1 + ] + ] + }, + "step": { + "count": 10000, + "mean": 78.9453, + "min": 0, + "25%": 44, + "50%": 81, + "75%": 115, + "max": 147, + "std": 41.598136357351876, + "hist": [ + [ + 392, + 355, + 443, + 404, + 416, + 498, + 441, + 468, + 551, + 479, + 498, + 559, + 500, + 531, + 608, + 569, + 537, + 623, + 538, + 590 + ], + [ + 0, + 7.35, + 14.7, + 22.049999999999997, + 29.4, + 36.75, + 44.099999999999994, + 51.449999999999996, + 58.8, + 66.14999999999999, + 73.5, + 80.85, + 88.19999999999999, + 95.55, + 102.89999999999999, + 110.25, + 117.6, + 124.94999999999999, + 132.29999999999998, + 139.65, + 147 + ] + ] + }, + "amount": { + "count": 10000, + "mean": 38.00471700000001, + "min": 0, + "25%": 13.57, + "50%": 26.69, + "75%": 42.36, + "max": 7635.41, + "std": 130.3568133027091, + "hist": [ + [ + 9958, + 21, + 8, + 6, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1 + ], + [ + 0, + 381.77049999999997, + 763.5409999999999, + 1145.3114999999998, + 1527.0819999999999, + 1908.8525, + 2290.6229999999996, + 2672.3934999999997, + 3054.1639999999998, + 3435.9345, + 3817.705, + 4199.4755, + 4581.245999999999, + 4963.0165, + 5344.786999999999, + 5726.5575, + 6108.3279999999995, + 6490.098499999999, + 6871.869, + 7253.639499999999, + 7635.41 + ] + ] + }, + "timestamp_hour": { + "count": 10000, + "mean": 11.45, + "min": 0, + "25%": 5, + "50%": 11, + "75%": 17, + "max": 23, + "std": 6.927705197966422, + "hist": [ + [ + 834, + 421, + 415, + 441, + 424, + 421, + 836, + 431, + 405, + 398, + 441, + 394, + 434, + 825, + 386, + 403, + 423, + 411, + 418, + 839 + ], + [ + 0, + 1.15, + 2.3, + 3.4499999999999997, + 4.6, + 5.75, + 6.8999999999999995, + 8.049999999999999, + 9.2, + 10.35, + 11.5, + 12.649999999999999, + 13.799999999999999, + 14.95, + 16.099999999999998, + 17.25, + 18.4, + 19.549999999999997, + 20.7, + 21.849999999999998, + 23 + ] + ] + }, + "timestamp_day_of_week": { + "count": 10000, + "mean": 1.663, + "min": 0, + "25%": 0, + "50%": 0, + "75%": 1, + "max": 6, + "std": 2.4345479462048467, + "hist": [ + [ + 5085, + 0, + 0, + 2572, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2343 + ], + [ + 0, + 0.3, + 0.6, + 0.8999999999999999, + 1.2, + 1.5, + 1.7999999999999998, + 2.1, + 2.4, + 2.6999999999999997, + 3, + 3.3, + 3.5999999999999996, + 3.9, + 4.2, + 4.5, + 4.8, + 5.1, + 5.3999999999999995, + 5.7, + 6 + ] + ] + }, + "label": { + "count": 10000, + "mean": 0.0095, + "min": 0, + "25%": 0, + "50%": 0, + "75%": 0, + "max": 1, + "std": 0.09700871645943425, + "hist": [ + [ + 9905, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 95 + ], + [ + 0, + 0.05, + 0.1, + 0.15000000000000002, + 0.2, + 0.25, + 0.30000000000000004, + 0.35000000000000003, + 0.4, + 0.45, + 0.5, + 0.55, + 0.6000000000000001, + 0.65, + 0.7000000000000001, + 0.75, + 0.8, + 0.8500000000000001, + 0.9, + 0.9500000000000001, + 1 + ] + ] + } + }, + "features": [ + { + "origin": "churn-project-admin/events:latest.event_password_change", + "value_type": "int", + "name": "event_password_change" + }, + { + "origin": "churn-project-admin/events:latest.event_details_change", + "value_type": "int", + "name": "event_details_change" + }, + { + "origin": "churn-project-admin/events:latest.event_login", + "value_type": "int", + "name": "event_login" + }, + { + "origin": "churn-project-admin/transactions:latest.amount_max_2h", + "value_type": "float", + "name": "amount_max_2h", + "aggregate": true + }, + { + "origin": "churn-project-admin/transactions:latest.amount_sum_2h", + "value_type": "float", + "name": "amount_sum_2h", + "aggregate": true + }, + { + "origin": "churn-project-admin/transactions:latest.amount_count_2h", + "value_type": "float", + "name": "amount_count_2h", + "aggregate": true + }, + { + "origin": "churn-project-admin/transactions:latest.amount_avg_2h", + "value_type": "float", + "name": "amount_avg_2h", + "aggregate": true + }, + { + "origin": "churn-project-admin/transactions:latest.amount_max_12h", + "value_type": "float", + "name": "amount_max_12h", + "aggregate": true + }, + { + "origin": "churn-project-admin/transactions:latest.amount_sum_12h", + "value_type": "float", + "name": "amount_sum_12h", + "aggregate": true + }, + { + "origin": "churn-project-admin/transactions:latest.amount_count_12h", + "value_type": "float", + "name": "amount_count_12h", + "aggregate": true + }, + { + "origin": "churn-project-admin/transactions:latest.amount_avg_12h", + "value_type": "float", + "name": "amount_avg_12h", + "aggregate": true + }, + { + "origin": "churn-project-admin/transactions:latest.amount_max_24h", + "value_type": "float", + "name": "amount_max_24h", + "aggregate": true + }, + { + "origin": "churn-project-admin/transactions:latest.amount_sum_24h", + "value_type": "float", + "name": "amount_sum_24h", + "aggregate": true + }, + { + "origin": "churn-project-admin/transactions:latest.amount_count_24h", + "value_type": "float", + "name": "amount_count_24h", + "aggregate": true + }, + { + "origin": "churn-project-admin/transactions:latest.amount_avg_24h", + "value_type": "float", + "name": "amount_avg_24h", + "aggregate": true + }, + { + "origin": "churn-project-admin/transactions:latest.es_transportation_sum_14d", + "value_type": "float", + "name": "es_transportation_sum_14d", + "aggregate": true + }, + { + "origin": "churn-project-admin/transactions:latest.es_health_sum_14d", + "value_type": "float", + "name": "es_health_sum_14d", + "aggregate": true + }, + { + "origin": "churn-project-admin/transactions:latest.es_otherservices_sum_14d", + "value_type": "float", + "name": "es_otherservices_sum_14d", + "aggregate": true + }, + { + "origin": "churn-project-admin/transactions:latest.es_food_sum_14d", + "value_type": "float", + "name": "es_food_sum_14d", + "aggregate": true + }, + { + "origin": "churn-project-admin/transactions:latest.es_hotelservices_sum_14d", + "value_type": "float", + "name": "es_hotelservices_sum_14d", + "aggregate": true + }, + { + "origin": "churn-project-admin/transactions:latest.es_barsandrestaurants_sum_14d", + "value_type": "float", + "name": "es_barsandrestaurants_sum_14d", + "aggregate": true + }, + { + "origin": "churn-project-admin/transactions:latest.es_tech_sum_14d", + "value_type": "float", + "name": "es_tech_sum_14d", + "aggregate": true + }, + { + "origin": "churn-project-admin/transactions:latest.es_sportsandtoys_sum_14d", + "value_type": "float", + "name": "es_sportsandtoys_sum_14d", + "aggregate": true + }, + { + "origin": "churn-project-admin/transactions:latest.es_wellnessandbeauty_sum_14d", + "value_type": "float", + "name": "es_wellnessandbeauty_sum_14d", + "aggregate": true + }, + { + "origin": "churn-project-admin/transactions:latest.es_hyper_sum_14d", + "value_type": "float", + "name": "es_hyper_sum_14d", + "aggregate": true + }, + { + "origin": "churn-project-admin/transactions:latest.es_fashion_sum_14d", + "value_type": "float", + "name": "es_fashion_sum_14d", + "aggregate": true + }, + { + "origin": "churn-project-admin/transactions:latest.es_home_sum_14d", + "value_type": "float", + "name": "es_home_sum_14d", + "aggregate": true + }, + { + "origin": "churn-project-admin/transactions:latest.es_travel_sum_14d", + "value_type": "float", + "name": "es_travel_sum_14d", + "aggregate": true + }, + { + "origin": "churn-project-admin/transactions:latest.es_leisure_sum_14d", + "value_type": "float", + "name": "es_leisure_sum_14d", + "aggregate": true + }, + { + "origin": "churn-project-admin/transactions:latest.gender_F", + "value_type": "int", + "name": "gender_F" + }, + { + "origin": "churn-project-admin/transactions:latest.gender_M", + "value_type": "int", + "name": "gender_M" + }, + { + "origin": "churn-project-admin/transactions:latest.step", + "value_type": "int", + "name": "step" + }, + { + "origin": "churn-project-admin/transactions:latest.amount", + "value_type": "float", + "name": "amount" + }, + { + "origin": "churn-project-admin/transactions:latest.timestamp_hour", + "value_type": "int", + "name": "timestamp_hour" + }, + { + "origin": "churn-project-admin/transactions:latest.timestamp_day_of_week", + "value_type": "int", + "name": "timestamp_day_of_week" + }, + { + "origin": "churn-project-admin/labels:latest.label", + "value_type": "int", + "name": "label" + } + ], + "index_keys": [ + "source" + ], + "targets": [ + { + "path": "v3io:///projects/churn-project-admin/FeatureStore/transactions-fraud/parquet/vectors/transactions-fraud-latest.parquet", + "size": 151274, + "status": "ready", + "name": "parquet", + "updated": "2025-09-30T15:57:17.402617+00:00", + "partitioned": true, + "kind": "parquet" + } + ] + } + } ] } diff --git a/tests/mockServer/data/funcs.json b/tests/mockServer/data/funcs.json index 1763514d87..8546eac84d 100644 --- a/tests/mockServer/data/funcs.json +++ b/tests/mockServer/data/funcs.json @@ -1,5 +1,203 @@ { "funcs": [ + { + "metadata": { + "tag": "latest", + "name": "function-with-llm", + "credentials": { + "access_key": "$ref:mlrun-auth-secrets.253c8a6e4c3595da61cbc90b60036ec928934dd6826298fcc3b5e3c3" + }, + "project": "default", + "hash": "a87f91c90d26cdc8d03bb3fcb1423d0ea005b00e", + "updated": "2025-10-06T14:36:35.053000+00:00" + }, + "spec": { + "base_image_pull": false, + "default_handler": "", + "function_kind": "serving_v2", + "preemption_mode": "prevent", + "function_handler": "function-with-llm-nuclio:handler", + "max_replicas": 4, + "min_replicas": 1, + "description": "", + "source": "", + "graph": { + "steps": { + "model-runner": { + "class_args": { + "model_selector": [ + null, + null + ], + "execution_mechanism_by_model_name": { + "my-endpoint": "shared_executor" + }, + "models": { + "my-endpoint": [ + "mlrun.serving.Model", + { + "name": "my-endpoint", + "shared_runnable_name": "model-deployment", + "artifact_uri": "store://llm-prompts/default/my_llm4#0@9c0c8773-b1ce-4fa0-ac94-2f6c1fb71554^d28e010ba24e272a3ba2ba522f6caecde05ff383" + } + ] + }, + "monitoring_data": { + "my-endpoint": { + "inputs": [], + "outputs": [ + "output1", + "output2" + ], + "input_path": "input_path", + "result_path": "result_path", + "creation_strategy": "inplace", + "labels": null, + "model_path": "store://llm-prompts/default/my_llm4#0@9c0c8773-b1ce-4fa0-ac94-2f6c1fb71554^d28e010ba24e272a3ba2ba522f6caecde05ff383", + "model_class": "MyLLM", + "model_endpoint_uid": "c3e9308aaab54e53b1013ecda9234e43" + }, + "my-endpoin2t": { + "inputs": [ ], + "outputs": [ ], + "input_path": null, + "result_path": null, + "creation_strategy": "inplace", + "labels": null, + "model_path": "store://llm-prompts/default/my_llm4#0@9c0c8773-b1ce-4fa0-ac94-2f6c1fb71554^d28e010ba24e272a3ba2ba522f6caecde05ff383", + "model_class": "MyLLM", + "model_endpoint_uid": "a7c95783e6a726a1a233e581ea898ba33fa7e342" + } + } + }, + "responder": true, + "kind": "model_runner", + "endpoint_type": 1, + "model_endpoint_creation_strategy": "skip", + "class_name": "mlrun.serving.ModelRunner", + "raise_exception": true, + "_shared_proxy_mapping": { + "model-deployment": { + "my-endpoint": "store://llm-prompts/default/my_llm4#0:latest@9c0c8773-b1ce-4fa0-ac94-2f6c1fb71554^d28e010ba24e272a3ba2ba522f6caecde05ff383" + } + }, + "shape": "folder" + } + }, + "shared_models": { + "model-deployment": [ + "MyLLM", + { + "name": "model-deployment", + "artifact_uri": "store://models/default/model_art1#0@5b83db22-80da-4c97-8cd0-eb269a4c9d2a^e1b0a442a7602456e6bbd0934931b3eaaf8ce09a", + "inputs": [], + "outputs": [], + "input_path": null, + "result_path": null + } + ] + }, + "engine": "async", + "track_models": true, + "model_endpoints_names": [ + "my-endpoint" + ], + "shared_models_mechanism": { + "model-deployment": "naive" + } + }, + "build": { + "functionSourceCode": "IyBDb3B5cmlnaHQgMjAyNSBJZ3VhemlvCiMKIyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiMgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiMKIyAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAojCiMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQojIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiMgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAojIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgoKZnJvbSBtbHJ1bi5zZXJ2aW5nIGltcG9ydCBMTE1vZGVsCgoKY2xhc3MgTXlMTE0oTExNb2RlbCk6CiAgICBkZWYgcHJlZGljdChzZWxmLCBib2R5LCBtZXNzYWdlcywgbW9kZWxfY29uZmlndXJhdGlvbik6CiAgICAgICAgYm9keVsidXJsIl0gPSBzZWxmLm1vZGVsX2FydGlmYWN0Lm1vZGVsX3VybAogICAgICAgIGJvZHlbImRlZmF1bHRfY29uZmlnIl0gPSBzZWxmLm1vZGVsX2FydGlmYWN0LmRlZmF1bHRfY29uZmlnCiAgICAgICAgYm9keVsicHJvbXB0Il0gPSBtZXNzYWdlcwogICAgICAgIHJldHVybiBib2R5CmZyb20gbWxydW4ucnVudGltZXMgaW1wb3J0IG51Y2xpb19pbml0X2hvb2sKZGVmIGluaXRfY29udGV4dChjb250ZXh0KToKICAgIG51Y2xpb19pbml0X2hvb2soY29udGV4dCwgZ2xvYmFscygpLCAnc2VydmluZ192MicpCgpkZWYgaGFuZGxlcihjb250ZXh0LCBldmVudCk6CiAgICByZXR1cm4gY29udGV4dC5tbHJ1bl9oYW5kbGVyKGNvbnRleHQsIGV2ZW50KQoKZnJvbSBtbHJ1bi5zZXJ2aW5nLnN0YXRlcyBpbXBvcnQgTExNb2RlbAo=", + "code_origin": "./function_with_llm.py", + "origin_filename": "./function_with_llm.py", + "secret": "" + }, + "command": "http://default-function-with-llm.default-tenant.app.vmdev82.lab.iguazeng.com/", + "disable_auto_mount": true, + "priority_class_name": "igz-workload-medium", + "filename": "./function_with_llm.py", + "image": "mlrun/mlrun", + "node_selector": {}, + "env": [ + { + "name": "MLRUN_HTTPDB__NUCLIO__EXPLICIT_ACK", + "value": "enabled" + }, + { + "name": "V3IO_API", + "value": "v3io-webapi.default-tenant.svc:8081" + }, + { + "name": "V3IO_USERNAME", + "value": "normal-user" + }, + { + "name": "V3IO_FRAMESD", + "value": "framesd:8081" + }, + { + "name": "V3IO_ACCESS_KEY", + "valueFrom": { + "secretKeyRef": { + "key": "accessKey", + "name": "mlrun-auth-secrets.89488b129fafa22ca44076258f6b1cb249d3120f9c66d699ce6d4b68" + } + } + }, + { + "name": "MLRUN_AUTH_SESSION", + "valueFrom": { + "secretKeyRef": { + "key": "accessKey", + "name": "mlrun-auth-secrets.253c8a6e4c3595da61cbc90b60036ec928934dd6826298fcc3b5e3c3" + } + } + } + ], + "volumes": [ + { + "name": "serving-conf", + "configMap": { + "name": "serving-conf-default-function-with-llm" + } + } + ], + "affinity": null, + "resources": { + "requests": { + "memory": "1Mi", + "cpu": "25m" + }, + "limits": { + "memory": "20Gi", + "cpu": "2" + } + }, + "tolerations": null, + "track_models": true, + "volume_mounts": [ + { + "name": "serving-conf", + "mountPath": "/tmp/mlrun/serving-conf", + "readOnly": true + } + ] + }, + "verbose": false, + "status": { + "address": "default-function-with-llm.default-tenant.app.vmdev82.lab.iguazeng.com/", + "external_invocation_urls": [ + "default-function-with-llm.default-tenant.app.vmdev82.lab.iguazeng.com/" + ], + "nuclio_name": "default-function-with-llm", + "container_image": "docker-registry.default-tenant.app.vmdev82.lab.iguazeng.com:80/nuclio/default-default-function-with-llm-processor:latest", + "internal_invocation_urls": [ + "nuclio-default-function-with-llm.default-tenant.svc.cluster.local:8080" + ], + "state": "ready" + }, + "kind": "serving" + }, { "kind": "job", "metadata": { @@ -7828,26 +8026,26 @@ "verbose": false }, { - "kind": "serving", - "metadata": { + "kind": "serving", + "metadata": { "name": "model-monitoring-stream", "tag": "latest", "project": "default", "categories": [], "credentials": { - "access_key": "$ref:mlrun-auth-secrets.36ade9f8ae7bddc0fc42b8c701469b8d23268177977bd695c36ed51c" + "access_key": "$ref:mlrun-auth-secrets.36ade9f8ae7bddc0fc42b8c701469b8d23268177977bd695c36ed51c" }, "hash": "85957751e571a92e07213781f5e0c35bfbe42c64", "updated": "2022-07-04T06:37:28.324783+00:00" - }, - "spec": { + }, + "spec": { "command": "", "args": [], "image": "mlrun/mlrun", "build": { - "commands": [], - "code_origin": "/mlrun/mlrun/model_monitoring/stream_processing_fs.py", - "origin_filename": "/mlrun/mlrun/model_monitoring/stream_processing_fs.py" + "commands": [], + "code_origin": "/mlrun/mlrun/model_monitoring/stream_processing_fs.py", + "origin_filename": "/mlrun/mlrun/model_monitoring/stream_processing_fs.py" }, "description": "", "default_handler": "", @@ -7855,657 +8053,657 @@ "volumes": [], "volume_mounts": [], "env": [ - { - "name": "MODEL_MONITORING_ACCESS_KEY", - "valueFrom": { - "secretKeyRef": { - "key": "mlrun.model-monitoring.MODEL_MONITORING_ACCESS_KEY", - "name": "mlrun-project-secrets-default" - } - } + { + "name": "MODEL_MONITORING_ACCESS_KEY", + "valueFrom": { + "secretKeyRef": { + "key": "mlrun.model-monitoring.MODEL_MONITORING_ACCESS_KEY", + "name": "mlrun-project-secrets-default" + } + } + }, + { + "name": "V3IO_API", + "value": "http://v3io-webapi:8081" + }, + { + "name": "V3IO_USERNAME", + "value": "pipelines" + }, + { + "name": "V3IO_ACCESS_KEY", + "valueFrom": { + "secretKeyRef": { + "key": "accessKey", + "name": "mlrun-auth-secrets.27111631aff0f77b2ca9e3f972065f482a58b63645f0afd8d231028f" + } + } + }, + { + "name": "V3IO_FRAMESD", + "value": "http://framesd:8080" + }, + { + "name": "MLRUN_AUTH_SESSION", + "valueFrom": { + "secretKeyRef": { + "key": "accessKey", + "name": "mlrun-auth-secrets.36ade9f8ae7bddc0fc42b8c701469b8d23268177977bd695c36ed51c" + } + } + }, + { + "name": "MLRUN_K8S_SECRET__AZURE_RESOURCE_GROUP", + "valueFrom": { + "secretKeyRef": { + "key": "AZURE_RESOURCE_GROUP", + "name": "mlrun-project-secrets-azureml-admin" + } + } + }, + { + "name": "MLRUN_K8S_SECRET__AZURE_SERVICE_PRINCIPAL_ID", + "valueFrom": { + "secretKeyRef": { + "key": "AZURE_SERVICE_PRINCIPAL_ID", + "name": "mlrun-project-secrets-azureml-admin" + } + } + }, + { + "name": "MLRUN_K8S_SECRET__AZURE_SERVICE_PRINCIPAL_PASSWORD", + "valueFrom": { + "secretKeyRef": { + "key": "AZURE_SERVICE_PRINCIPAL_PASSWORD", + "name": "mlrun-project-secrets-azureml-admin" + } + } + }, + { + "name": "MLRUN_K8S_SECRET__AZURE_STORAGE_CONNECTION_STRING", + "valueFrom": { + "secretKeyRef": { + "key": "AZURE_STORAGE_CONNECTION_STRING", + "name": "mlrun-project-secrets-azureml-admin" + } + } + }, + { + "name": "MLRUN_K8S_SECRET__AZURE_SUBSCRIPTION_ID", + "valueFrom": { + "secretKeyRef": { + "key": "AZURE_SUBSCRIPTION_ID", + "name": "mlrun-project-secrets-azureml-admin" + } + } + }, + { + "name": "MLRUN_K8S_SECRET__AZURE_TENANT_ID", + "valueFrom": { + "secretKeyRef": { + "key": "AZURE_TENANT_ID", + "name": "mlrun-project-secrets-azureml-admin" + } + } + }, + { + "name": "MLRUN_K8S_SECRET__AZURE_WORKSPACE_NAME", + "valueFrom": { + "secretKeyRef": { + "key": "AZURE_WORKSPACE_NAME", + "name": "mlrun-project-secrets-azureml-admin" + } + } + } + ], + "resources": { + "requests": { + "memory": "1Mi", + "cpu": "25m" + }, + "limits": { + "memory": "20Gi", + "cpu": "2" + } + }, + "priority_class_name": "igz-workload-medium", + "preemption_mode": "prevent", + "min_replicas": 1, + "max_replicas": 1, + "config": { + "spec.triggers.monitoring_stream_trigger": { + "kind": "v3ioStream", + "url": "http://v3io-webapi:8081", + "attributes": { + "containerName": "users", + "streamPath": "pipelines/default/model-endpoints/stream", + "consumerGroup": "serving", + "sequenceNumberCommitInterval": "1s", + "workerAllocationMode": "pool", + "sessionTimeout": "10s", + "heartbeatInterval": "3s", + "seekTo": "earliest", + "readBatchSize": 256, + "pollingIntervalMs": 500 }, - { + "name": "monitoring_stream_trigger", + "maxWorkers": 1, + "password": "76ceea19-4b10-47d9-afbb-f687c91b9231" + }, + "metadata.labels.mlrun/class": "serving", + "spec.runtime": "python:3.7", + "spec.serviceType": "ClusterIP", + "spec.resources": { + "requests": { + "memory": "1Mi", + "cpu": "25m" + }, + "limits": { + "memory": "20Gi", + "cpu": "2" + } + }, + "spec.PreemptionMode": "prevent", + "spec.priorityClassName": "igz-workload-medium", + "spec.minReplicas": 1, + "spec.maxReplicas": 1 + }, + "base_spec": { + "apiVersion": "nuclio.io/v1", + "kind": "Function", + "metadata": { + "name": "default-model-monitoring-stream", + "labels": { + "mlrun/class": "serving", + "nuclio.io/project-name": "default" + }, + "annotations": { + "nuclio.io/generated_by": "function generated from /mlrun/mlrun/model_monitoring/stream_processing_fs.py" + } + }, + "spec": { + "runtime": "python:3.7", + "handler": "stream_processing_fs:handler", + "env": [ + { "name": "V3IO_API", "value": "http://v3io-webapi:8081" - }, - { + }, + { "name": "V3IO_USERNAME", "value": "pipelines" - }, - { - "name": "V3IO_ACCESS_KEY", - "valueFrom": { - "secretKeyRef": { - "key": "accessKey", - "name": "mlrun-auth-secrets.27111631aff0f77b2ca9e3f972065f482a58b63645f0afd8d231028f" - } - } - }, - { + }, + { "name": "V3IO_FRAMESD", "value": "http://framesd:8080" - }, - { + }, + { + "name": "MLRUN_DEFAULT_PROJECT", + "value": "azureml-admin" + }, + { + "name": "MLRUN_DBPATH", + "value": "http://mlrun-api:8080" + }, + { + "name": "MLRUN_NAMESPACE", + "value": "default-tenant" + }, + { "name": "MLRUN_AUTH_SESSION", "valueFrom": { - "secretKeyRef": { - "key": "accessKey", - "name": "mlrun-auth-secrets.36ade9f8ae7bddc0fc42b8c701469b8d23268177977bd695c36ed51c" - } + "secretKeyRef": { + "key": "accessKey", + "name": "mlrun-auth-secrets.36ade9f8ae7bddc0fc42b8c701469b8d23268177977bd695c36ed51c" + } } - }, - { + }, + { + "name": "SERVING_SPEC_ENV", + "value": "{\"function_uri\": \"azureml-admin/model-monitoring-stream\", \"version\": \"v2\", \"parameters\": {\"infer_options\": 0, \"overwrite\": null, \"featureset\": \"store://feature-sets/azureml-admin/monitoring\", \"source\": {\"kind\": \"http\", \"online\": true}, \"targets\": [{\"name\": \"parquet\", \"kind\": \"parquet\", \"path\": \"v3io:///projects/azureml-admin/model-endpoints/parquet\", \"after_step\": \"ProcessBeforeParquet\", \"attributes\": {\"infer_columns_from_data\": true}, \"partitioned\": true, \"key_bucketing_number\": 0, \"time_partitioning_granularity\": \"hour\", \"max_events\": 10000, \"flush_after_seconds\": 1800, \"storage_options\": {\"v3io_access_key\": \"55a0d13c-7d9a-44ab-a556-dd213d8c7165\", \"v3io_api\": \"http://v3io-webapi:8081\"}}]}, \"graph\": {\"steps\": {\"ProcessEndpointEvent\": {\"kind\": \"task\", \"class_name\": \"ProcessEndpointEvent\", \"class_args\": {\"kv_container\": \"users\", \"kv_path\": \"pipelines/azureml-admin/model-endpoints/endpoints/\", \"v3io_access_key\": \"76ceea19-4b10-47d9-afbb-f687c91b9231\"}, \"full_event\": true}, \"filter_none\": {\"kind\": \"task\", \"class_name\": \"storey.Filter\", \"class_args\": {\"_fn\": \"(event is not None)\"}, \"after\": [\"ProcessEndpointEvent\"]}, \"flatten_events\": {\"kind\": \"task\", \"class_name\": \"storey.FlatMap\", \"class_args\": {\"_fn\": \"(event)\"}, \"after\": [\"filter_none\"]}, \"MapFeatureNames\": {\"kind\": \"task\", \"class_name\": \"MapFeatureNames\", \"class_args\": {\"kv_container\": \"users\", \"kv_path\": \"pipelines/azureml-admin/model-endpoints/endpoints/\", \"access_key\": \"76ceea19-4b10-47d9-afbb-f687c91b9231\", \"infer_columns_from_data\": true}, \"after\": [\"flatten_events\"]}, \"Aggregates\": {\"kind\": \"task\", \"class_name\": \"storey.AggregateByKey\", \"class_args\": {\"aggregates\": [{\"name\": \"predictions\", \"column\": \"endpoint_id\", \"operations\": [\"count\"], \"windows\": [\"5m\", \"1h\"], \"period\": \"30s\"}, {\"name\": \"latency\", \"column\": \"latency\", \"operations\": [\"avg\"], \"windows\": [\"5m\", \"1h\"], \"period\": \"30s\"}], \"table\": \".\"}, \"after\": [\"MapFeatureNames\"]}, \"sample\": {\"kind\": \"task\", \"class_name\": \"storey.steps.SampleWindow\", \"class_args\": {\"window_size\": 10, \"key\": \"endpoint_id\"}, \"after\": [\"Aggregates\"]}, \"ProcessBeforeKV\": {\"kind\": \"task\", \"class_name\": \"ProcessBeforeKV\", \"after\": [\"sample\"]}, \"WriteToKV\": {\"kind\": \"task\", \"class_name\": \"WriteToKV\", \"class_args\": {\"container\": \"users\", \"table\": \"pipelines/azureml-admin/model-endpoints/endpoints/\"}, \"after\": [\"ProcessBeforeKV\"]}, \"InferSchema\": {\"kind\": \"task\", \"class_name\": \"InferSchema\", \"class_args\": {\"v3io_access_key\": \"76ceea19-4b10-47d9-afbb-f687c91b9231\", \"v3io_framesd\": \"http://framesd:8080\", \"container\": \"users\", \"table\": \"pipelines/azureml-admin/model-endpoints/endpoints/\"}, \"after\": [\"WriteToKV\"]}, \"ProcessBeforeTSDB\": {\"kind\": \"task\", \"class_name\": \"ProcessBeforeTSDB\", \"after\": [\"sample\"]}, \"FilterAndUnpackKeys1\": {\"kind\": \"task\", \"class_name\": \"FilterAndUnpackKeys\", \"class_args\": {\"keys\": [\"base_metrics\"]}, \"after\": [\"ProcessBeforeTSDB\"]}, \"tsdb1\": {\"kind\": \"task\", \"class_name\": \"storey.TSDBTarget\", \"class_args\": {\"path\": \"users/pipelines/azureml-admin/model-endpoints/events/\", \"rate\": \"10/m\", \"time_col\": \"timestamp\", \"container\": \"users\", \"access_key\": \"76ceea19-4b10-47d9-afbb-f687c91b9231\", \"v3io_frames\": \"http://framesd:8080\", \"index_cols\": [\"endpoint_id\", \"record_type\"], \"max_events\": 10, \"timeout_secs\": 300, \"key\": \"endpoint_id\"}, \"after\": [\"FilterAndUnpackKeys1\"]}, \"FilterAndUnpackKeys2\": {\"kind\": \"task\", \"class_name\": \"FilterAndUnpackKeys\", \"class_args\": {\"keys\": [\"endpoint_features\"]}, \"after\": [\"ProcessBeforeTSDB\"]}, \"tsdb2\": {\"kind\": \"task\", \"class_name\": \"storey.TSDBTarget\", \"class_args\": {\"path\": \"users/pipelines/azureml-admin/model-endpoints/events/\", \"rate\": \"10/m\", \"time_col\": \"timestamp\", \"container\": \"users\", \"access_key\": \"76ceea19-4b10-47d9-afbb-f687c91b9231\", \"v3io_frames\": \"http://framesd:8080\", \"index_cols\": [\"endpoint_id\", \"record_type\"], \"max_events\": 10, \"timeout_secs\": 300, \"key\": \"endpoint_id\"}, \"after\": [\"FilterAndUnpackKeys2\"]}, \"FilterAndUnpackKeys3\": {\"kind\": \"task\", \"class_name\": \"FilterAndUnpackKeys\", \"class_args\": {\"keys\": [\"custom_metrics\"]}, \"after\": [\"ProcessBeforeTSDB\"]}, \"FilterNotNone\": {\"kind\": \"task\", \"class_name\": \"storey.Filter\", \"class_args\": {\"_fn\": \"(event is not None)\"}, \"after\": [\"FilterAndUnpackKeys3\"]}, \"tsdb3\": {\"kind\": \"task\", \"class_name\": \"storey.TSDBTarget\", \"class_args\": {\"path\": \"users/pipelines/azureml-admin/model-endpoints/events/\", \"rate\": \"10/m\", \"time_col\": \"timestamp\", \"container\": \"users\", \"access_key\": \"76ceea19-4b10-47d9-afbb-f687c91b9231\", \"v3io_frames\": \"http://framesd:8080\", \"index_cols\": [\"endpoint_id\", \"record_type\"], \"max_events\": 10, \"timeout_secs\": 300, \"key\": \"endpoint_id\"}, \"after\": [\"FilterNotNone\"]}, \"ProcessBeforeParquet\": {\"kind\": \"task\", \"class_name\": \"ProcessBeforeParquet\", \"class_args\": {\"_fn\": \"(event)\"}, \"after\": [\"MapFeatureNames\"]}}, \"final_step\": \"ProcessBeforeParquet\"}, \"load_mode\": null, \"functions\": {}, \"graph_initializer\": \"mlrun.feature_store.ingestion.featureset_initializer\", \"error_stream\": null, \"track_models\": null, \"default_content_type\": null}" + }, + { + "name": "MODEL_MONITORING_ACCESS_KEY", + "valueFrom": { + "secretKeyRef": { + "key": "mlrun.model-monitoring.MODEL_MONITORING_ACCESS_KEY", + "name": "mlrun-project-secrets-default" + } + } + }, + { + "name": "V3IO_ACCESS_KEY", + "valueFrom": { + "secretKeyRef": { + "key": "accessKey", + "name": "mlrun-auth-secrets.27111631aff0f77b2ca9e3f972065f482a58b63645f0afd8d231028f" + } + } + }, + { "name": "MLRUN_K8S_SECRET__AZURE_RESOURCE_GROUP", "valueFrom": { - "secretKeyRef": { - "key": "AZURE_RESOURCE_GROUP", - "name": "mlrun-project-secrets-azureml-admin" - } + "secretKeyRef": { + "key": "AZURE_RESOURCE_GROUP", + "name": "mlrun-project-secrets-default" + } } - }, - { + }, + { "name": "MLRUN_K8S_SECRET__AZURE_SERVICE_PRINCIPAL_ID", "valueFrom": { - "secretKeyRef": { - "key": "AZURE_SERVICE_PRINCIPAL_ID", - "name": "mlrun-project-secrets-azureml-admin" - } + "secretKeyRef": { + "key": "AZURE_SERVICE_PRINCIPAL_ID", + "name": "mlrun-project-secrets-default" + } } - }, - { + }, + { "name": "MLRUN_K8S_SECRET__AZURE_SERVICE_PRINCIPAL_PASSWORD", "valueFrom": { - "secretKeyRef": { - "key": "AZURE_SERVICE_PRINCIPAL_PASSWORD", - "name": "mlrun-project-secrets-azureml-admin" - } + "secretKeyRef": { + "key": "AZURE_SERVICE_PRINCIPAL_PASSWORD", + "name": "mlrun-project-secrets-default" + } } - }, - { + }, + { "name": "MLRUN_K8S_SECRET__AZURE_STORAGE_CONNECTION_STRING", "valueFrom": { - "secretKeyRef": { - "key": "AZURE_STORAGE_CONNECTION_STRING", - "name": "mlrun-project-secrets-azureml-admin" - } + "secretKeyRef": { + "key": "AZURE_STORAGE_CONNECTION_STRING", + "name": "mlrun-project-secrets-default" + } } - }, - { + }, + { "name": "MLRUN_K8S_SECRET__AZURE_SUBSCRIPTION_ID", "valueFrom": { - "secretKeyRef": { - "key": "AZURE_SUBSCRIPTION_ID", - "name": "mlrun-project-secrets-azureml-admin" - } + "secretKeyRef": { + "key": "AZURE_SUBSCRIPTION_ID", + "name": "mlrun-project-secrets-default" + } } - }, - { + }, + { "name": "MLRUN_K8S_SECRET__AZURE_TENANT_ID", "valueFrom": { - "secretKeyRef": { - "key": "AZURE_TENANT_ID", - "name": "mlrun-project-secrets-azureml-admin" - } + "secretKeyRef": { + "key": "AZURE_TENANT_ID", + "name": "mlrun-project-secrets-default" + } } - }, - { + }, + { "name": "MLRUN_K8S_SECRET__AZURE_WORKSPACE_NAME", "valueFrom": { - "secretKeyRef": { - "key": "AZURE_WORKSPACE_NAME", - "name": "mlrun-project-secrets-azureml-admin" - } + "secretKeyRef": { + "key": "AZURE_WORKSPACE_NAME", + "name": "mlrun-project-secrets-default" + } } - } - ], - "resources": { - "requests": { - "memory": "1Mi", - "cpu": "25m" + } + ], + "volumes": [], + "build": { + "commands": [], + "noBaseImagesPull": true, + "functionSourceCode": "aW1wb3J0IGpzb24KaW1wb3J0IG9zCmZyb20gY29sbGVjdGlvbnMgaW1wb3J0IGRlZmF1bHRkaWN0CmZyb20gb3MgaW1wb3J0IGVudmlyb24KZnJvbSB0eXBpbmcgaW1wb3J0IEFueSwgRGljdCwgTGlzdCwgT3B0aW9uYWwsIFNldCwgVW5pb24KCmltcG9ydCBwYW5kYXMgYXMgcGQKaW1wb3J0IHYzaW8KCiMgQ29uc3RhbnRzCmZyb20gc3RvcmV5IGltcG9ydCBFdmVudApmcm9tIHYzaW8uZGF0YXBsYW5lIGltcG9ydCBSYWlzZUZvclN0YXR1cwoKaW1wb3J0IG1scnVuLmZlYXR1cmVfc3RvcmUgYXMgZnMKZnJvbSBtbHJ1bi5jb25maWcgaW1wb3J0IGNvbmZpZwpmcm9tIG1scnVuLmRhdGFzdG9yZS50YXJnZXRzIGltcG9ydCBQYXJxdWV0VGFyZ2V0CmZyb20gbWxydW4uZmVhdHVyZV9zdG9yZS5zdGVwcyBpbXBvcnQgTWFwQ2xhc3MKZnJvbSBtbHJ1bi51dGlscyBpbXBvcnQgbG9nZ2VyCmZyb20gbWxydW4udXRpbHMubW9kZWxfbW9uaXRvcmluZyBpbXBvcnQgKAogICAgY3JlYXRlX21vZGVsX2VuZHBvaW50X2lkLAogICAgcGFyc2VfbW9kZWxfZW5kcG9pbnRfc3RvcmVfcHJlZml4LAopCmZyb20gbWxydW4udXRpbHMudjNpb19jbGllbnRzIGltcG9ydCBnZXRfZnJhbWVzX2NsaWVudCwgZ2V0X3YzaW9fY2xpZW50CgpJU09fODA2MV9VVEMgPSAiJVktJW0tJWQgJUg6JU06JVMuJWYleiIKRlVOQ1RJT05fVVJJID0gImZ1bmN0aW9uX3VyaSIKTU9ERUwgPSAibW9kZWwiClZFUlNJT04gPSAidmVyc2lvbiIKVkVSU0lPTkVEX01PREVMID0gInZlcnNpb25lZF9tb2RlbCIKTU9ERUxfQ0xBU1MgPSAibW9kZWxfY2xhc3MiClRJTUVTVEFNUCA9ICJ0aW1lc3RhbXAiCkVORFBPSU5UX0lEID0gImVuZHBvaW50X2lkIgpSRVFVRVNUX0lEID0gInJlcXVlc3RfaWQiCkxBQkVMUyA9ICJsYWJlbHMiClVOUEFDS0VEX0xBQkVMUyA9ICJ1bnBhY2tlZF9sYWJlbHMiCkxBVEVOQ1lfQVZHXzVNID0gImxhdGVuY3lfYXZnXzVtIgpMQVRFTkNZX0FWR18xSCA9ICJsYXRlbmN5X2F2Z18xaCIKUFJFRElDVElPTlNfUEVSX1NFQ09ORCA9ICJwcmVkaWN0aW9uc19wZXJfc2Vjb25kIgpQUkVESUNUSU9OU19DT1VOVF81TSA9ICJwcmVkaWN0aW9uc19jb3VudF81bSIKUFJFRElDVElPTlNfQ09VTlRfMUggPSAicHJlZGljdGlvbnNfY291bnRfMWgiCkZJUlNUX1JFUVVFU1QgPSAiZmlyc3RfcmVxdWVzdCIKTEFTVF9SRVFVRVNUID0gImxhc3RfcmVxdWVzdCIKRVJST1JfQ09VTlQgPSAiZXJyb3JfY291bnQiCkVOVElUSUVTID0gImVudGl0aWVzIgpGRUFUVVJFX05BTUVTID0gImZlYXR1cmVfbmFtZXMiCkxBQkVMX0NPTFVNTlMgPSAibGFiZWxfY29sdW1ucyIKTEFURU5DWSA9ICJsYXRlbmN5IgpSRUNPUkRfVFlQRSA9ICJyZWNvcmRfdHlwZSIKRkVBVFVSRVMgPSAiZmVhdHVyZXMiClBSRURJQ1RJT04gPSAicHJlZGljdGlvbiIKUFJFRElDVElPTlMgPSAicHJlZGljdGlvbnMiCk5BTUVEX0ZFQVRVUkVTID0gIm5hbWVkX2ZlYXR1cmVzIgpOQU1FRF9QUkVESUNUSU9OUyA9ICJuYW1lZF9wcmVkaWN0aW9ucyIKQkFTRV9NRVRSSUNTID0gImJhc2VfbWV0cmljcyIKQ1VTVE9NX01FVFJJQ1MgPSAiY3VzdG9tX21ldHJpY3MiCkVORFBPSU5UX0ZFQVRVUkVTID0gImVuZHBvaW50X2ZlYXR1cmVzIgpNRVRSSUNTID0gIm1ldHJpY3MiCkJBVENIX1RJTUVTVEFNUCA9ICJiYXRjaF90aW1lc3RhbXAiClRJTUVfRk9STUFUOiBzdHIgPSAiJVktJW0tJWQgJUg6JU06JVMuJWYiICAjIElTTyA4MDYxCgoKIyBTdHJlYW0gcHJvY2Vzc2luZyBjb2RlCmNsYXNzIEV2ZW50U3RyZWFtUHJvY2Vzc29yOgogICAgZGVmIF9faW5pdF9fKAogICAgICAgIHNlbGYsCiAgICAgICAgcHJvamVjdDogc3RyLAogICAgICAgIHBhcnF1ZXRfYmF0Y2hpbmdfbWF4X2V2ZW50czogaW50LAogICAgICAgIHNhbXBsZV93aW5kb3c6IGludCA9IDEwLAogICAgICAgIHRzZGJfYmF0Y2hpbmdfbWF4X2V2ZW50czogaW50ID0gMTAsCiAgICAgICAgdHNkYl9iYXRjaGluZ190aW1lb3V0X3NlY3M6IGludCA9IDYwICogNSwgICMgRGVmYXVsdCA1IG1pbnV0ZXMKICAgICAgICBwYXJxdWV0X2JhdGNoaW5nX3RpbWVvdXRfc2VjczogaW50ID0gMzAgKiA2MCwgICMgRGVmYXVsdCAzMCBtaW51dGVzCiAgICAgICAgYWdncmVnYXRlX2NvdW50X3dpbmRvd3M6IE9wdGlvbmFsW0xpc3Rbc3RyXV0gPSBOb25lLAogICAgICAgIGFnZ3JlZ2F0ZV9jb3VudF9wZXJpb2Q6IHN0ciA9ICIzMHMiLAogICAgICAgIGFnZ3JlZ2F0ZV9hdmdfd2luZG93czogT3B0aW9uYWxbTGlzdFtzdHJdXSA9IE5vbmUsCiAgICAgICAgYWdncmVnYXRlX2F2Z19wZXJpb2Q6IHN0ciA9ICIzMHMiLAogICAgICAgIHYzaW9fYWNjZXNzX2tleTogT3B0aW9uYWxbc3RyXSA9IE5vbmUsCiAgICAgICAgdjNpb19mcmFtZXNkOiBPcHRpb25hbFtzdHJdID0gTm9uZSwKICAgICAgICB2M2lvX2FwaTogT3B0aW9uYWxbc3RyXSA9IE5vbmUsCiAgICAgICAgbW9kZWxfbW9uaXRvcmluZ19hY2Nlc3Nfa2V5OiBzdHIgPSBOb25lLAogICAgKToKICAgICAgICBzZWxmLnByb2plY3QgPSBwcm9qZWN0CiAgICAgICAgc2VsZi5zYW1wbGVfd2luZG93ID0gc2FtcGxlX3dpbmRvdwogICAgICAgIHNlbGYudHNkYl9iYXRjaGluZ19tYXhfZXZlbnRzID0gdHNkYl9iYXRjaGluZ19tYXhfZXZlbnRzCiAgICAgICAgc2VsZi50c2RiX2JhdGNoaW5nX3RpbWVvdXRfc2VjcyA9IHRzZGJfYmF0Y2hpbmdfdGltZW91dF9zZWNzCiAgICAgICAgc2VsZi5wYXJxdWV0X2JhdGNoaW5nX21heF9ldmVudHMgPSBwYXJxdWV0X2JhdGNoaW5nX21heF9ldmVudHMKICAgICAgICBzZWxmLnBhcnF1ZXRfYmF0Y2hpbmdfdGltZW91dF9zZWNzID0gcGFycXVldF9iYXRjaGluZ190aW1lb3V0X3NlY3MKICAgICAgICBzZWxmLmFnZ3JlZ2F0ZV9jb3VudF93aW5kb3dzID0gYWdncmVnYXRlX2NvdW50X3dpbmRvd3Mgb3IgWyI1bSIsICIxaCJdCiAgICAgICAgc2VsZi5hZ2dyZWdhdGVfY291bnRfcGVyaW9kID0gYWdncmVnYXRlX2NvdW50X3BlcmlvZAogICAgICAgIHNlbGYuYWdncmVnYXRlX2F2Z193aW5kb3dzID0gYWdncmVnYXRlX2F2Z193aW5kb3dzIG9yIFsiNW0iLCAiMWgiXQogICAgICAgIHNlbGYuYWdncmVnYXRlX2F2Z19wZXJpb2QgPSBhZ2dyZWdhdGVfYXZnX3BlcmlvZAoKICAgICAgICBzZWxmLnYzaW9fZnJhbWVzZCA9IHYzaW9fZnJhbWVzZCBvciBjb25maWcudjNpb19mcmFtZXNkCiAgICAgICAgc2VsZi52M2lvX2FwaSA9IHYzaW9fYXBpIG9yIGNvbmZpZy52M2lvX2FwaQoKICAgICAgICBzZWxmLnYzaW9fYWNjZXNzX2tleSA9IHYzaW9fYWNjZXNzX2tleSBvciBlbnZpcm9uLmdldCgiVjNJT19BQ0NFU1NfS0VZIikKICAgICAgICBzZWxmLm1vZGVsX21vbml0b3JpbmdfYWNjZXNzX2tleSA9ICgKICAgICAgICAgICAgbW9kZWxfbW9uaXRvcmluZ19hY2Nlc3Nfa2V5CiAgICAgICAgICAgIG9yIG9zLmVudmlyb24uZ2V0KCJNT0RFTF9NT05JVE9SSU5HX0FDQ0VTU19LRVkiKQogICAgICAgICAgICBvciBzZWxmLnYzaW9fYWNjZXNzX2tleQogICAgICAgICkKCiAgICAgICAgdGVtcGxhdGUgPSBjb25maWcubW9kZWxfZW5kcG9pbnRfbW9uaXRvcmluZy5zdG9yZV9wcmVmaXhlcy5kZWZhdWx0CgogICAgICAgIGt2X3BhdGggPSB0ZW1wbGF0ZS5mb3JtYXQocHJvamVjdD1wcm9qZWN0LCBraW5kPSJlbmRwb2ludHMiKQogICAgICAgIF8sIHNlbGYua3ZfY29udGFpbmVyLCBzZWxmLmt2X3BhdGggPSBwYXJzZV9tb2RlbF9lbmRwb2ludF9zdG9yZV9wcmVmaXgoa3ZfcGF0aCkKCiAgICAgICAgdHNkYl9wYXRoID0gdGVtcGxhdGUuZm9ybWF0KHByb2plY3Q9cHJvamVjdCwga2luZD0iZXZlbnRzIikKICAgICAgICBfLCBzZWxmLnRzZGJfY29udGFpbmVyLCBzZWxmLnRzZGJfcGF0aCA9IHBhcnNlX21vZGVsX2VuZHBvaW50X3N0b3JlX3ByZWZpeCgKICAgICAgICAgICAgdHNkYl9wYXRoCiAgICAgICAgKQogICAgICAgIHNlbGYudHNkYl9wYXRoID0gZiJ7c2VsZi50c2RiX2NvbnRhaW5lcn0ve3NlbGYudHNkYl9wYXRofSIKCiAgICAgICAgc2VsZi5wYXJxdWV0X3BhdGggPSAoCiAgICAgICAgICAgIGNvbmZpZy5tb2RlbF9lbmRwb2ludF9tb25pdG9yaW5nLnN0b3JlX3ByZWZpeGVzLnVzZXJfc3BhY2UuZm9ybWF0KAogICAgICAgICAgICAgICAgcHJvamVjdD1wcm9qZWN0LCBraW5kPSJwYXJxdWV0IgogICAgICAgICAgICApCiAgICAgICAgKQoKICAgICAgICBsb2dnZXIuaW5mbygKICAgICAgICAgICAgIkluaXRpYWxpemluZyBtb2RlbCBtb25pdG9yaW5nIGV2ZW50IHN0cmVhbSBwcm9jZXNzb3IiLAogICAgICAgICAgICBwYXJxdWV0X2JhdGNoaW5nX21heF9ldmVudHM9c2VsZi5wYXJxdWV0X2JhdGNoaW5nX21heF9ldmVudHMsCiAgICAgICAgICAgIHYzaW9fYWNjZXNzX2tleT1zZWxmLnYzaW9fYWNjZXNzX2tleSwKICAgICAgICAgICAgbW9kZWxfbW9uaXRvcmluZ19hY2Nlc3Nfa2V5PXNlbGYubW9kZWxfbW9uaXRvcmluZ19hY2Nlc3Nfa2V5LAogICAgICAgICAgICBkZWZhdWx0X3N0b3JlX3ByZWZpeD1jb25maWcubW9kZWxfZW5kcG9pbnRfbW9uaXRvcmluZy5zdG9yZV9wcmVmaXhlcy5kZWZhdWx0LAogICAgICAgICAgICB1c2VyX3NwYWNlX3N0b3JlX3ByZWZpeD1jb25maWcubW9kZWxfZW5kcG9pbnRfbW9uaXRvcmluZy5zdG9yZV9wcmVmaXhlcy51c2VyX3NwYWNlLAogICAgICAgICAgICB2M2lvX2FwaT1zZWxmLnYzaW9fYXBpLAogICAgICAgICAgICB2M2lvX2ZyYW1lc2Q9c2VsZi52M2lvX2ZyYW1lc2QsCiAgICAgICAgICAgIGt2X2NvbnRhaW5lcj1zZWxmLmt2X2NvbnRhaW5lciwKICAgICAgICAgICAga3ZfcGF0aD1zZWxmLmt2X3BhdGgsCiAgICAgICAgICAgIHRzZGJfY29udGFpbmVyPXNlbGYudHNkYl9jb250YWluZXIsCiAgICAgICAgICAgIHRzZGJfcGF0aD1zZWxmLnRzZGJfcGF0aCwKICAgICAgICAgICAgcGFycXVldF9wYXRoPXNlbGYucGFycXVldF9wYXRoLAogICAgICAgICkKCiAgICBkZWYgY3JlYXRlX2ZlYXR1cmVfc2V0KHNlbGYpOgogICAgICAgIGZlYXR1cmVfc2V0ID0gZnMuRmVhdHVyZVNldCgKICAgICAgICAgICAgIm1vbml0b3JpbmciLCBlbnRpdGllcz1bRU5EUE9JTlRfSURdLCB0aW1lc3RhbXBfa2V5PVRJTUVTVEFNUAogICAgICAgICkKICAgICAgICBmZWF0dXJlX3NldC5tZXRhZGF0YS5wcm9qZWN0ID0gc2VsZi5wcm9qZWN0CiAgICAgICAgZmVhdHVyZV9zZXQuZ3JhcGgudG8oCiAgICAgICAgICAgICJQcm9jZXNzRW5kcG9pbnRFdmVudCIsCiAgICAgICAgICAgIGt2X2NvbnRhaW5lcj1zZWxmLmt2X2NvbnRhaW5lciwKICAgICAgICAgICAga3ZfcGF0aD1zZWxmLmt2X3BhdGgsCiAgICAgICAgICAgIHYzaW9fYWNjZXNzX2tleT1zZWxmLnYzaW9fYWNjZXNzX2tleSwKICAgICAgICAgICAgZnVsbF9ldmVudD1UcnVlLAogICAgICAgICkudG8oInN0b3JleS5GaWx0ZXIiLCAiZmlsdGVyX25vbmUiLCBfZm49IihldmVudCBpcyBub3QgTm9uZSkiKS50bygKICAgICAgICAgICAgInN0b3JleS5GbGF0TWFwIiwgImZsYXR0ZW5fZXZlbnRzIiwgX2ZuPSIoZXZlbnQpIgogICAgICAgICkudG8oCiAgICAgICAgICAgICJNYXBGZWF0dXJlTmFtZXMiLAogICAgICAgICAgICBuYW1lPSJNYXBGZWF0dXJlTmFtZXMiLAogICAgICAgICAgICBrdl9jb250YWluZXI9c2VsZi5rdl9jb250YWluZXIsCiAgICAgICAgICAgIGt2X3BhdGg9c2VsZi5rdl9wYXRoLAogICAgICAgICAgICBhY2Nlc3Nfa2V5PXNlbGYudjNpb19hY2Nlc3Nfa2V5LAogICAgICAgICAgICBpbmZlcl9jb2x1bW5zX2Zyb21fZGF0YT1UcnVlLAogICAgICAgICkKICAgICAgICAjIGt2IGFuZCB0c2RiIGJyYW5jaAogICAgICAgIGZlYXR1cmVfc2V0LmFkZF9hZ2dyZWdhdGlvbigKICAgICAgICAgICAgRU5EUE9JTlRfSUQsCiAgICAgICAgICAgIFsiY291bnQiXSwKICAgICAgICAgICAgc2VsZi5hZ2dyZWdhdGVfY291bnRfd2luZG93cywKICAgICAgICAgICAgc2VsZi5hZ2dyZWdhdGVfY291bnRfcGVyaW9kLAogICAgICAgICAgICBuYW1lPVBSRURJQ1RJT05TLAogICAgICAgICAgICBhZnRlcj0iTWFwRmVhdHVyZU5hbWVzIiwKICAgICAgICAgICAgc3RlcF9uYW1lPSJBZ2dyZWdhdGVzIiwKICAgICAgICApCiAgICAgICAgZmVhdHVyZV9zZXQuYWRkX2FnZ3JlZ2F0aW9uKAogICAgICAgICAgICBMQVRFTkNZLAogICAgICAgICAgICBbImF2ZyJdLAogICAgICAgICAgICBzZWxmLmFnZ3JlZ2F0ZV9hdmdfd2luZG93cywKICAgICAgICAgICAgc2VsZi5hZ2dyZWdhdGVfYXZnX3BlcmlvZCwKICAgICAgICApCiAgICAgICAgZmVhdHVyZV9zZXQuZ3JhcGguYWRkX3N0ZXAoCiAgICAgICAgICAgICJzdG9yZXkuc3RlcHMuU2FtcGxlV2luZG93IiwKICAgICAgICAgICAgbmFtZT0ic2FtcGxlIiwKICAgICAgICAgICAgYWZ0ZXI9IkFnZ3JlZ2F0ZXMiLAogICAgICAgICAgICB3aW5kb3dfc2l6ZT1zZWxmLnNhbXBsZV93aW5kb3csCiAgICAgICAgICAgIGtleT1FTkRQT0lOVF9JRCwKICAgICAgICApCiAgICAgICAgIyBrdgogICAgICAgIGZlYXR1cmVfc2V0LmdyYXBoLmFkZF9zdGVwKAogICAgICAgICAgICAiUHJvY2Vzc0JlZm9yZUtWIiwgbmFtZT0iUHJvY2Vzc0JlZm9yZUtWIiwgYWZ0ZXI9InNhbXBsZSIKICAgICAgICApCiAgICAgICAgZmVhdHVyZV9zZXQuZ3JhcGguYWRkX3N0ZXAoCiAgICAgICAgICAgICJXcml0ZVRvS1YiLAogICAgICAgICAgICBuYW1lPSJXcml0ZVRvS1YiLAogICAgICAgICAgICBhZnRlcj0iUHJvY2Vzc0JlZm9yZUtWIiwKICAgICAgICAgICAgY29udGFpbmVyPXNlbGYua3ZfY29udGFpbmVyLAogICAgICAgICAgICB0YWJsZT1zZWxmLmt2X3BhdGgsCiAgICAgICAgKQogICAgICAgIGZlYXR1cmVfc2V0LmdyYXBoLmFkZF9zdGVwKAogICAgICAgICAgICAiSW5mZXJTY2hlbWEiLAogICAgICAgICAgICBuYW1lPSJJbmZlclNjaGVtYSIsCiAgICAgICAgICAgIGFmdGVyPSJXcml0ZVRvS1YiLAogICAgICAgICAgICB2M2lvX2FjY2Vzc19rZXk9c2VsZi52M2lvX2FjY2Vzc19rZXksCiAgICAgICAgICAgIHYzaW9fZnJhbWVzZD1zZWxmLnYzaW9fZnJhbWVzZCwKICAgICAgICAgICAgY29udGFpbmVyPXNlbGYua3ZfY29udGFpbmVyLAogICAgICAgICAgICB0YWJsZT1zZWxmLmt2X3BhdGgsCiAgICAgICAgKQogICAgICAgICMgdHNkYgogICAgICAgIGZlYXR1cmVfc2V0LmdyYXBoLmFkZF9zdGVwKAogICAgICAgICAgICAiUHJvY2Vzc0JlZm9yZVRTREIiLCBuYW1lPSJQcm9jZXNzQmVmb3JlVFNEQiIsIGFmdGVyPSJzYW1wbGUiCiAgICAgICAgKQogICAgICAgIGZlYXR1cmVfc2V0LmdyYXBoLmFkZF9zdGVwKAogICAgICAgICAgICAiRmlsdGVyQW5kVW5wYWNrS2V5cyIsCiAgICAgICAgICAgIG5hbWU9IkZpbHRlckFuZFVucGFja0tleXMxIiwKICAgICAgICAgICAgYWZ0ZXI9IlByb2Nlc3NCZWZvcmVUU0RCIiwKICAgICAgICAgICAga2V5cz1bQkFTRV9NRVRSSUNTXSwKICAgICAgICApCiAgICAgICAgZmVhdHVyZV9zZXQuZ3JhcGguYWRkX3N0ZXAoCiAgICAgICAgICAgICJzdG9yZXkuVFNEQlRhcmdldCIsCiAgICAgICAgICAgIG5hbWU9InRzZGIxIiwKICAgICAgICAgICAgYWZ0ZXI9IkZpbHRlckFuZFVucGFja0tleXMxIiwKICAgICAgICAgICAgcGF0aD1zZWxmLnRzZGJfcGF0aCwKICAgICAgICAgICAgcmF0ZT0iMTAvbSIsCiAgICAgICAgICAgIHRpbWVfY29sPVRJTUVTVEFNUCwKICAgICAgICAgICAgY29udGFpbmVyPXNlbGYudHNkYl9jb250YWluZXIsCiAgICAgICAgICAgIGFjY2Vzc19rZXk9c2VsZi52M2lvX2FjY2Vzc19rZXksCiAgICAgICAgICAgIHYzaW9fZnJhbWVzPXNlbGYudjNpb19mcmFtZXNkLAogICAgICAgICAgICBpbmRleF9jb2xzPVtFTkRQT0lOVF9JRCwgUkVDT1JEX1RZUEVdLAogICAgICAgICAgICBtYXhfZXZlbnRzPXNlbGYudHNkYl9iYXRjaGluZ19tYXhfZXZlbnRzLAogICAgICAgICAgICB0aW1lb3V0X3NlY3M9c2VsZi50c2RiX2JhdGNoaW5nX3RpbWVvdXRfc2VjcywKICAgICAgICAgICAga2V5PUVORFBPSU5UX0lELAogICAgICAgICkKICAgICAgICBmZWF0dXJlX3NldC5ncmFwaC5hZGRfc3RlcCgKICAgICAgICAgICAgIkZpbHRlckFuZFVucGFja0tleXMiLAogICAgICAgICAgICBuYW1lPSJGaWx0ZXJBbmRVbnBhY2tLZXlzMiIsCiAgICAgICAgICAgIGFmdGVyPSJQcm9jZXNzQmVmb3JlVFNEQiIsCiAgICAgICAgICAgIGtleXM9W0VORFBPSU5UX0ZFQVRVUkVTXSwKICAgICAgICApCiAgICAgICAgZmVhdHVyZV9zZXQuZ3JhcGguYWRkX3N0ZXAoCiAgICAgICAgICAgICJzdG9yZXkuVFNEQlRhcmdldCIsCiAgICAgICAgICAgIG5hbWU9InRzZGIyIiwKICAgICAgICAgICAgYWZ0ZXI9IkZpbHRlckFuZFVucGFja0tleXMyIiwKICAgICAgICAgICAgcGF0aD1zZWxmLnRzZGJfcGF0aCwKICAgICAgICAgICAgcmF0ZT0iMTAvbSIsCiAgICAgICAgICAgIHRpbWVfY29sPVRJTUVTVEFNUCwKICAgICAgICAgICAgY29udGFpbmVyPXNlbGYudHNkYl9jb250YWluZXIsCiAgICAgICAgICAgIGFjY2Vzc19rZXk9c2VsZi52M2lvX2FjY2Vzc19rZXksCiAgICAgICAgICAgIHYzaW9fZnJhbWVzPXNlbGYudjNpb19mcmFtZXNkLAogICAgICAgICAgICBpbmRleF9jb2xzPVtFTkRQT0lOVF9JRCwgUkVDT1JEX1RZUEVdLAogICAgICAgICAgICBtYXhfZXZlbnRzPXNlbGYudHNkYl9iYXRjaGluZ19tYXhfZXZlbnRzLAogICAgICAgICAgICB0aW1lb3V0X3NlY3M9c2VsZi50c2RiX2JhdGNoaW5nX3RpbWVvdXRfc2VjcywKICAgICAgICAgICAga2V5PUVORFBPSU5UX0lELAogICAgICAgICkKICAgICAgICBmZWF0dXJlX3NldC5ncmFwaC5hZGRfc3RlcCgKICAgICAgICAgICAgIkZpbHRlckFuZFVucGFja0tleXMiLAogICAgICAgICAgICBuYW1lPSJGaWx0ZXJBbmRVbnBhY2tLZXlzMyIsCiAgICAgICAgICAgIGFmdGVyPSJQcm9jZXNzQmVmb3JlVFNEQiIsCiAgICAgICAgICAgIGtleXM9W0NVU1RPTV9NRVRSSUNTXSwKICAgICAgICApCiAgICAgICAgZmVhdHVyZV9zZXQuZ3JhcGguYWRkX3N0ZXAoCiAgICAgICAgICAgICJzdG9yZXkuRmlsdGVyIiwKICAgICAgICAgICAgIkZpbHRlck5vdE5vbmUiLAogICAgICAgICAgICBhZnRlcj0iRmlsdGVyQW5kVW5wYWNrS2V5czMiLAogICAgICAgICAgICBfZm49IihldmVudCBpcyBub3QgTm9uZSkiLAogICAgICAgICkKICAgICAgICBmZWF0dXJlX3NldC5ncmFwaC5hZGRfc3RlcCgKICAgICAgICAgICAgInN0b3JleS5UU0RCVGFyZ2V0IiwKICAgICAgICAgICAgbmFtZT0idHNkYjMiLAogICAgICAgICAgICBhZnRlcj0iRmlsdGVyTm90Tm9uZSIsCiAgICAgICAgICAgIHBhdGg9c2VsZi50c2RiX3BhdGgsCiAgICAgICAgICAgIHJhdGU9IjEwL20iLAogICAgICAgICAgICB0aW1lX2NvbD1USU1FU1RBTVAsCiAgICAgICAgICAgIGNvbnRhaW5lcj1zZWxmLnRzZGJfY29udGFpbmVyLAogICAgICAgICAgICBhY2Nlc3Nfa2V5PXNlbGYudjNpb19hY2Nlc3Nfa2V5LAogICAgICAgICAgICB2M2lvX2ZyYW1lcz1zZWxmLnYzaW9fZnJhbWVzZCwKICAgICAgICAgICAgaW5kZXhfY29scz1bRU5EUE9JTlRfSUQsIFJFQ09SRF9UWVBFXSwKICAgICAgICAgICAgbWF4X2V2ZW50cz1zZWxmLnRzZGJfYmF0Y2hpbmdfbWF4X2V2ZW50cywKICAgICAgICAgICAgdGltZW91dF9zZWNzPXNlbGYudHNkYl9iYXRjaGluZ190aW1lb3V0X3NlY3MsCiAgICAgICAgICAgIGtleT1FTkRQT0lOVF9JRCwKICAgICAgICApCgogICAgICAgICMgcGFycXVldCBicmFuY2gKICAgICAgICBmZWF0dXJlX3NldC5ncmFwaC5hZGRfc3RlcCgKICAgICAgICAgICAgIlByb2Nlc3NCZWZvcmVQYXJxdWV0IiwKICAgICAgICAgICAgbmFtZT0iUHJvY2Vzc0JlZm9yZVBhcnF1ZXQiLAogICAgICAgICAgICBhZnRlcj0iTWFwRmVhdHVyZU5hbWVzIiwKICAgICAgICAgICAgX2ZuPSIoZXZlbnQpIiwKICAgICAgICApCiAgICAgICAgc3RvcmFnZV9vcHRpb25zID0gZGljdCgKICAgICAgICAgICAgdjNpb19hY2Nlc3Nfa2V5PXNlbGYubW9kZWxfbW9uaXRvcmluZ19hY2Nlc3Nfa2V5LCB2M2lvX2FwaT1zZWxmLnYzaW9fYXBpCiAgICAgICAgKQoKICAgICAgICBwcV90YXJnZXQgPSBQYXJxdWV0VGFyZ2V0KAogICAgICAgICAgICBwYXRoPXNlbGYucGFycXVldF9wYXRoLAogICAgICAgICAgICBhZnRlcl9zdGVwPSJQcm9jZXNzQmVmb3JlUGFycXVldCIsCiAgICAgICAgICAgIGtleV9idWNrZXRpbmdfbnVtYmVyPTAsCiAgICAgICAgICAgIHRpbWVfcGFydGl0aW9uaW5nX2dyYW51bGFyaXR5PSJob3VyIiwKICAgICAgICAgICAgbWF4X2V2ZW50cz1zZWxmLnBhcnF1ZXRfYmF0Y2hpbmdfbWF4X2V2ZW50cywKICAgICAgICAgICAgZmx1c2hfYWZ0ZXJfc2Vjb25kcz1zZWxmLnBhcnF1ZXRfYmF0Y2hpbmdfdGltZW91dF9zZWNzLAogICAgICAgICAgICBzdG9yYWdlX29wdGlvbnM9c3RvcmFnZV9vcHRpb25zLAogICAgICAgICAgICBhdHRyaWJ1dGVzPXsiaW5mZXJfY29sdW1uc19mcm9tX2RhdGEiOiBUcnVlfSwKICAgICAgICApCgogICAgICAgIGZlYXR1cmVfc2V0LnNldF90YXJnZXRzKAogICAgICAgICAgICB0YXJnZXRzPVtwcV90YXJnZXRdLAogICAgICAgICAgICB3aXRoX2RlZmF1bHRzPUZhbHNlLAogICAgICAgICAgICBkZWZhdWx0X2ZpbmFsX3N0ZXA9IlByb2Nlc3NCZWZvcmVQYXJxdWV0IiwKICAgICAgICApCiAgICAgICAgcmV0dXJuIGZlYXR1cmVfc2V0CgoKY2xhc3MgUHJvY2Vzc0JlZm9yZUtWKE1hcENsYXNzKToKICAgIGRlZiBfX2luaXRfXyhzZWxmLCAqKmt3YXJncyk6CiAgICAgICAgc3VwZXIoKS5fX2luaXRfXygqKmt3YXJncykKCiAgICBkZWYgZG8oc2VsZiwgZXZlbnQpOgogICAgICAgICMgY29tcHV0ZSBwcmVkaWN0aW9uIHBlciBzZWNvbmQKICAgICAgICBldmVudFtQUkVESUNUSU9OU19QRVJfU0VDT05EXSA9IGZsb2F0KGV2ZW50W1BSRURJQ1RJT05TX0NPVU5UXzVNXSkgLyAzMDAKICAgICAgICAjIEZpbHRlciByZWxldmFudCBrZXlzCiAgICAgICAgZSA9IHsKICAgICAgICAgICAgazogZXZlbnRba10KICAgICAgICAgICAgZm9yIGsgaW4gWwogICAgICAgICAgICAgICAgRlVOQ1RJT05fVVJJLAogICAgICAgICAgICAgICAgTU9ERUwsCiAgICAgICAgICAgICAgICBNT0RFTF9DTEFTUywKICAgICAgICAgICAgICAgIFRJTUVTVEFNUCwKICAgICAgICAgICAgICAgIEVORFBPSU5UX0lELAogICAgICAgICAgICAgICAgTEFCRUxTLAogICAgICAgICAgICAgICAgVU5QQUNLRURfTEFCRUxTLAogICAgICAgICAgICAgICAgTEFURU5DWV9BVkdfNU0sCiAgICAgICAgICAgICAgICBMQVRFTkNZX0FWR18xSCwKICAgICAgICAgICAgICAgIFBSRURJQ1RJT05TX1BFUl9TRUNPTkQsCiAgICAgICAgICAgICAgICBQUkVESUNUSU9OU19DT1VOVF81TSwKICAgICAgICAgICAgICAgIFBSRURJQ1RJT05TX0NPVU5UXzFILAogICAgICAgICAgICAgICAgRklSU1RfUkVRVUVTVCwKICAgICAgICAgICAgICAgIExBU1RfUkVRVUVTVCwKICAgICAgICAgICAgICAgIEVSUk9SX0NPVU5ULAogICAgICAgICAgICBdCiAgICAgICAgfQogICAgICAgICMgVW5wYWNrIGxhYmVscyBkaWN0aW9uYXJ5CiAgICAgICAgZSA9IHsqKmUsICoqZS5wb3AoVU5QQUNLRURfTEFCRUxTLCB7fSl9CiAgICAgICAgIyBXcml0ZSBsYWJlbHMgdG8ga3YgYXMganNvbiBzdHJpbmcgdG8gYmUgcHJlc2VudGFibGUgbGF0ZXIKICAgICAgICBlW0xBQkVMU10gPSBqc29uLmR1bXBzKGVbTEFCRUxTXSkKICAgICAgICByZXR1cm4gZQoKCmNsYXNzIFByb2Nlc3NCZWZvcmVUU0RCKE1hcENsYXNzKToKICAgIGRlZiBfX2luaXRfXyhzZWxmLCAqKmt3YXJncyk6CiAgICAgICAgc3VwZXIoKS5fX2luaXRfXygqKmt3YXJncykKCiAgICBkZWYgZG8oc2VsZiwgZXZlbnQpOgogICAgICAgICMgY29tcHV0ZSBwcmVkaWN0aW9uIHBlciBzZWNvbmQKICAgICAgICBldmVudFtQUkVESUNUSU9OU19QRVJfU0VDT05EXSA9IGZsb2F0KGV2ZW50W1BSRURJQ1RJT05TX0NPVU5UXzVNXSkgLyAzMDAKICAgICAgICBiYXNlX2ZpZWxkcyA9IFtUSU1FU1RBTVAsIEVORFBPSU5UX0lEXQoKICAgICAgICBiYXNlX2V2ZW50ID0ge2s6IGV2ZW50W2tdIGZvciBrIGluIGJhc2VfZmllbGRzfQogICAgICAgIGJhc2VfZXZlbnRbVElNRVNUQU1QXSA9IHBkLnRvX2RhdGV0aW1lKAogICAgICAgICAgICBiYXNlX2V2ZW50W1RJTUVTVEFNUF0sIGZvcm1hdD1USU1FX0ZPUk1BVAogICAgICAgICkKCiAgICAgICAgYmFzZV9tZXRyaWNzID0gewogICAgICAgICAgICBSRUNPUkRfVFlQRTogQkFTRV9NRVRSSUNTLAogICAgICAgICAgICBQUkVESUNUSU9OU19QRVJfU0VDT05EOiBldmVudFtQUkVESUNUSU9OU19QRVJfU0VDT05EXSwKICAgICAgICAgICAgUFJFRElDVElPTlNfQ09VTlRfNU06IGV2ZW50W1BSRURJQ1RJT05TX0NPVU5UXzVNXSwKICAgICAgICAgICAgUFJFRElDVElPTlNfQ09VTlRfMUg6IGV2ZW50W1BSRURJQ1RJT05TX0NPVU5UXzFIXSwKICAgICAgICAgICAgTEFURU5DWV9BVkdfNU06IGV2ZW50W0xBVEVOQ1lfQVZHXzVNXSwKICAgICAgICAgICAgTEFURU5DWV9BVkdfMUg6IGV2ZW50W0xBVEVOQ1lfQVZHXzFIXSwKICAgICAgICAgICAgKipiYXNlX2V2ZW50LAogICAgICAgIH0KCiAgICAgICAgZW5kcG9pbnRfZmVhdHVyZXMgPSB7CiAgICAgICAgICAgIFJFQ09SRF9UWVBFOiBFTkRQT0lOVF9GRUFUVVJFUywKICAgICAgICAgICAgKipldmVudFtOQU1FRF9QUkVESUNUSU9OU10sCiAgICAgICAgICAgICoqZXZlbnRbTkFNRURfRkVBVFVSRVNdLAogICAgICAgICAgICAqKmJhc2VfZXZlbnQsCiAgICAgICAgfQoKICAgICAgICBwcm9jZXNzZWQgPSB7QkFTRV9NRVRSSUNTOiBiYXNlX21ldHJpY3MsIEVORFBPSU5UX0ZFQVRVUkVTOiBlbmRwb2ludF9mZWF0dXJlc30KCiAgICAgICAgaWYgZXZlbnRbTUVUUklDU106CiAgICAgICAgICAgIHByb2Nlc3NlZFtDVVNUT01fTUVUUklDU10gPSB7CiAgICAgICAgICAgICAgICBSRUNPUkRfVFlQRTogQ1VTVE9NX01FVFJJQ1MsCiAgICAgICAgICAgICAgICAqKmV2ZW50W01FVFJJQ1NdLAogICAgICAgICAgICAgICAgKipiYXNlX2V2ZW50LAogICAgICAgICAgICB9CgogICAgICAgIHJldHVybiBwcm9jZXNzZWQKCgpjbGFzcyBQcm9jZXNzQmVmb3JlUGFycXVldChNYXBDbGFzcyk6CiAgICBkZWYgX19pbml0X18oc2VsZiwgKiprd2FyZ3MpOgogICAgICAgIHN1cGVyKCkuX19pbml0X18oKiprd2FyZ3MpCgogICAgZGVmIGRvKHNlbGYsIGV2ZW50KToKICAgICAgICBsb2dnZXIuaW5mbygiUHJvY2Vzc0JlZm9yZVBhcnF1ZXQxIiwgZXZlbnQ9ZXZlbnQpCiAgICAgICAgZm9yIGtleSBpbiBbVU5QQUNLRURfTEFCRUxTLCBGRUFUVVJFU106CiAgICAgICAgICAgIGV2ZW50LnBvcChrZXksIE5vbmUpCiAgICAgICAgdmFsdWUgPSBldmVudC5nZXQoImVudGl0aWVzIikKICAgICAgICBpZiB2YWx1ZSBpcyBub3QgTm9uZToKICAgICAgICAgICAgZXZlbnQgPSB7Kip2YWx1ZSwgKipldmVudH0KICAgICAgICBmb3Iga2V5IGluIFtMQUJFTFMsIE1FVFJJQ1MsIEVOVElUSUVTXToKICAgICAgICAgICAgaWYgbm90IGV2ZW50LmdldChrZXkpOgogICAgICAgICAgICAgICAgZXZlbnRba2V5XSA9IE5vbmUKICAgICAgICBsb2dnZXIuaW5mbygiUHJvY2Vzc0JlZm9yZVBhcnF1ZXQyIiwgZXZlbnQ9ZXZlbnQpCiAgICAgICAgcmV0dXJuIGV2ZW50CgoKY2xhc3MgUHJvY2Vzc0VuZHBvaW50RXZlbnQoTWFwQ2xhc3MpOgogICAgZGVmIF9faW5pdF9fKHNlbGYsIGt2X2NvbnRhaW5lcjogc3RyLCBrdl9wYXRoOiBzdHIsIHYzaW9fYWNjZXNzX2tleTogc3RyLCAqKmt3YXJncyk6CiAgICAgICAgc3VwZXIoKS5fX2luaXRfXygqKmt3YXJncykKICAgICAgICBzZWxmLmt2X2NvbnRhaW5lcjogc3RyID0ga3ZfY29udGFpbmVyCiAgICAgICAgc2VsZi5rdl9wYXRoOiBzdHIgPSBrdl9wYXRoCiAgICAgICAgc2VsZi52M2lvX2FjY2Vzc19rZXk6IHN0ciA9IHYzaW9fYWNjZXNzX2tleQogICAgICAgIHNlbGYuZmlyc3RfcmVxdWVzdDogRGljdFtzdHIsIHN0cl0gPSBkaWN0KCkKICAgICAgICBzZWxmLmxhc3RfcmVxdWVzdDogRGljdFtzdHIsIHN0cl0gPSBkaWN0KCkKICAgICAgICBzZWxmLmVycm9yX2NvdW50OiBEaWN0W3N0ciwgaW50XSA9IGRlZmF1bHRkaWN0KGludCkKICAgICAgICBzZWxmLmVuZHBvaW50czogU2V0W3N0cl0gPSBzZXQoKQoKICAgIGRlZiBkbyhzZWxmLCBmdWxsX2V2ZW50KToKICAgICAgICBldmVudCA9IGZ1bGxfZXZlbnQuYm9keQoKICAgICAgICAjIGNvZGUgdGhhdCBjYWxjdWxhdGVzIHRoZSBlbmRwcGludCBpZC4gc2hvdWxkIGJlCiAgICAgICAgZnVuY3Rpb25fdXJpID0gZXZlbnQuZ2V0KEZVTkNUSU9OX1VSSSkKICAgICAgICBpZiBub3QgaXNfbm90X25vbmUoZnVuY3Rpb25fdXJpLCBbRlVOQ1RJT05fVVJJXSk6CiAgICAgICAgICAgIHJldHVybiBOb25lCgogICAgICAgIG1vZGVsID0gZXZlbnQuZ2V0KE1PREVMKQogICAgICAgIGlmIG5vdCBpc19ub3Rfbm9uZShtb2RlbCwgW01PREVMXSk6CiAgICAgICAgICAgIHJldHVybiBOb25lCgogICAgICAgIHZlcnNpb24gPSBldmVudC5nZXQoVkVSU0lPTikKICAgICAgICB2ZXJzaW9uZWRfbW9kZWwgPSBmInttb2RlbH06e3ZlcnNpb259IiBpZiB2ZXJzaW9uIGVsc2UgZiJ7bW9kZWx9OmxhdGVzdCIKCiAgICAgICAgZW5kcG9pbnRfaWQgPSBjcmVhdGVfbW9kZWxfZW5kcG9pbnRfaWQoCiAgICAgICAgICAgIGZ1bmN0aW9uX3VyaT1mdW5jdGlvbl91cmksCiAgICAgICAgICAgIHZlcnNpb25lZF9tb2RlbD12ZXJzaW9uZWRfbW9kZWwsCiAgICAgICAgKQogICAgICAgIGVuZHBvaW50X2lkID0gc3RyKGVuZHBvaW50X2lkKQoKICAgICAgICBldmVudFtWRVJTSU9ORURfTU9ERUxdID0gdmVyc2lvbmVkX21vZGVsCiAgICAgICAgZXZlbnRbRU5EUE9JTlRfSURdID0gZW5kcG9pbnRfaWQKCiAgICAgICAgIyBJbiBjYXNlIHRoaXMgcHJvY2VzcyBmYWlscywgcmVzdW1lIHN0YXRlIGZyb20gZXhpc3RpbmcgcmVjb3JkCiAgICAgICAgc2VsZi5yZXN1bWVfc3RhdGUoZW5kcG9pbnRfaWQpCgogICAgICAgICMgSGFuZGxlIGVycm9ycyBjb21pbmcgZnJvbSBzdHJlYW0KICAgICAgICBmb3VuZF9lcnJvcnMgPSBzZWxmLmhhbmRsZV9lcnJvcnMoZW5kcG9pbnRfaWQsIGV2ZW50KQogICAgICAgIGlmIGZvdW5kX2Vycm9yczoKICAgICAgICAgICAgcmV0dXJuIE5vbmUKCiAgICAgICAgIyBWYWxpZGF0ZSBldmVudCBmaWVsZHMKICAgICAgICBtb2RlbF9jbGFzcyA9IGV2ZW50LmdldCgibW9kZWxfY2xhc3MiKSBvciBldmVudC5nZXQoImNsYXNzIikKICAgICAgICB0aW1lc3RhbXAgPSBldmVudC5nZXQoIndoZW4iKQogICAgICAgIHJlcXVlc3RfaWQgPSBldmVudC5nZXQoInJlcXVlc3QiLCB7fSkuZ2V0KCJpZCIpIG9yIGV2ZW50LmdldCgicmVzcCIsIHt9KS5nZXQoCiAgICAgICAgICAgICJpZCIKICAgICAgICApCiAgICAgICAgbGF0ZW5jeSA9IGV2ZW50LmdldCgibWljcm9zZWMiKQogICAgICAgIGZlYXR1cmVzID0gZXZlbnQuZ2V0KCJyZXF1ZXN0Iiwge30pLmdldCgiaW5wdXRzIikKICAgICAgICBwcmVkaWN0aW9ucyA9IGV2ZW50LmdldCgicmVzcCIsIHt9KS5nZXQoIm91dHB1dHMiKQoKICAgICAgICBpZiBub3Qgc2VsZi5pc192YWxpZCgKICAgICAgICAgICAgZW5kcG9pbnRfaWQsCiAgICAgICAgICAgIGlzX25vdF9ub25lLAogICAgICAgICAgICB0aW1lc3RhbXAsCiAgICAgICAgICAgIFsid2hlbiJdLAogICAgICAgICk6CiAgICAgICAgICAgIHJldHVybiBOb25lCgogICAgICAgIGlmIGVuZHBvaW50X2lkIG5vdCBpbiBzZWxmLmZpcnN0X3JlcXVlc3Q6CiAgICAgICAgICAgIHNlbGYuZmlyc3RfcmVxdWVzdFtlbmRwb2ludF9pZF0gPSB0aW1lc3RhbXAKICAgICAgICBzZWxmLmxhc3RfcmVxdWVzdFtlbmRwb2ludF9pZF0gPSB0aW1lc3RhbXAKCiAgICAgICAgaWYgbm90IHNlbGYuaXNfdmFsaWQoCiAgICAgICAgICAgIGVuZHBvaW50X2lkLAogICAgICAgICAgICBpc19ub3Rfbm9uZSwKICAgICAgICAgICAgcmVxdWVzdF9pZCwKICAgICAgICAgICAgWyJyZXF1ZXN0IiwgImlkIl0sCiAgICAgICAgKToKICAgICAgICAgICAgcmV0dXJuIE5vbmUKICAgICAgICBpZiBub3Qgc2VsZi5pc192YWxpZCgKICAgICAgICAgICAgZW5kcG9pbnRfaWQsCiAgICAgICAgICAgIGlzX25vdF9ub25lLAogICAgICAgICAgICBsYXRlbmN5LAogICAgICAgICAgICBbIm1pY3Jvc2VjIl0sCiAgICAgICAgKToKICAgICAgICAgICAgcmV0dXJuIE5vbmUKICAgICAgICBpZiBub3Qgc2VsZi5pc192YWxpZCgKICAgICAgICAgICAgZW5kcG9pbnRfaWQsCiAgICAgICAgICAgIGlzX25vdF9ub25lLAogICAgICAgICAgICBmZWF0dXJlcywKICAgICAgICAgICAgWyJyZXF1ZXN0IiwgImlucHV0cyJdLAogICAgICAgICk6CiAgICAgICAgICAgIHJldHVybiBOb25lCiAgICAgICAgaWYgbm90IHNlbGYuaXNfdmFsaWQoCiAgICAgICAgICAgIGVuZHBvaW50X2lkLAogICAgICAgICAgICBpc19ub3Rfbm9uZSwKICAgICAgICAgICAgcHJlZGljdGlvbnMsCiAgICAgICAgICAgIFsicmVzcCIsICJvdXRwdXRzIl0sCiAgICAgICAgKToKICAgICAgICAgICAgcmV0dXJuIE5vbmUKCiAgICAgICAgdW5wYWNrZWRfbGFiZWxzID0ge2YiX3trfSI6IHYgZm9yIGssIHYgaW4gZXZlbnQuZ2V0KExBQkVMUywge30pLml0ZW1zKCl9CgogICAgICAgICMgU2VwYXJhdGUgZWFjaCBtb2RlbCBpbnZvY2F0aW9uIGludG8gc3ViIGV2ZW50cwogICAgICAgIGV2ZW50cyA9IFtdCiAgICAgICAgZm9yIGksIChmZWF0dXJlLCBwcmVkaWN0aW9uKSBpbiBlbnVtZXJhdGUoemlwKGZlYXR1cmVzLCBwcmVkaWN0aW9ucykpOgogICAgICAgICAgICBpZiBub3Qgc2VsZi5pc192YWxpZCgKICAgICAgICAgICAgICAgIGVuZHBvaW50X2lkLAogICAgICAgICAgICAgICAgc2VsZi5pc19saXN0X29mX251bWVyaWNzLAogICAgICAgICAgICAgICAgZmVhdHVyZSwKICAgICAgICAgICAgICAgIFsicmVxdWVzdCIsICJpbnB1dHMiLCBmIlt7aX1dIl0sCiAgICAgICAgICAgICk6CiAgICAgICAgICAgICAgICByZXR1cm4gTm9uZQoKICAgICAgICAgICAgaWYgbm90IGlzaW5zdGFuY2UocHJlZGljdGlvbiwgbGlzdCk6CiAgICAgICAgICAgICAgICBwcmVkaWN0aW9uID0gW3ByZWRpY3Rpb25dCgogICAgICAgICAgICBldmVudHMuYXBwZW5kKAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEZVTkNUSU9OX1VSSTogZnVuY3Rpb25fdXJpLAogICAgICAgICAgICAgICAgICAgIE1PREVMOiB2ZXJzaW9uZWRfbW9kZWwsCiAgICAgICAgICAgICAgICAgICAgTU9ERUxfQ0xBU1M6IG1vZGVsX2NsYXNzLAogICAgICAgICAgICAgICAgICAgIFRJTUVTVEFNUDogdGltZXN0YW1wLAogICAgICAgICAgICAgICAgICAgIEVORFBPSU5UX0lEOiBlbmRwb2ludF9pZCwKICAgICAgICAgICAgICAgICAgICBSRVFVRVNUX0lEOiByZXF1ZXN0X2lkLAogICAgICAgICAgICAgICAgICAgIExBVEVOQ1k6IGxhdGVuY3ksCiAgICAgICAgICAgICAgICAgICAgRkVBVFVSRVM6IGZlYXR1cmUsCiAgICAgICAgICAgICAgICAgICAgUFJFRElDVElPTjogcHJlZGljdGlvbiwKICAgICAgICAgICAgICAgICAgICBGSVJTVF9SRVFVRVNUOiBzZWxmLmZpcnN0X3JlcXVlc3RbZW5kcG9pbnRfaWRdLAogICAgICAgICAgICAgICAgICAgIExBU1RfUkVRVUVTVDogc2VsZi5sYXN0X3JlcXVlc3RbZW5kcG9pbnRfaWRdLAogICAgICAgICAgICAgICAgICAgIEVSUk9SX0NPVU5UOiBzZWxmLmVycm9yX2NvdW50W2VuZHBvaW50X2lkXSwKICAgICAgICAgICAgICAgICAgICBMQUJFTFM6IGV2ZW50LmdldChMQUJFTFMsIHt9KSwKICAgICAgICAgICAgICAgICAgICBNRVRSSUNTOiBldmVudC5nZXQoTUVUUklDUywge30pLAogICAgICAgICAgICAgICAgICAgIEVOVElUSUVTOiBldmVudC5nZXQoInJlcXVlc3QiLCB7fSkuZ2V0KEVOVElUSUVTLCB7fSksCiAgICAgICAgICAgICAgICAgICAgVU5QQUNLRURfTEFCRUxTOiB1bnBhY2tlZF9sYWJlbHMsCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkKCiAgICAgICAgc3RvcmV5X2V2ZW50ID0gRXZlbnQoYm9keT1ldmVudHMsIGtleT1lbmRwb2ludF9pZCwgdGltZT10aW1lc3RhbXApCiAgICAgICAgcmV0dXJuIHN0b3JleV9ldmVudAoKICAgIGRlZiBpc19saXN0X29mX251bWVyaWNzKAogICAgICAgIHNlbGYsIGZpZWxkOiBMaXN0W1VuaW9uW2ludCwgZmxvYXQsIGRpY3QsIGxpc3RdXSwgZGljdF9wYXRoOiBMaXN0W3N0cl0KICAgICk6CiAgICAgICAgaWYgYWxsKGlzaW5zdGFuY2UoeCwgaW50KSBvciBpc2luc3RhbmNlKHgsIGZsb2F0KSBmb3IgeCBpbiBmaWVsZCk6CiAgICAgICAgICAgIHJldHVybiBUcnVlCiAgICAgICAgbG9nZ2VyLmVycm9yKAogICAgICAgICAgICBmIkxpc3QgZG9lcyBub3QgY29uc2lzdCBvZiBvbmx5IG51bWVyaWMgdmFsdWVzOiB7ZmllbGR9IFtFdmVudCAtPiB7JywnLmpvaW4oZGljdF9wYXRoKX1dIgogICAgICAgICkKICAgICAgICByZXR1cm4gRmFsc2UKCiAgICBkZWYgcmVzdW1lX3N0YXRlKHNlbGYsIGVuZHBvaW50X2lkKToKICAgICAgICAjIE1ha2Ugc3VyZSBwcm9jZXNzIGlzIHJlc3VtYWJsZSwgaWYgcHJvY2VzcyBmYWlscyBmb3IgYW55IHJlYXNvbiwgYmUgYWJsZSB0byBwaWNrIHRoaW5ncyB1cCBjbG9zZSB0byB3aGVyZSB3ZQogICAgICAgICMgbGVmdCB0aGVtCiAgICAgICAgaWYgZW5kcG9pbnRfaWQgbm90IGluIHNlbGYuZW5kcG9pbnRzOgogICAgICAgICAgICBsb2dnZXIuaW5mbygiVHJ5aW5nIHRvIHJlc3VtZSBzdGF0ZSIsIGVuZHBvaW50X2lkPWVuZHBvaW50X2lkKQogICAgICAgICAgICBlbmRwb2ludF9yZWNvcmQgPSBnZXRfZW5kcG9pbnRfcmVjb3JkKAogICAgICAgICAgICAgICAga3ZfY29udGFpbmVyPXNlbGYua3ZfY29udGFpbmVyLAogICAgICAgICAgICAgICAga3ZfcGF0aD1zZWxmLmt2X3BhdGgsCiAgICAgICAgICAgICAgICBlbmRwb2ludF9pZD1lbmRwb2ludF9pZCwKICAgICAgICAgICAgICAgIGFjY2Vzc19rZXk9c2VsZi52M2lvX2FjY2Vzc19rZXksCiAgICAgICAgICAgICkKICAgICAgICAgICAgaWYgZW5kcG9pbnRfcmVjb3JkOgogICAgICAgICAgICAgICAgZmlyc3RfcmVxdWVzdCA9IGVuZHBvaW50X3JlY29yZC5nZXQoRklSU1RfUkVRVUVTVCkKICAgICAgICAgICAgICAgIGlmIGZpcnN0X3JlcXVlc3Q6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5maXJzdF9yZXF1ZXN0W2VuZHBvaW50X2lkXSA9IGZpcnN0X3JlcXVlc3QKICAgICAgICAgICAgICAgIGVycm9yX2NvdW50ID0gZW5kcG9pbnRfcmVjb3JkLmdldChFUlJPUl9DT1VOVCkKICAgICAgICAgICAgICAgIGlmIGVycm9yX2NvdW50OgogICAgICAgICAgICAgICAgICAgIHNlbGYuZXJyb3JfY291bnRbZW5kcG9pbnRfaWRdID0gZXJyb3JfY291bnQKICAgICAgICAgICAgc2VsZi5lbmRwb2ludHMuYWRkKGVuZHBvaW50X2lkKQoKICAgIGRlZiBpc192YWxpZCgKICAgICAgICBzZWxmLCBlbmRwb2ludF9pZDogc3RyLCB2YWxpZGF0aW9uX2Z1bmN0aW9uLCBmaWVsZDogQW55LCBkaWN0X3BhdGg6IExpc3Rbc3RyXQogICAgKToKICAgICAgICBpZiB2YWxpZGF0aW9uX2Z1bmN0aW9uKGZpZWxkLCBkaWN0X3BhdGgpOgogICAgICAgICAgICByZXR1cm4gVHJ1ZQogICAgICAgIHNlbGYuZXJyb3JfY291bnRbZW5kcG9pbnRfaWRdICs9IDEKICAgICAgICByZXR1cm4gRmFsc2UKCiAgICBkZWYgaGFuZGxlX2Vycm9ycyhzZWxmLCBlbmRwb2ludF9pZCwgZXZlbnQpIC0+IGJvb2w6CiAgICAgICAgaWYgImVycm9yIiBpbiBldmVudDoKICAgICAgICAgICAgc2VsZi5lcnJvcl9jb3VudFtlbmRwb2ludF9pZF0gKz0gMQogICAgICAgICAgICByZXR1cm4gVHJ1ZQoKICAgICAgICByZXR1cm4gRmFsc2UKCgpkZWYgZW5yaWNoX2V2ZW5fZGV0YWlscyhldmVudCkgLT4gT3B0aW9uYWxbZGljdF06CiAgICBmdW5jdGlvbl91cmkgPSBldmVudC5nZXQoRlVOQ1RJT05fVVJJKQoKICAgIGlmIG5vdCBpc19ub3Rfbm9uZShmdW5jdGlvbl91cmksIFtGVU5DVElPTl9VUkldKToKICAgICAgICByZXR1cm4gTm9uZQoKICAgIG1vZGVsID0gZXZlbnQuZ2V0KE1PREVMKQogICAgaWYgbm90IGlzX25vdF9ub25lKG1vZGVsLCBbTU9ERUxdKToKICAgICAgICByZXR1cm4gTm9uZQoKICAgIHZlcnNpb24gPSBldmVudC5nZXQoVkVSU0lPTikKICAgIHZlcnNpb25lZF9tb2RlbCA9IGYie21vZGVsfTp7dmVyc2lvbn0iIGlmIHZlcnNpb24gZWxzZSBmInttb2RlbH06bGF0ZXN0IgoKICAgIGVuZHBvaW50X2lkID0gY3JlYXRlX21vZGVsX2VuZHBvaW50X2lkKAogICAgICAgIGZ1bmN0aW9uX3VyaT1mdW5jdGlvbl91cmksCiAgICAgICAgdmVyc2lvbmVkX21vZGVsPXZlcnNpb25lZF9tb2RlbCwKICAgICkKCiAgICBlbmRwb2ludF9pZCA9IHN0cihlbmRwb2ludF9pZCkKCiAgICBldmVudFtWRVJTSU9ORURfTU9ERUxdID0gdmVyc2lvbmVkX21vZGVsCiAgICBldmVudFtFTkRQT0lOVF9JRF0gPSBlbmRwb2ludF9pZAoKICAgIHJldHVybiBldmVudAoKCmRlZiBpc19ub3Rfbm9uZShmaWVsZDogQW55LCBkaWN0X3BhdGg6IExpc3Rbc3RyXSk6CiAgICBpZiBmaWVsZCBpcyBub3QgTm9uZToKICAgICAgICByZXR1cm4gVHJ1ZQogICAgbG9nZ2VyLmVycm9yKAogICAgICAgIGYiRXhwZWN0ZWQgZXZlbnQgZmllbGQgaXMgbWlzc2luZzoge2ZpZWxkfSBbRXZlbnQgLT4geycsJy5qb2luKGRpY3RfcGF0aCl9XSIKICAgICkKICAgIHJldHVybiBGYWxzZQoKCmNsYXNzIEZpbHRlckFuZFVucGFja0tleXMoTWFwQ2xhc3MpOgogICAgZGVmIF9faW5pdF9fKHNlbGYsIGtleXMsICoqa3dhcmdzKToKICAgICAgICBzdXBlcigpLl9faW5pdF9fKCoqa3dhcmdzKQogICAgICAgIHNlbGYua2V5cyA9IGtleXMKCiAgICBkZWYgZG8oc2VsZiwgZXZlbnQpOgogICAgICAgIG5ld19ldmVudCA9IHt9CiAgICAgICAgZm9yIGtleSBpbiBzZWxmLmtleXM6CiAgICAgICAgICAgIGlmIGtleSBpbiBldmVudDoKICAgICAgICAgICAgICAgIG5ld19ldmVudFtrZXldID0gZXZlbnRba2V5XQogICAgICAgIHVucGFja2VkID0ge30KICAgICAgICBmb3Iga2V5IGluIG5ld19ldmVudC5rZXlzKCk6CiAgICAgICAgICAgIGlmIGtleSBpbiBzZWxmLmtleXM6CiAgICAgICAgICAgICAgICB1bnBhY2tlZCA9IHsqKnVucGFja2VkLCAqKm5ld19ldmVudFtrZXldfQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgdW5wYWNrZWRba2V5XSA9IG5ld19ldmVudFtrZXldCiAgICAgICAgcmV0dXJuIHVucGFja2VkIGlmIHVucGFja2VkIGVsc2UgTm9uZQoKCmNsYXNzIE1hcEZlYXR1cmVOYW1lcyhNYXBDbGFzcyk6CiAgICBkZWYgX19pbml0X18oCiAgICAgICAgc2VsZiwKICAgICAgICBrdl9jb250YWluZXI6IHN0ciwKICAgICAgICBrdl9wYXRoOiBzdHIsCiAgICAgICAgYWNjZXNzX2tleTogc3RyLAogICAgICAgIGluZmVyX2NvbHVtbnNfZnJvbV9kYXRhOiBib29sID0gRmFsc2UsCiAgICAgICAgKiprd2FyZ3MsCiAgICApOgogICAgICAgIHN1cGVyKCkuX19pbml0X18oKiprd2FyZ3MpCiAgICAgICAgc2VsZi5rdl9jb250YWluZXIgPSBrdl9jb250YWluZXIKICAgICAgICBzZWxmLmt2X3BhdGggPSBrdl9wYXRoCiAgICAgICAgc2VsZi5hY2Nlc3Nfa2V5ID0gYWNjZXNzX2tleQogICAgICAgIHNlbGYuX2luZmVyX2NvbHVtbnNfZnJvbV9kYXRhID0gaW5mZXJfY29sdW1uc19mcm9tX2RhdGEKICAgICAgICBzZWxmLmZlYXR1cmVfbmFtZXMgPSB7fQogICAgICAgIHNlbGYubGFiZWxfY29sdW1ucyA9IHt9CgogICAgZGVmIF9pbmZlcl9mZWF0dXJlX25hbWVzX2Zyb21fZGF0YShzZWxmLCBldmVudCk6CiAgICAgICAgZm9yIGVuZHBvaW50X2lkIGluIHNlbGYuZmVhdHVyZV9uYW1lczoKICAgICAgICAgICAgaWYgbGVuKHNlbGYuZmVhdHVyZV9uYW1lc1tlbmRwb2ludF9pZF0pID49IGxlbihldmVudFtGRUFUVVJFU10pOgogICAgICAgICAgICAgICAgcmV0dXJuIHNlbGYuZmVhdHVyZV9uYW1lc1tlbmRwb2ludF9pZF0KICAgICAgICByZXR1cm4gTm9uZQoKICAgIGRlZiBfaW5mZXJfbGFiZWxfY29sdW1uc19mcm9tX2RhdGEoc2VsZiwgZXZlbnQpOgogICAgICAgIGZvciBlbmRwb2ludF9pZCBpbiBzZWxmLmxhYmVsX2NvbHVtbnM6CiAgICAgICAgICAgIGlmIGxlbihzZWxmLmxhYmVsX2NvbHVtbnNbZW5kcG9pbnRfaWRdKSA+PSBsZW4oZXZlbnRbUFJFRElDVElPTl0pOgogICAgICAgICAgICAgICAgcmV0dXJuIHNlbGYubGFiZWxfY29sdW1uc1tlbmRwb2ludF9pZF0KICAgICAgICByZXR1cm4gTm9uZQoKICAgIGRlZiBkbyhzZWxmLCBldmVudDogRGljdCk6CiAgICAgICAgZW5kcG9pbnRfaWQgPSBldmVudFtFTkRQT0lOVF9JRF0KCiAgICAgICAgaWYgZW5kcG9pbnRfaWQgbm90IGluIHNlbGYuZmVhdHVyZV9uYW1lczoKICAgICAgICAgICAgZW5kcG9pbnRfcmVjb3JkID0gZ2V0X2VuZHBvaW50X3JlY29yZCgKICAgICAgICAgICAgICAgIGt2X2NvbnRhaW5lcj1zZWxmLmt2X2NvbnRhaW5lciwKICAgICAgICAgICAgICAgIGt2X3BhdGg9c2VsZi5rdl9wYXRoLAogICAgICAgICAgICAgICAgZW5kcG9pbnRfaWQ9ZW5kcG9pbnRfaWQsCiAgICAgICAgICAgICAgICBhY2Nlc3Nfa2V5PXNlbGYuYWNjZXNzX2tleSwKICAgICAgICAgICAgKQogICAgICAgICAgICBmZWF0dXJlX25hbWVzID0gZW5kcG9pbnRfcmVjb3JkLmdldChGRUFUVVJFX05BTUVTKQogICAgICAgICAgICBmZWF0dXJlX25hbWVzID0ganNvbi5sb2FkcyhmZWF0dXJlX25hbWVzKSBpZiBmZWF0dXJlX25hbWVzIGVsc2UgTm9uZQoKICAgICAgICAgICAgbGFiZWxfY29sdW1ucyA9IGVuZHBvaW50X3JlY29yZC5nZXQoTEFCRUxfQ09MVU1OUykKICAgICAgICAgICAgbGFiZWxfY29sdW1ucyA9IGpzb24ubG9hZHMobGFiZWxfY29sdW1ucykgaWYgbGFiZWxfY29sdW1ucyBlbHNlIE5vbmUKCiAgICAgICAgICAgIGlmIG5vdCBmZWF0dXJlX25hbWVzIGFuZCBzZWxmLl9pbmZlcl9jb2x1bW5zX2Zyb21fZGF0YToKICAgICAgICAgICAgICAgIGZlYXR1cmVfbmFtZXMgPSBzZWxmLl9pbmZlcl9mZWF0dXJlX25hbWVzX2Zyb21fZGF0YShldmVudCkKCiAgICAgICAgICAgIGlmIG5vdCBmZWF0dXJlX25hbWVzOgogICAgICAgICAgICAgICAgbG9nZ2VyLndhcm4oCiAgICAgICAgICAgICAgICAgICAgIkZlYXR1cmUgbmFtZXMgYXJlIG5vdCBpbml0aWFsaXplZCwgdGhleSB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIiwKICAgICAgICAgICAgICAgICAgICBlbmRwb2ludF9pZD1lbmRwb2ludF9pZCwKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIGZlYXR1cmVfbmFtZXMgPSBbZiJme2l9IiBmb3IgaSwgXyBpbiBlbnVtZXJhdGUoZXZlbnRbRkVBVFVSRVNdKV0KICAgICAgICAgICAgICAgIGdldF92M2lvX2NsaWVudCgpLmt2LnVwZGF0ZSgKICAgICAgICAgICAgICAgICAgICBjb250YWluZXI9c2VsZi5rdl9jb250YWluZXIsCiAgICAgICAgICAgICAgICAgICAgdGFibGVfcGF0aD1zZWxmLmt2X3BhdGgsCiAgICAgICAgICAgICAgICAgICAgYWNjZXNzX2tleT1zZWxmLmFjY2Vzc19rZXksCiAgICAgICAgICAgICAgICAgICAga2V5PWV2ZW50W0VORFBPSU5UX0lEXSwKICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzPXtGRUFUVVJFX05BTUVTOiBqc29uLmR1bXBzKGZlYXR1cmVfbmFtZXMpfSwKICAgICAgICAgICAgICAgICAgICByYWlzZV9mb3Jfc3RhdHVzPVJhaXNlRm9yU3RhdHVzLmFsd2F5cywKICAgICAgICAgICAgICAgICkKCiAgICAgICAgICAgIGlmIG5vdCBsYWJlbF9jb2x1bW5zIGFuZCBzZWxmLl9pbmZlcl9jb2x1bW5zX2Zyb21fZGF0YToKICAgICAgICAgICAgICAgIGxhYmVsX2NvbHVtbnMgPSBzZWxmLl9pbmZlcl9sYWJlbF9jb2x1bW5zX2Zyb21fZGF0YShldmVudCkKCiAgICAgICAgICAgIGlmIG5vdCBsYWJlbF9jb2x1bW5zOgogICAgICAgICAgICAgICAgbG9nZ2VyLndhcm4oCiAgICAgICAgICAgICAgICAgICAgImxhYmVsIGNvbHVtbiBuYW1lcyBhcmUgbm90IGluaXRpYWxpemVkLCB0aGV5IHdpbGwgYmUgYXV0b21hdGljYWxseSBnZW5lcmF0ZWQiLAogICAgICAgICAgICAgICAgICAgIGVuZHBvaW50X2lkPWVuZHBvaW50X2lkLAogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgbGFiZWxfY29sdW1ucyA9IFtmInB7aX0iIGZvciBpLCBfIGluIGVudW1lcmF0ZShldmVudFtQUkVESUNUSU9OXSldCiAgICAgICAgICAgICAgICBnZXRfdjNpb19jbGllbnQoKS5rdi51cGRhdGUoCiAgICAgICAgICAgICAgICAgICAgY29udGFpbmVyPXNlbGYua3ZfY29udGFpbmVyLAogICAgICAgICAgICAgICAgICAgIHRhYmxlX3BhdGg9c2VsZi5rdl9wYXRoLAogICAgICAgICAgICAgICAgICAgIGFjY2Vzc19rZXk9c2VsZi5hY2Nlc3Nfa2V5LAogICAgICAgICAgICAgICAgICAgIGtleT1ldmVudFtFTkRQT0lOVF9JRF0sCiAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlcz17TEFCRUxfQ09MVU1OUzoganNvbi5kdW1wcyhsYWJlbF9jb2x1bW5zKX0sCiAgICAgICAgICAgICAgICAgICAgcmFpc2VfZm9yX3N0YXR1cz1SYWlzZUZvclN0YXR1cy5hbHdheXMsCiAgICAgICAgICAgICAgICApCgogICAgICAgICAgICBzZWxmLmxhYmVsX2NvbHVtbnNbZW5kcG9pbnRfaWRdID0gbGFiZWxfY29sdW1ucwogICAgICAgICAgICBzZWxmLmZlYXR1cmVfbmFtZXNbZW5kcG9pbnRfaWRdID0gZmVhdHVyZV9uYW1lcwoKICAgICAgICAgICAgbG9nZ2VyLmluZm8oCiAgICAgICAgICAgICAgICAiTGFiZWwgY29sdW1ucyIsIGVuZHBvaW50X2lkPWVuZHBvaW50X2lkLCBsYWJlbF9jb2x1bW5zPWxhYmVsX2NvbHVtbnMKICAgICAgICAgICAgKQogICAgICAgICAgICBsb2dnZXIuaW5mbygKICAgICAgICAgICAgICAgICJGZWF0dXJlIG5hbWVzIiwgZW5kcG9pbnRfaWQ9ZW5kcG9pbnRfaWQsIGZlYXR1cmVfbmFtZXM9ZmVhdHVyZV9uYW1lcwogICAgICAgICAgICApCgogICAgICAgIGZlYXR1cmVfbmFtZXMgPSBzZWxmLmZlYXR1cmVfbmFtZXNbZW5kcG9pbnRfaWRdCiAgICAgICAgZmVhdHVyZXMgPSBldmVudFtGRUFUVVJFU10KICAgICAgICBldmVudFtOQU1FRF9GRUFUVVJFU10gPSB7CiAgICAgICAgICAgIG5hbWU6IGZlYXR1cmUgZm9yIG5hbWUsIGZlYXR1cmUgaW4gemlwKGZlYXR1cmVfbmFtZXMsIGZlYXR1cmVzKQogICAgICAgIH0KCiAgICAgICAgbGFiZWxfY29sdW1ucyA9IHNlbGYubGFiZWxfY29sdW1uc1tlbmRwb2ludF9pZF0KICAgICAgICBwcmVkaWN0aW9uID0gZXZlbnRbUFJFRElDVElPTl0KICAgICAgICBldmVudFtOQU1FRF9QUkVESUNUSU9OU10gPSB7CiAgICAgICAgICAgIG5hbWU6IHByZWRpY3Rpb24gZm9yIG5hbWUsIHByZWRpY3Rpb24gaW4gemlwKGxhYmVsX2NvbHVtbnMsIHByZWRpY3Rpb24pCiAgICAgICAgfQogICAgICAgIGxvZ2dlci5pbmZvKCJNYXBwZWQgZXZlbnQiLCBldmVudD1ldmVudCkKICAgICAgICByZXR1cm4gZXZlbnQKCgpjbGFzcyBXcml0ZVRvS1YoTWFwQ2xhc3MpOgogICAgZGVmIF9faW5pdF9fKHNlbGYsIGNvbnRhaW5lcjogc3RyLCB0YWJsZTogc3RyLCAqKmt3YXJncyk6CiAgICAgICAgc3VwZXIoKS5fX2luaXRfXygqKmt3YXJncykKICAgICAgICBzZWxmLmNvbnRhaW5lciA9IGNvbnRhaW5lcgogICAgICAgIHNlbGYudGFibGUgPSB0YWJsZQoKICAgIGRlZiBkbyhzZWxmLCBldmVudDogRGljdCk6CiAgICAgICAgZ2V0X3YzaW9fY2xpZW50KCkua3YudXBkYXRlKAogICAgICAgICAgICBjb250YWluZXI9c2VsZi5jb250YWluZXIsCiAgICAgICAgICAgIHRhYmxlX3BhdGg9c2VsZi50YWJsZSwKICAgICAgICAgICAga2V5PWV2ZW50W0VORFBPSU5UX0lEXSwKICAgICAgICAgICAgYXR0cmlidXRlcz1ldmVudCwKICAgICAgICApCiAgICAgICAgcmV0dXJuIGV2ZW50CgoKY2xhc3MgSW5mZXJTY2hlbWEoTWFwQ2xhc3MpOgogICAgZGVmIF9faW5pdF9fKAogICAgICAgIHNlbGYsCiAgICAgICAgdjNpb19hY2Nlc3Nfa2V5OiBzdHIsCiAgICAgICAgdjNpb19mcmFtZXNkOiBzdHIsCiAgICAgICAgY29udGFpbmVyOiBzdHIsCiAgICAgICAgdGFibGU6IHN0ciwKICAgICAgICAqKmt3YXJncywKICAgICk6CiAgICAgICAgc3VwZXIoKS5fX2luaXRfXygqKmt3YXJncykKICAgICAgICBzZWxmLmNvbnRhaW5lciA9IGNvbnRhaW5lcgogICAgICAgIHNlbGYudjNpb19hY2Nlc3Nfa2V5ID0gdjNpb19hY2Nlc3Nfa2V5CiAgICAgICAgc2VsZi52M2lvX2ZyYW1lc2QgPSB2M2lvX2ZyYW1lc2QKICAgICAgICBzZWxmLnRhYmxlID0gdGFibGUKICAgICAgICBzZWxmLmtleXMgPSBzZXQoKQoKICAgIGRlZiBkbyhzZWxmLCBldmVudDogRGljdCk6CiAgICAgICAga2V5X3NldCA9IHNldChldmVudC5rZXlzKCkpCiAgICAgICAgaWYgbm90IGtleV9zZXQuaXNzdWJzZXQoc2VsZi5rZXlzKToKICAgICAgICAgICAgc2VsZi5rZXlzLnVwZGF0ZShrZXlfc2V0KQogICAgICAgICAgICBnZXRfZnJhbWVzX2NsaWVudCgKICAgICAgICAgICAgICAgIHRva2VuPXNlbGYudjNpb19hY2Nlc3Nfa2V5LAogICAgICAgICAgICAgICAgY29udGFpbmVyPXNlbGYuY29udGFpbmVyLAogICAgICAgICAgICAgICAgYWRkcmVzcz1zZWxmLnYzaW9fZnJhbWVzZCwKICAgICAgICAgICAgKS5leGVjdXRlKGJhY2tlbmQ9Imt2IiwgdGFibGU9c2VsZi50YWJsZSwgY29tbWFuZD0iaW5mZXJfc2NoZW1hIikKICAgICAgICAgICAgbG9nZ2VyLmluZm8oCiAgICAgICAgICAgICAgICAiRm91bmQgbmV3IGtleXMsIGluZmVycmVkIHNjaGVtYSIsIHRhYmxlPXNlbGYudGFibGUsIGV2ZW50PWV2ZW50CiAgICAgICAgICAgICkKICAgICAgICByZXR1cm4gZXZlbnQKCgpkZWYgZ2V0X2VuZHBvaW50X3JlY29yZCgKICAgIGt2X2NvbnRhaW5lcjogc3RyLCBrdl9wYXRoOiBzdHIsIGVuZHBvaW50X2lkOiBzdHIsIGFjY2Vzc19rZXk6IHN0cgopIC0+IE9wdGlvbmFsW2RpY3RdOgogICAgbG9nZ2VyLmluZm8oCiAgICAgICAgIkdyYWJiaW5nIGVuZHBvaW50IGRhdGEiLAogICAgICAgIGNvbnRhaW5lcj1rdl9jb250YWluZXIsCiAgICAgICAgdGFibGVfcGF0aD1rdl9wYXRoLAogICAgICAgIGtleT1lbmRwb2ludF9pZCwKICAgICkKICAgIHRyeToKICAgICAgICBlbmRwb2ludF9yZWNvcmQgPSAoCiAgICAgICAgICAgIGdldF92M2lvX2NsaWVudCgpCiAgICAgICAgICAgIC5rdi5nZXQoCiAgICAgICAgICAgICAgICBjb250YWluZXI9a3ZfY29udGFpbmVyLAogICAgICAgICAgICAgICAgdGFibGVfcGF0aD1rdl9wYXRoLAogICAgICAgICAgICAgICAga2V5PWVuZHBvaW50X2lkLAogICAgICAgICAgICAgICAgYWNjZXNzX2tleT1hY2Nlc3Nfa2V5LAogICAgICAgICAgICAgICAgcmFpc2VfZm9yX3N0YXR1cz12M2lvLmRhdGFwbGFuZS5SYWlzZUZvclN0YXR1cy5hbHdheXMsCiAgICAgICAgICAgICkKICAgICAgICAgICAgLm91dHB1dC5pdGVtCiAgICAgICAgKQogICAgICAgIHJldHVybiBlbmRwb2ludF9yZWNvcmQKICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgcmV0dXJuIE5vbmUKCmZyb20gbWxydW4ucnVudGltZXMgaW1wb3J0IG51Y2xpb19pbml0X2hvb2sKZGVmIGluaXRfY29udGV4dChjb250ZXh0KToKICAgIG51Y2xpb19pbml0X2hvb2soY29udGV4dCwgZ2xvYmFscygpLCAnc2VydmluZ192MicpCgpkZWYgaGFuZGxlcihjb250ZXh0LCBldmVudCk6CiAgICByZXR1cm4gY29udGV4dC5tbHJ1bl9oYW5kbGVyKGNvbnRleHQsIGV2ZW50KQo=", + "baseImage": "datanode-registry.iguazio-platform.app.product-3-4.iguazio-cd1.com:80/quay.io/mlrun/mlrun:1.0.0" }, - "limits": { - "memory": "20Gi", - "cpu": "2" - } - }, - "priority_class_name": "igz-workload-medium", - "preemption_mode": "prevent", - "min_replicas": 1, - "max_replicas": 1, - "config": { - "spec.triggers.monitoring_stream_trigger": { + "triggers": { + "monitoring_stream_trigger": { "kind": "v3ioStream", "url": "http://v3io-webapi:8081", "attributes": { - "containerName": "users", - "streamPath": "pipelines/default/model-endpoints/stream", - "consumerGroup": "serving", - "sequenceNumberCommitInterval": "1s", - "workerAllocationMode": "pool", - "sessionTimeout": "10s", - "heartbeatInterval": "3s", - "seekTo": "earliest", - "readBatchSize": 256, - "pollingIntervalMs": 500 + "containerName": "users", + "streamPath": "pipelines/default/model-endpoints/stream", + "consumerGroup": "serving", + "sequenceNumberCommitInterval": "1s", + "workerAllocationMode": "pool", + "sessionTimeout": "10s", + "heartbeatInterval": "3s", + "seekTo": "earliest", + "readBatchSize": 256, + "pollingIntervalMs": 500 }, "name": "monitoring_stream_trigger", "maxWorkers": 1, "password": "76ceea19-4b10-47d9-afbb-f687c91b9231" - }, - "metadata.labels.mlrun/class": "serving", - "spec.runtime": "python:3.7", - "spec.serviceType": "ClusterIP", - "spec.resources": { - "requests": { - "memory": "1Mi", - "cpu": "25m" - }, - "limits": { - "memory": "20Gi", - "cpu": "2" + }, + "http": { + "kind": "http", + "name": "http", + "maxWorkers": 1, + "workerAvailabilityTimeoutMilliseconds": 10000, + "attributes": { + "ingresses": { + "0": { + "paths": [ + "/" + ], + "hostTemplate": "@nuclio.fromDefault" + } + }, + "serviceType": "ClusterIP" } + } }, - "spec.PreemptionMode": "prevent", - "spec.priorityClassName": "igz-workload-medium", - "spec.minReplicas": 1, - "spec.maxReplicas": 1 + "serviceType": "ClusterIP", + "resources": { + "requests": { + "memory": "1Mi", + "cpu": "25m" + }, + "limits": { + "memory": "20Gi", + "cpu": "2" + } + }, + "PreemptionMode": "prevent", + "priorityClassName": "igz-workload-medium", + "minReplicas": 1, + "maxReplicas": 1 + } }, - "base_spec": { - "apiVersion": "nuclio.io/v1", - "kind": "Function", - "metadata": { - "name": "default-model-monitoring-stream", - "labels": { - "mlrun/class": "serving", - "nuclio.io/project-name": "default" - }, - "annotations": { - "nuclio.io/generated_by": "function generated from /mlrun/mlrun/model_monitoring/stream_processing_fs.py" - } + "source": "", + "function_kind": "serving_v2", + "graph": { + "steps": { + "ProcessEndpointEvent": { + "kind": "task", + "class_name": "ProcessEndpointEvent", + "class_args": { + "kv_container": "users", + "kv_path": "pipelines/default/model-endpoints/endpoints/", + "v3io_access_key": "76ceea19-4b10-47d9-afbb-f687c91b9231" + }, + "full_event": true }, - "spec": { - "runtime": "python:3.7", - "handler": "stream_processing_fs:handler", - "env": [ - { - "name": "V3IO_API", - "value": "http://v3io-webapi:8081" - }, - { - "name": "V3IO_USERNAME", - "value": "pipelines" - }, - { - "name": "V3IO_FRAMESD", - "value": "http://framesd:8080" - }, - { - "name": "MLRUN_DEFAULT_PROJECT", - "value": "azureml-admin" - }, - { - "name": "MLRUN_DBPATH", - "value": "http://mlrun-api:8080" - }, - { - "name": "MLRUN_NAMESPACE", - "value": "default-tenant" - }, - { - "name": "MLRUN_AUTH_SESSION", - "valueFrom": { - "secretKeyRef": { - "key": "accessKey", - "name": "mlrun-auth-secrets.36ade9f8ae7bddc0fc42b8c701469b8d23268177977bd695c36ed51c" - } - } - }, - { - "name": "SERVING_SPEC_ENV", - "value": "{\"function_uri\": \"azureml-admin/model-monitoring-stream\", \"version\": \"v2\", \"parameters\": {\"infer_options\": 0, \"overwrite\": null, \"featureset\": \"store://feature-sets/azureml-admin/monitoring\", \"source\": {\"kind\": \"http\", \"online\": true}, \"targets\": [{\"name\": \"parquet\", \"kind\": \"parquet\", \"path\": \"v3io:///projects/azureml-admin/model-endpoints/parquet\", \"after_step\": \"ProcessBeforeParquet\", \"attributes\": {\"infer_columns_from_data\": true}, \"partitioned\": true, \"key_bucketing_number\": 0, \"time_partitioning_granularity\": \"hour\", \"max_events\": 10000, \"flush_after_seconds\": 1800, \"storage_options\": {\"v3io_access_key\": \"55a0d13c-7d9a-44ab-a556-dd213d8c7165\", \"v3io_api\": \"http://v3io-webapi:8081\"}}]}, \"graph\": {\"steps\": {\"ProcessEndpointEvent\": {\"kind\": \"task\", \"class_name\": \"ProcessEndpointEvent\", \"class_args\": {\"kv_container\": \"users\", \"kv_path\": \"pipelines/azureml-admin/model-endpoints/endpoints/\", \"v3io_access_key\": \"76ceea19-4b10-47d9-afbb-f687c91b9231\"}, \"full_event\": true}, \"filter_none\": {\"kind\": \"task\", \"class_name\": \"storey.Filter\", \"class_args\": {\"_fn\": \"(event is not None)\"}, \"after\": [\"ProcessEndpointEvent\"]}, \"flatten_events\": {\"kind\": \"task\", \"class_name\": \"storey.FlatMap\", \"class_args\": {\"_fn\": \"(event)\"}, \"after\": [\"filter_none\"]}, \"MapFeatureNames\": {\"kind\": \"task\", \"class_name\": \"MapFeatureNames\", \"class_args\": {\"kv_container\": \"users\", \"kv_path\": \"pipelines/azureml-admin/model-endpoints/endpoints/\", \"access_key\": \"76ceea19-4b10-47d9-afbb-f687c91b9231\", \"infer_columns_from_data\": true}, \"after\": [\"flatten_events\"]}, \"Aggregates\": {\"kind\": \"task\", \"class_name\": \"storey.AggregateByKey\", \"class_args\": {\"aggregates\": [{\"name\": \"predictions\", \"column\": \"endpoint_id\", \"operations\": [\"count\"], \"windows\": [\"5m\", \"1h\"], \"period\": \"30s\"}, {\"name\": \"latency\", \"column\": \"latency\", \"operations\": [\"avg\"], \"windows\": [\"5m\", \"1h\"], \"period\": \"30s\"}], \"table\": \".\"}, \"after\": [\"MapFeatureNames\"]}, \"sample\": {\"kind\": \"task\", \"class_name\": \"storey.steps.SampleWindow\", \"class_args\": {\"window_size\": 10, \"key\": \"endpoint_id\"}, \"after\": [\"Aggregates\"]}, \"ProcessBeforeKV\": {\"kind\": \"task\", \"class_name\": \"ProcessBeforeKV\", \"after\": [\"sample\"]}, \"WriteToKV\": {\"kind\": \"task\", \"class_name\": \"WriteToKV\", \"class_args\": {\"container\": \"users\", \"table\": \"pipelines/azureml-admin/model-endpoints/endpoints/\"}, \"after\": [\"ProcessBeforeKV\"]}, \"InferSchema\": {\"kind\": \"task\", \"class_name\": \"InferSchema\", \"class_args\": {\"v3io_access_key\": \"76ceea19-4b10-47d9-afbb-f687c91b9231\", \"v3io_framesd\": \"http://framesd:8080\", \"container\": \"users\", \"table\": \"pipelines/azureml-admin/model-endpoints/endpoints/\"}, \"after\": [\"WriteToKV\"]}, \"ProcessBeforeTSDB\": {\"kind\": \"task\", \"class_name\": \"ProcessBeforeTSDB\", \"after\": [\"sample\"]}, \"FilterAndUnpackKeys1\": {\"kind\": \"task\", \"class_name\": \"FilterAndUnpackKeys\", \"class_args\": {\"keys\": [\"base_metrics\"]}, \"after\": [\"ProcessBeforeTSDB\"]}, \"tsdb1\": {\"kind\": \"task\", \"class_name\": \"storey.TSDBTarget\", \"class_args\": {\"path\": \"users/pipelines/azureml-admin/model-endpoints/events/\", \"rate\": \"10/m\", \"time_col\": \"timestamp\", \"container\": \"users\", \"access_key\": \"76ceea19-4b10-47d9-afbb-f687c91b9231\", \"v3io_frames\": \"http://framesd:8080\", \"index_cols\": [\"endpoint_id\", \"record_type\"], \"max_events\": 10, \"timeout_secs\": 300, \"key\": \"endpoint_id\"}, \"after\": [\"FilterAndUnpackKeys1\"]}, \"FilterAndUnpackKeys2\": {\"kind\": \"task\", \"class_name\": \"FilterAndUnpackKeys\", \"class_args\": {\"keys\": [\"endpoint_features\"]}, \"after\": [\"ProcessBeforeTSDB\"]}, \"tsdb2\": {\"kind\": \"task\", \"class_name\": \"storey.TSDBTarget\", \"class_args\": {\"path\": \"users/pipelines/azureml-admin/model-endpoints/events/\", \"rate\": \"10/m\", \"time_col\": \"timestamp\", \"container\": \"users\", \"access_key\": \"76ceea19-4b10-47d9-afbb-f687c91b9231\", \"v3io_frames\": \"http://framesd:8080\", \"index_cols\": [\"endpoint_id\", \"record_type\"], \"max_events\": 10, \"timeout_secs\": 300, \"key\": \"endpoint_id\"}, \"after\": [\"FilterAndUnpackKeys2\"]}, \"FilterAndUnpackKeys3\": {\"kind\": \"task\", \"class_name\": \"FilterAndUnpackKeys\", \"class_args\": {\"keys\": [\"custom_metrics\"]}, \"after\": [\"ProcessBeforeTSDB\"]}, \"FilterNotNone\": {\"kind\": \"task\", \"class_name\": \"storey.Filter\", \"class_args\": {\"_fn\": \"(event is not None)\"}, \"after\": [\"FilterAndUnpackKeys3\"]}, \"tsdb3\": {\"kind\": \"task\", \"class_name\": \"storey.TSDBTarget\", \"class_args\": {\"path\": \"users/pipelines/azureml-admin/model-endpoints/events/\", \"rate\": \"10/m\", \"time_col\": \"timestamp\", \"container\": \"users\", \"access_key\": \"76ceea19-4b10-47d9-afbb-f687c91b9231\", \"v3io_frames\": \"http://framesd:8080\", \"index_cols\": [\"endpoint_id\", \"record_type\"], \"max_events\": 10, \"timeout_secs\": 300, \"key\": \"endpoint_id\"}, \"after\": [\"FilterNotNone\"]}, \"ProcessBeforeParquet\": {\"kind\": \"task\", \"class_name\": \"ProcessBeforeParquet\", \"class_args\": {\"_fn\": \"(event)\"}, \"after\": [\"MapFeatureNames\"]}}, \"final_step\": \"ProcessBeforeParquet\"}, \"load_mode\": null, \"functions\": {}, \"graph_initializer\": \"mlrun.feature_store.ingestion.featureset_initializer\", \"error_stream\": null, \"track_models\": null, \"default_content_type\": null}" - }, - { - "name": "MODEL_MONITORING_ACCESS_KEY", - "valueFrom": { - "secretKeyRef": { - "key": "mlrun.model-monitoring.MODEL_MONITORING_ACCESS_KEY", - "name": "mlrun-project-secrets-default" - } - } - }, - { - "name": "V3IO_ACCESS_KEY", - "valueFrom": { - "secretKeyRef": { - "key": "accessKey", - "name": "mlrun-auth-secrets.27111631aff0f77b2ca9e3f972065f482a58b63645f0afd8d231028f" - } - } - }, - { - "name": "MLRUN_K8S_SECRET__AZURE_RESOURCE_GROUP", - "valueFrom": { - "secretKeyRef": { - "key": "AZURE_RESOURCE_GROUP", - "name": "mlrun-project-secrets-default" - } - } - }, - { - "name": "MLRUN_K8S_SECRET__AZURE_SERVICE_PRINCIPAL_ID", - "valueFrom": { - "secretKeyRef": { - "key": "AZURE_SERVICE_PRINCIPAL_ID", - "name": "mlrun-project-secrets-default" - } - } - }, - { - "name": "MLRUN_K8S_SECRET__AZURE_SERVICE_PRINCIPAL_PASSWORD", - "valueFrom": { - "secretKeyRef": { - "key": "AZURE_SERVICE_PRINCIPAL_PASSWORD", - "name": "mlrun-project-secrets-default" - } - } - }, - { - "name": "MLRUN_K8S_SECRET__AZURE_STORAGE_CONNECTION_STRING", - "valueFrom": { - "secretKeyRef": { - "key": "AZURE_STORAGE_CONNECTION_STRING", - "name": "mlrun-project-secrets-default" - } - } - }, - { - "name": "MLRUN_K8S_SECRET__AZURE_SUBSCRIPTION_ID", - "valueFrom": { - "secretKeyRef": { - "key": "AZURE_SUBSCRIPTION_ID", - "name": "mlrun-project-secrets-default" - } - } - }, - { - "name": "MLRUN_K8S_SECRET__AZURE_TENANT_ID", - "valueFrom": { - "secretKeyRef": { - "key": "AZURE_TENANT_ID", - "name": "mlrun-project-secrets-default" - } - } - }, - { - "name": "MLRUN_K8S_SECRET__AZURE_WORKSPACE_NAME", - "valueFrom": { - "secretKeyRef": { - "key": "AZURE_WORKSPACE_NAME", - "name": "mlrun-project-secrets-default" - } - } - } + "filter_none": { + "kind": "task", + "class_name": "storey.Filter", + "class_args": { + "_fn": "(event is not None)" + }, + "after": [ + "ProcessEndpointEvent" + ] + }, + "flatten_events": { + "kind": "task", + "class_name": "storey.FlatMap", + "class_args": { + "_fn": "(event)" + }, + "after": [ + "filter_none" + ] + }, + "MapFeatureNames": { + "kind": "task", + "class_name": "MapFeatureNames", + "class_args": { + "kv_container": "users", + "kv_path": "pipelines/default/model-endpoints/endpoints/", + "access_key": "76ceea19-4b10-47d9-afbb-f687c91b9231", + "infer_columns_from_data": true + }, + "after": [ + "flatten_events" + ] + }, + "Aggregates": { + "kind": "task", + "class_name": "storey.AggregateByKey", + "class_args": { + "aggregates": [ + { + "name": "predictions", + "column": "endpoint_id", + "operations": [ + "count" + ], + "windows": [ + "5m", + "1h" + ], + "period": "30s" + }, + { + "name": "latency", + "column": "latency", + "operations": [ + "avg" + ], + "windows": [ + "5m", + "1h" + ], + "period": "30s" + } + ], + "table": "." + }, + "after": [ + "MapFeatureNames" + ] + }, + "sample": { + "kind": "task", + "class_name": "storey.steps.SampleWindow", + "class_args": { + "window_size": 10, + "key": "endpoint_id" + }, + "after": [ + "Aggregates" + ] + }, + "ProcessBeforeKV": { + "kind": "task", + "class_name": "ProcessBeforeKV", + "after": [ + "sample" + ] + }, + "WriteToKV": { + "kind": "task", + "class_name": "WriteToKV", + "class_args": { + "container": "users", + "table": "pipelines/default/model-endpoints/endpoints/" + }, + "after": [ + "ProcessBeforeKV" + ] + }, + "InferSchema": { + "kind": "task", + "class_name": "InferSchema", + "class_args": { + "v3io_access_key": "76ceea19-4b10-47d9-afbb-f687c91b9231", + "v3io_framesd": "http://framesd:8080", + "container": "users", + "table": "pipelines/default/model-endpoints/endpoints/" + }, + "after": [ + "WriteToKV" + ] + }, + "ProcessBeforeTSDB": { + "kind": "task", + "class_name": "ProcessBeforeTSDB", + "after": [ + "sample" + ] + }, + "FilterAndUnpackKeys1": { + "kind": "task", + "class_name": "FilterAndUnpackKeys", + "class_args": { + "keys": [ + "base_metrics" + ] + }, + "after": [ + "ProcessBeforeTSDB" + ] + }, + "tsdb1": { + "kind": "task", + "class_name": "storey.TSDBTarget", + "class_args": { + "path": "users/pipelines/default/model-endpoints/events/", + "rate": "10/m", + "time_col": "timestamp", + "container": "users", + "access_key": "76ceea19-4b10-47d9-afbb-f687c91b9231", + "v3io_frames": "http://framesd:8080", + "index_cols": [ + "endpoint_id", + "record_type" + ], + "max_events": 10, + "timeout_secs": 300, + "key": "endpoint_id" + }, + "after": [ + "FilterAndUnpackKeys1" + ] + }, + "FilterAndUnpackKeys2": { + "kind": "task", + "class_name": "FilterAndUnpackKeys", + "class_args": { + "keys": [ + "endpoint_features" + ] + }, + "after": [ + "ProcessBeforeTSDB" + ] + }, + "tsdb2": { + "kind": "task", + "class_name": "storey.TSDBTarget", + "class_args": { + "path": "users/pipelines/default/model-endpoints/events/", + "rate": "10/m", + "time_col": "timestamp", + "container": "users", + "access_key": "76ceea19-4b10-47d9-afbb-f687c91b9231", + "v3io_frames": "http://framesd:8080", + "index_cols": [ + "endpoint_id", + "record_type" + ], + "max_events": 10, + "timeout_secs": 300, + "key": "endpoint_id" + }, + "after": [ + "FilterAndUnpackKeys2" + ] + }, + "FilterAndUnpackKeys3": { + "kind": "task", + "class_name": "FilterAndUnpackKeys", + "class_args": { + "keys": [ + "custom_metrics" + ] + }, + "after": [ + "ProcessBeforeTSDB" + ] + }, + "FilterNotNone": { + "kind": "task", + "class_name": "storey.Filter", + "class_args": { + "_fn": "(event is not None)" + }, + "after": [ + "FilterAndUnpackKeys3" + ] + }, + "tsdb3": { + "kind": "task", + "class_name": "storey.TSDBTarget", + "class_args": { + "path": "users/pipelines/default/model-endpoints/events/", + "rate": "10/m", + "time_col": "timestamp", + "container": "users", + "access_key": "76ceea19-4b10-47d9-afbb-f687c91b9231", + "v3io_frames": "http://framesd:8080", + "index_cols": [ + "endpoint_id", + "record_type" ], - "volumes": [], - "build": { - "commands": [], - "noBaseImagesPull": true, - "functionSourceCode": "aW1wb3J0IGpzb24KaW1wb3J0IG9zCmZyb20gY29sbGVjdGlvbnMgaW1wb3J0IGRlZmF1bHRkaWN0CmZyb20gb3MgaW1wb3J0IGVudmlyb24KZnJvbSB0eXBpbmcgaW1wb3J0IEFueSwgRGljdCwgTGlzdCwgT3B0aW9uYWwsIFNldCwgVW5pb24KCmltcG9ydCBwYW5kYXMgYXMgcGQKaW1wb3J0IHYzaW8KCiMgQ29uc3RhbnRzCmZyb20gc3RvcmV5IGltcG9ydCBFdmVudApmcm9tIHYzaW8uZGF0YXBsYW5lIGltcG9ydCBSYWlzZUZvclN0YXR1cwoKaW1wb3J0IG1scnVuLmZlYXR1cmVfc3RvcmUgYXMgZnMKZnJvbSBtbHJ1bi5jb25maWcgaW1wb3J0IGNvbmZpZwpmcm9tIG1scnVuLmRhdGFzdG9yZS50YXJnZXRzIGltcG9ydCBQYXJxdWV0VGFyZ2V0CmZyb20gbWxydW4uZmVhdHVyZV9zdG9yZS5zdGVwcyBpbXBvcnQgTWFwQ2xhc3MKZnJvbSBtbHJ1bi51dGlscyBpbXBvcnQgbG9nZ2VyCmZyb20gbWxydW4udXRpbHMubW9kZWxfbW9uaXRvcmluZyBpbXBvcnQgKAogICAgY3JlYXRlX21vZGVsX2VuZHBvaW50X2lkLAogICAgcGFyc2VfbW9kZWxfZW5kcG9pbnRfc3RvcmVfcHJlZml4LAopCmZyb20gbWxydW4udXRpbHMudjNpb19jbGllbnRzIGltcG9ydCBnZXRfZnJhbWVzX2NsaWVudCwgZ2V0X3YzaW9fY2xpZW50CgpJU09fODA2MV9VVEMgPSAiJVktJW0tJWQgJUg6JU06JVMuJWYleiIKRlVOQ1RJT05fVVJJID0gImZ1bmN0aW9uX3VyaSIKTU9ERUwgPSAibW9kZWwiClZFUlNJT04gPSAidmVyc2lvbiIKVkVSU0lPTkVEX01PREVMID0gInZlcnNpb25lZF9tb2RlbCIKTU9ERUxfQ0xBU1MgPSAibW9kZWxfY2xhc3MiClRJTUVTVEFNUCA9ICJ0aW1lc3RhbXAiCkVORFBPSU5UX0lEID0gImVuZHBvaW50X2lkIgpSRVFVRVNUX0lEID0gInJlcXVlc3RfaWQiCkxBQkVMUyA9ICJsYWJlbHMiClVOUEFDS0VEX0xBQkVMUyA9ICJ1bnBhY2tlZF9sYWJlbHMiCkxBVEVOQ1lfQVZHXzVNID0gImxhdGVuY3lfYXZnXzVtIgpMQVRFTkNZX0FWR18xSCA9ICJsYXRlbmN5X2F2Z18xaCIKUFJFRElDVElPTlNfUEVSX1NFQ09ORCA9ICJwcmVkaWN0aW9uc19wZXJfc2Vjb25kIgpQUkVESUNUSU9OU19DT1VOVF81TSA9ICJwcmVkaWN0aW9uc19jb3VudF81bSIKUFJFRElDVElPTlNfQ09VTlRfMUggPSAicHJlZGljdGlvbnNfY291bnRfMWgiCkZJUlNUX1JFUVVFU1QgPSAiZmlyc3RfcmVxdWVzdCIKTEFTVF9SRVFVRVNUID0gImxhc3RfcmVxdWVzdCIKRVJST1JfQ09VTlQgPSAiZXJyb3JfY291bnQiCkVOVElUSUVTID0gImVudGl0aWVzIgpGRUFUVVJFX05BTUVTID0gImZlYXR1cmVfbmFtZXMiCkxBQkVMX0NPTFVNTlMgPSAibGFiZWxfY29sdW1ucyIKTEFURU5DWSA9ICJsYXRlbmN5IgpSRUNPUkRfVFlQRSA9ICJyZWNvcmRfdHlwZSIKRkVBVFVSRVMgPSAiZmVhdHVyZXMiClBSRURJQ1RJT04gPSAicHJlZGljdGlvbiIKUFJFRElDVElPTlMgPSAicHJlZGljdGlvbnMiCk5BTUVEX0ZFQVRVUkVTID0gIm5hbWVkX2ZlYXR1cmVzIgpOQU1FRF9QUkVESUNUSU9OUyA9ICJuYW1lZF9wcmVkaWN0aW9ucyIKQkFTRV9NRVRSSUNTID0gImJhc2VfbWV0cmljcyIKQ1VTVE9NX01FVFJJQ1MgPSAiY3VzdG9tX21ldHJpY3MiCkVORFBPSU5UX0ZFQVRVUkVTID0gImVuZHBvaW50X2ZlYXR1cmVzIgpNRVRSSUNTID0gIm1ldHJpY3MiCkJBVENIX1RJTUVTVEFNUCA9ICJiYXRjaF90aW1lc3RhbXAiClRJTUVfRk9STUFUOiBzdHIgPSAiJVktJW0tJWQgJUg6JU06JVMuJWYiICAjIElTTyA4MDYxCgoKIyBTdHJlYW0gcHJvY2Vzc2luZyBjb2RlCmNsYXNzIEV2ZW50U3RyZWFtUHJvY2Vzc29yOgogICAgZGVmIF9faW5pdF9fKAogICAgICAgIHNlbGYsCiAgICAgICAgcHJvamVjdDogc3RyLAogICAgICAgIHBhcnF1ZXRfYmF0Y2hpbmdfbWF4X2V2ZW50czogaW50LAogICAgICAgIHNhbXBsZV93aW5kb3c6IGludCA9IDEwLAogICAgICAgIHRzZGJfYmF0Y2hpbmdfbWF4X2V2ZW50czogaW50ID0gMTAsCiAgICAgICAgdHNkYl9iYXRjaGluZ190aW1lb3V0X3NlY3M6IGludCA9IDYwICogNSwgICMgRGVmYXVsdCA1IG1pbnV0ZXMKICAgICAgICBwYXJxdWV0X2JhdGNoaW5nX3RpbWVvdXRfc2VjczogaW50ID0gMzAgKiA2MCwgICMgRGVmYXVsdCAzMCBtaW51dGVzCiAgICAgICAgYWdncmVnYXRlX2NvdW50X3dpbmRvd3M6IE9wdGlvbmFsW0xpc3Rbc3RyXV0gPSBOb25lLAogICAgICAgIGFnZ3JlZ2F0ZV9jb3VudF9wZXJpb2Q6IHN0ciA9ICIzMHMiLAogICAgICAgIGFnZ3JlZ2F0ZV9hdmdfd2luZG93czogT3B0aW9uYWxbTGlzdFtzdHJdXSA9IE5vbmUsCiAgICAgICAgYWdncmVnYXRlX2F2Z19wZXJpb2Q6IHN0ciA9ICIzMHMiLAogICAgICAgIHYzaW9fYWNjZXNzX2tleTogT3B0aW9uYWxbc3RyXSA9IE5vbmUsCiAgICAgICAgdjNpb19mcmFtZXNkOiBPcHRpb25hbFtzdHJdID0gTm9uZSwKICAgICAgICB2M2lvX2FwaTogT3B0aW9uYWxbc3RyXSA9IE5vbmUsCiAgICAgICAgbW9kZWxfbW9uaXRvcmluZ19hY2Nlc3Nfa2V5OiBzdHIgPSBOb25lLAogICAgKToKICAgICAgICBzZWxmLnByb2plY3QgPSBwcm9qZWN0CiAgICAgICAgc2VsZi5zYW1wbGVfd2luZG93ID0gc2FtcGxlX3dpbmRvdwogICAgICAgIHNlbGYudHNkYl9iYXRjaGluZ19tYXhfZXZlbnRzID0gdHNkYl9iYXRjaGluZ19tYXhfZXZlbnRzCiAgICAgICAgc2VsZi50c2RiX2JhdGNoaW5nX3RpbWVvdXRfc2VjcyA9IHRzZGJfYmF0Y2hpbmdfdGltZW91dF9zZWNzCiAgICAgICAgc2VsZi5wYXJxdWV0X2JhdGNoaW5nX21heF9ldmVudHMgPSBwYXJxdWV0X2JhdGNoaW5nX21heF9ldmVudHMKICAgICAgICBzZWxmLnBhcnF1ZXRfYmF0Y2hpbmdfdGltZW91dF9zZWNzID0gcGFycXVldF9iYXRjaGluZ190aW1lb3V0X3NlY3MKICAgICAgICBzZWxmLmFnZ3JlZ2F0ZV9jb3VudF93aW5kb3dzID0gYWdncmVnYXRlX2NvdW50X3dpbmRvd3Mgb3IgWyI1bSIsICIxaCJdCiAgICAgICAgc2VsZi5hZ2dyZWdhdGVfY291bnRfcGVyaW9kID0gYWdncmVnYXRlX2NvdW50X3BlcmlvZAogICAgICAgIHNlbGYuYWdncmVnYXRlX2F2Z193aW5kb3dzID0gYWdncmVnYXRlX2F2Z193aW5kb3dzIG9yIFsiNW0iLCAiMWgiXQogICAgICAgIHNlbGYuYWdncmVnYXRlX2F2Z19wZXJpb2QgPSBhZ2dyZWdhdGVfYXZnX3BlcmlvZAoKICAgICAgICBzZWxmLnYzaW9fZnJhbWVzZCA9IHYzaW9fZnJhbWVzZCBvciBjb25maWcudjNpb19mcmFtZXNkCiAgICAgICAgc2VsZi52M2lvX2FwaSA9IHYzaW9fYXBpIG9yIGNvbmZpZy52M2lvX2FwaQoKICAgICAgICBzZWxmLnYzaW9fYWNjZXNzX2tleSA9IHYzaW9fYWNjZXNzX2tleSBvciBlbnZpcm9uLmdldCgiVjNJT19BQ0NFU1NfS0VZIikKICAgICAgICBzZWxmLm1vZGVsX21vbml0b3JpbmdfYWNjZXNzX2tleSA9ICgKICAgICAgICAgICAgbW9kZWxfbW9uaXRvcmluZ19hY2Nlc3Nfa2V5CiAgICAgICAgICAgIG9yIG9zLmVudmlyb24uZ2V0KCJNT0RFTF9NT05JVE9SSU5HX0FDQ0VTU19LRVkiKQogICAgICAgICAgICBvciBzZWxmLnYzaW9fYWNjZXNzX2tleQogICAgICAgICkKCiAgICAgICAgdGVtcGxhdGUgPSBjb25maWcubW9kZWxfZW5kcG9pbnRfbW9uaXRvcmluZy5zdG9yZV9wcmVmaXhlcy5kZWZhdWx0CgogICAgICAgIGt2X3BhdGggPSB0ZW1wbGF0ZS5mb3JtYXQocHJvamVjdD1wcm9qZWN0LCBraW5kPSJlbmRwb2ludHMiKQogICAgICAgIF8sIHNlbGYua3ZfY29udGFpbmVyLCBzZWxmLmt2X3BhdGggPSBwYXJzZV9tb2RlbF9lbmRwb2ludF9zdG9yZV9wcmVmaXgoa3ZfcGF0aCkKCiAgICAgICAgdHNkYl9wYXRoID0gdGVtcGxhdGUuZm9ybWF0KHByb2plY3Q9cHJvamVjdCwga2luZD0iZXZlbnRzIikKICAgICAgICBfLCBzZWxmLnRzZGJfY29udGFpbmVyLCBzZWxmLnRzZGJfcGF0aCA9IHBhcnNlX21vZGVsX2VuZHBvaW50X3N0b3JlX3ByZWZpeCgKICAgICAgICAgICAgdHNkYl9wYXRoCiAgICAgICAgKQogICAgICAgIHNlbGYudHNkYl9wYXRoID0gZiJ7c2VsZi50c2RiX2NvbnRhaW5lcn0ve3NlbGYudHNkYl9wYXRofSIKCiAgICAgICAgc2VsZi5wYXJxdWV0X3BhdGggPSAoCiAgICAgICAgICAgIGNvbmZpZy5tb2RlbF9lbmRwb2ludF9tb25pdG9yaW5nLnN0b3JlX3ByZWZpeGVzLnVzZXJfc3BhY2UuZm9ybWF0KAogICAgICAgICAgICAgICAgcHJvamVjdD1wcm9qZWN0LCBraW5kPSJwYXJxdWV0IgogICAgICAgICAgICApCiAgICAgICAgKQoKICAgICAgICBsb2dnZXIuaW5mbygKICAgICAgICAgICAgIkluaXRpYWxpemluZyBtb2RlbCBtb25pdG9yaW5nIGV2ZW50IHN0cmVhbSBwcm9jZXNzb3IiLAogICAgICAgICAgICBwYXJxdWV0X2JhdGNoaW5nX21heF9ldmVudHM9c2VsZi5wYXJxdWV0X2JhdGNoaW5nX21heF9ldmVudHMsCiAgICAgICAgICAgIHYzaW9fYWNjZXNzX2tleT1zZWxmLnYzaW9fYWNjZXNzX2tleSwKICAgICAgICAgICAgbW9kZWxfbW9uaXRvcmluZ19hY2Nlc3Nfa2V5PXNlbGYubW9kZWxfbW9uaXRvcmluZ19hY2Nlc3Nfa2V5LAogICAgICAgICAgICBkZWZhdWx0X3N0b3JlX3ByZWZpeD1jb25maWcubW9kZWxfZW5kcG9pbnRfbW9uaXRvcmluZy5zdG9yZV9wcmVmaXhlcy5kZWZhdWx0LAogICAgICAgICAgICB1c2VyX3NwYWNlX3N0b3JlX3ByZWZpeD1jb25maWcubW9kZWxfZW5kcG9pbnRfbW9uaXRvcmluZy5zdG9yZV9wcmVmaXhlcy51c2VyX3NwYWNlLAogICAgICAgICAgICB2M2lvX2FwaT1zZWxmLnYzaW9fYXBpLAogICAgICAgICAgICB2M2lvX2ZyYW1lc2Q9c2VsZi52M2lvX2ZyYW1lc2QsCiAgICAgICAgICAgIGt2X2NvbnRhaW5lcj1zZWxmLmt2X2NvbnRhaW5lciwKICAgICAgICAgICAga3ZfcGF0aD1zZWxmLmt2X3BhdGgsCiAgICAgICAgICAgIHRzZGJfY29udGFpbmVyPXNlbGYudHNkYl9jb250YWluZXIsCiAgICAgICAgICAgIHRzZGJfcGF0aD1zZWxmLnRzZGJfcGF0aCwKICAgICAgICAgICAgcGFycXVldF9wYXRoPXNlbGYucGFycXVldF9wYXRoLAogICAgICAgICkKCiAgICBkZWYgY3JlYXRlX2ZlYXR1cmVfc2V0KHNlbGYpOgogICAgICAgIGZlYXR1cmVfc2V0ID0gZnMuRmVhdHVyZVNldCgKICAgICAgICAgICAgIm1vbml0b3JpbmciLCBlbnRpdGllcz1bRU5EUE9JTlRfSURdLCB0aW1lc3RhbXBfa2V5PVRJTUVTVEFNUAogICAgICAgICkKICAgICAgICBmZWF0dXJlX3NldC5tZXRhZGF0YS5wcm9qZWN0ID0gc2VsZi5wcm9qZWN0CiAgICAgICAgZmVhdHVyZV9zZXQuZ3JhcGgudG8oCiAgICAgICAgICAgICJQcm9jZXNzRW5kcG9pbnRFdmVudCIsCiAgICAgICAgICAgIGt2X2NvbnRhaW5lcj1zZWxmLmt2X2NvbnRhaW5lciwKICAgICAgICAgICAga3ZfcGF0aD1zZWxmLmt2X3BhdGgsCiAgICAgICAgICAgIHYzaW9fYWNjZXNzX2tleT1zZWxmLnYzaW9fYWNjZXNzX2tleSwKICAgICAgICAgICAgZnVsbF9ldmVudD1UcnVlLAogICAgICAgICkudG8oInN0b3JleS5GaWx0ZXIiLCAiZmlsdGVyX25vbmUiLCBfZm49IihldmVudCBpcyBub3QgTm9uZSkiKS50bygKICAgICAgICAgICAgInN0b3JleS5GbGF0TWFwIiwgImZsYXR0ZW5fZXZlbnRzIiwgX2ZuPSIoZXZlbnQpIgogICAgICAgICkudG8oCiAgICAgICAgICAgICJNYXBGZWF0dXJlTmFtZXMiLAogICAgICAgICAgICBuYW1lPSJNYXBGZWF0dXJlTmFtZXMiLAogICAgICAgICAgICBrdl9jb250YWluZXI9c2VsZi5rdl9jb250YWluZXIsCiAgICAgICAgICAgIGt2X3BhdGg9c2VsZi5rdl9wYXRoLAogICAgICAgICAgICBhY2Nlc3Nfa2V5PXNlbGYudjNpb19hY2Nlc3Nfa2V5LAogICAgICAgICAgICBpbmZlcl9jb2x1bW5zX2Zyb21fZGF0YT1UcnVlLAogICAgICAgICkKICAgICAgICAjIGt2IGFuZCB0c2RiIGJyYW5jaAogICAgICAgIGZlYXR1cmVfc2V0LmFkZF9hZ2dyZWdhdGlvbigKICAgICAgICAgICAgRU5EUE9JTlRfSUQsCiAgICAgICAgICAgIFsiY291bnQiXSwKICAgICAgICAgICAgc2VsZi5hZ2dyZWdhdGVfY291bnRfd2luZG93cywKICAgICAgICAgICAgc2VsZi5hZ2dyZWdhdGVfY291bnRfcGVyaW9kLAogICAgICAgICAgICBuYW1lPVBSRURJQ1RJT05TLAogICAgICAgICAgICBhZnRlcj0iTWFwRmVhdHVyZU5hbWVzIiwKICAgICAgICAgICAgc3RlcF9uYW1lPSJBZ2dyZWdhdGVzIiwKICAgICAgICApCiAgICAgICAgZmVhdHVyZV9zZXQuYWRkX2FnZ3JlZ2F0aW9uKAogICAgICAgICAgICBMQVRFTkNZLAogICAgICAgICAgICBbImF2ZyJdLAogICAgICAgICAgICBzZWxmLmFnZ3JlZ2F0ZV9hdmdfd2luZG93cywKICAgICAgICAgICAgc2VsZi5hZ2dyZWdhdGVfYXZnX3BlcmlvZCwKICAgICAgICApCiAgICAgICAgZmVhdHVyZV9zZXQuZ3JhcGguYWRkX3N0ZXAoCiAgICAgICAgICAgICJzdG9yZXkuc3RlcHMuU2FtcGxlV2luZG93IiwKICAgICAgICAgICAgbmFtZT0ic2FtcGxlIiwKICAgICAgICAgICAgYWZ0ZXI9IkFnZ3JlZ2F0ZXMiLAogICAgICAgICAgICB3aW5kb3dfc2l6ZT1zZWxmLnNhbXBsZV93aW5kb3csCiAgICAgICAgICAgIGtleT1FTkRQT0lOVF9JRCwKICAgICAgICApCiAgICAgICAgIyBrdgogICAgICAgIGZlYXR1cmVfc2V0LmdyYXBoLmFkZF9zdGVwKAogICAgICAgICAgICAiUHJvY2Vzc0JlZm9yZUtWIiwgbmFtZT0iUHJvY2Vzc0JlZm9yZUtWIiwgYWZ0ZXI9InNhbXBsZSIKICAgICAgICApCiAgICAgICAgZmVhdHVyZV9zZXQuZ3JhcGguYWRkX3N0ZXAoCiAgICAgICAgICAgICJXcml0ZVRvS1YiLAogICAgICAgICAgICBuYW1lPSJXcml0ZVRvS1YiLAogICAgICAgICAgICBhZnRlcj0iUHJvY2Vzc0JlZm9yZUtWIiwKICAgICAgICAgICAgY29udGFpbmVyPXNlbGYua3ZfY29udGFpbmVyLAogICAgICAgICAgICB0YWJsZT1zZWxmLmt2X3BhdGgsCiAgICAgICAgKQogICAgICAgIGZlYXR1cmVfc2V0LmdyYXBoLmFkZF9zdGVwKAogICAgICAgICAgICAiSW5mZXJTY2hlbWEiLAogICAgICAgICAgICBuYW1lPSJJbmZlclNjaGVtYSIsCiAgICAgICAgICAgIGFmdGVyPSJXcml0ZVRvS1YiLAogICAgICAgICAgICB2M2lvX2FjY2Vzc19rZXk9c2VsZi52M2lvX2FjY2Vzc19rZXksCiAgICAgICAgICAgIHYzaW9fZnJhbWVzZD1zZWxmLnYzaW9fZnJhbWVzZCwKICAgICAgICAgICAgY29udGFpbmVyPXNlbGYua3ZfY29udGFpbmVyLAogICAgICAgICAgICB0YWJsZT1zZWxmLmt2X3BhdGgsCiAgICAgICAgKQogICAgICAgICMgdHNkYgogICAgICAgIGZlYXR1cmVfc2V0LmdyYXBoLmFkZF9zdGVwKAogICAgICAgICAgICAiUHJvY2Vzc0JlZm9yZVRTREIiLCBuYW1lPSJQcm9jZXNzQmVmb3JlVFNEQiIsIGFmdGVyPSJzYW1wbGUiCiAgICAgICAgKQogICAgICAgIGZlYXR1cmVfc2V0LmdyYXBoLmFkZF9zdGVwKAogICAgICAgICAgICAiRmlsdGVyQW5kVW5wYWNrS2V5cyIsCiAgICAgICAgICAgIG5hbWU9IkZpbHRlckFuZFVucGFja0tleXMxIiwKICAgICAgICAgICAgYWZ0ZXI9IlByb2Nlc3NCZWZvcmVUU0RCIiwKICAgICAgICAgICAga2V5cz1bQkFTRV9NRVRSSUNTXSwKICAgICAgICApCiAgICAgICAgZmVhdHVyZV9zZXQuZ3JhcGguYWRkX3N0ZXAoCiAgICAgICAgICAgICJzdG9yZXkuVFNEQlRhcmdldCIsCiAgICAgICAgICAgIG5hbWU9InRzZGIxIiwKICAgICAgICAgICAgYWZ0ZXI9IkZpbHRlckFuZFVucGFja0tleXMxIiwKICAgICAgICAgICAgcGF0aD1zZWxmLnRzZGJfcGF0aCwKICAgICAgICAgICAgcmF0ZT0iMTAvbSIsCiAgICAgICAgICAgIHRpbWVfY29sPVRJTUVTVEFNUCwKICAgICAgICAgICAgY29udGFpbmVyPXNlbGYudHNkYl9jb250YWluZXIsCiAgICAgICAgICAgIGFjY2Vzc19rZXk9c2VsZi52M2lvX2FjY2Vzc19rZXksCiAgICAgICAgICAgIHYzaW9fZnJhbWVzPXNlbGYudjNpb19mcmFtZXNkLAogICAgICAgICAgICBpbmRleF9jb2xzPVtFTkRQT0lOVF9JRCwgUkVDT1JEX1RZUEVdLAogICAgICAgICAgICBtYXhfZXZlbnRzPXNlbGYudHNkYl9iYXRjaGluZ19tYXhfZXZlbnRzLAogICAgICAgICAgICB0aW1lb3V0X3NlY3M9c2VsZi50c2RiX2JhdGNoaW5nX3RpbWVvdXRfc2VjcywKICAgICAgICAgICAga2V5PUVORFBPSU5UX0lELAogICAgICAgICkKICAgICAgICBmZWF0dXJlX3NldC5ncmFwaC5hZGRfc3RlcCgKICAgICAgICAgICAgIkZpbHRlckFuZFVucGFja0tleXMiLAogICAgICAgICAgICBuYW1lPSJGaWx0ZXJBbmRVbnBhY2tLZXlzMiIsCiAgICAgICAgICAgIGFmdGVyPSJQcm9jZXNzQmVmb3JlVFNEQiIsCiAgICAgICAgICAgIGtleXM9W0VORFBPSU5UX0ZFQVRVUkVTXSwKICAgICAgICApCiAgICAgICAgZmVhdHVyZV9zZXQuZ3JhcGguYWRkX3N0ZXAoCiAgICAgICAgICAgICJzdG9yZXkuVFNEQlRhcmdldCIsCiAgICAgICAgICAgIG5hbWU9InRzZGIyIiwKICAgICAgICAgICAgYWZ0ZXI9IkZpbHRlckFuZFVucGFja0tleXMyIiwKICAgICAgICAgICAgcGF0aD1zZWxmLnRzZGJfcGF0aCwKICAgICAgICAgICAgcmF0ZT0iMTAvbSIsCiAgICAgICAgICAgIHRpbWVfY29sPVRJTUVTVEFNUCwKICAgICAgICAgICAgY29udGFpbmVyPXNlbGYudHNkYl9jb250YWluZXIsCiAgICAgICAgICAgIGFjY2Vzc19rZXk9c2VsZi52M2lvX2FjY2Vzc19rZXksCiAgICAgICAgICAgIHYzaW9fZnJhbWVzPXNlbGYudjNpb19mcmFtZXNkLAogICAgICAgICAgICBpbmRleF9jb2xzPVtFTkRQT0lOVF9JRCwgUkVDT1JEX1RZUEVdLAogICAgICAgICAgICBtYXhfZXZlbnRzPXNlbGYudHNkYl9iYXRjaGluZ19tYXhfZXZlbnRzLAogICAgICAgICAgICB0aW1lb3V0X3NlY3M9c2VsZi50c2RiX2JhdGNoaW5nX3RpbWVvdXRfc2VjcywKICAgICAgICAgICAga2V5PUVORFBPSU5UX0lELAogICAgICAgICkKICAgICAgICBmZWF0dXJlX3NldC5ncmFwaC5hZGRfc3RlcCgKICAgICAgICAgICAgIkZpbHRlckFuZFVucGFja0tleXMiLAogICAgICAgICAgICBuYW1lPSJGaWx0ZXJBbmRVbnBhY2tLZXlzMyIsCiAgICAgICAgICAgIGFmdGVyPSJQcm9jZXNzQmVmb3JlVFNEQiIsCiAgICAgICAgICAgIGtleXM9W0NVU1RPTV9NRVRSSUNTXSwKICAgICAgICApCiAgICAgICAgZmVhdHVyZV9zZXQuZ3JhcGguYWRkX3N0ZXAoCiAgICAgICAgICAgICJzdG9yZXkuRmlsdGVyIiwKICAgICAgICAgICAgIkZpbHRlck5vdE5vbmUiLAogICAgICAgICAgICBhZnRlcj0iRmlsdGVyQW5kVW5wYWNrS2V5czMiLAogICAgICAgICAgICBfZm49IihldmVudCBpcyBub3QgTm9uZSkiLAogICAgICAgICkKICAgICAgICBmZWF0dXJlX3NldC5ncmFwaC5hZGRfc3RlcCgKICAgICAgICAgICAgInN0b3JleS5UU0RCVGFyZ2V0IiwKICAgICAgICAgICAgbmFtZT0idHNkYjMiLAogICAgICAgICAgICBhZnRlcj0iRmlsdGVyTm90Tm9uZSIsCiAgICAgICAgICAgIHBhdGg9c2VsZi50c2RiX3BhdGgsCiAgICAgICAgICAgIHJhdGU9IjEwL20iLAogICAgICAgICAgICB0aW1lX2NvbD1USU1FU1RBTVAsCiAgICAgICAgICAgIGNvbnRhaW5lcj1zZWxmLnRzZGJfY29udGFpbmVyLAogICAgICAgICAgICBhY2Nlc3Nfa2V5PXNlbGYudjNpb19hY2Nlc3Nfa2V5LAogICAgICAgICAgICB2M2lvX2ZyYW1lcz1zZWxmLnYzaW9fZnJhbWVzZCwKICAgICAgICAgICAgaW5kZXhfY29scz1bRU5EUE9JTlRfSUQsIFJFQ09SRF9UWVBFXSwKICAgICAgICAgICAgbWF4X2V2ZW50cz1zZWxmLnRzZGJfYmF0Y2hpbmdfbWF4X2V2ZW50cywKICAgICAgICAgICAgdGltZW91dF9zZWNzPXNlbGYudHNkYl9iYXRjaGluZ190aW1lb3V0X3NlY3MsCiAgICAgICAgICAgIGtleT1FTkRQT0lOVF9JRCwKICAgICAgICApCgogICAgICAgICMgcGFycXVldCBicmFuY2gKICAgICAgICBmZWF0dXJlX3NldC5ncmFwaC5hZGRfc3RlcCgKICAgICAgICAgICAgIlByb2Nlc3NCZWZvcmVQYXJxdWV0IiwKICAgICAgICAgICAgbmFtZT0iUHJvY2Vzc0JlZm9yZVBhcnF1ZXQiLAogICAgICAgICAgICBhZnRlcj0iTWFwRmVhdHVyZU5hbWVzIiwKICAgICAgICAgICAgX2ZuPSIoZXZlbnQpIiwKICAgICAgICApCiAgICAgICAgc3RvcmFnZV9vcHRpb25zID0gZGljdCgKICAgICAgICAgICAgdjNpb19hY2Nlc3Nfa2V5PXNlbGYubW9kZWxfbW9uaXRvcmluZ19hY2Nlc3Nfa2V5LCB2M2lvX2FwaT1zZWxmLnYzaW9fYXBpCiAgICAgICAgKQoKICAgICAgICBwcV90YXJnZXQgPSBQYXJxdWV0VGFyZ2V0KAogICAgICAgICAgICBwYXRoPXNlbGYucGFycXVldF9wYXRoLAogICAgICAgICAgICBhZnRlcl9zdGVwPSJQcm9jZXNzQmVmb3JlUGFycXVldCIsCiAgICAgICAgICAgIGtleV9idWNrZXRpbmdfbnVtYmVyPTAsCiAgICAgICAgICAgIHRpbWVfcGFydGl0aW9uaW5nX2dyYW51bGFyaXR5PSJob3VyIiwKICAgICAgICAgICAgbWF4X2V2ZW50cz1zZWxmLnBhcnF1ZXRfYmF0Y2hpbmdfbWF4X2V2ZW50cywKICAgICAgICAgICAgZmx1c2hfYWZ0ZXJfc2Vjb25kcz1zZWxmLnBhcnF1ZXRfYmF0Y2hpbmdfdGltZW91dF9zZWNzLAogICAgICAgICAgICBzdG9yYWdlX29wdGlvbnM9c3RvcmFnZV9vcHRpb25zLAogICAgICAgICAgICBhdHRyaWJ1dGVzPXsiaW5mZXJfY29sdW1uc19mcm9tX2RhdGEiOiBUcnVlfSwKICAgICAgICApCgogICAgICAgIGZlYXR1cmVfc2V0LnNldF90YXJnZXRzKAogICAgICAgICAgICB0YXJnZXRzPVtwcV90YXJnZXRdLAogICAgICAgICAgICB3aXRoX2RlZmF1bHRzPUZhbHNlLAogICAgICAgICAgICBkZWZhdWx0X2ZpbmFsX3N0ZXA9IlByb2Nlc3NCZWZvcmVQYXJxdWV0IiwKICAgICAgICApCiAgICAgICAgcmV0dXJuIGZlYXR1cmVfc2V0CgoKY2xhc3MgUHJvY2Vzc0JlZm9yZUtWKE1hcENsYXNzKToKICAgIGRlZiBfX2luaXRfXyhzZWxmLCAqKmt3YXJncyk6CiAgICAgICAgc3VwZXIoKS5fX2luaXRfXygqKmt3YXJncykKCiAgICBkZWYgZG8oc2VsZiwgZXZlbnQpOgogICAgICAgICMgY29tcHV0ZSBwcmVkaWN0aW9uIHBlciBzZWNvbmQKICAgICAgICBldmVudFtQUkVESUNUSU9OU19QRVJfU0VDT05EXSA9IGZsb2F0KGV2ZW50W1BSRURJQ1RJT05TX0NPVU5UXzVNXSkgLyAzMDAKICAgICAgICAjIEZpbHRlciByZWxldmFudCBrZXlzCiAgICAgICAgZSA9IHsKICAgICAgICAgICAgazogZXZlbnRba10KICAgICAgICAgICAgZm9yIGsgaW4gWwogICAgICAgICAgICAgICAgRlVOQ1RJT05fVVJJLAogICAgICAgICAgICAgICAgTU9ERUwsCiAgICAgICAgICAgICAgICBNT0RFTF9DTEFTUywKICAgICAgICAgICAgICAgIFRJTUVTVEFNUCwKICAgICAgICAgICAgICAgIEVORFBPSU5UX0lELAogICAgICAgICAgICAgICAgTEFCRUxTLAogICAgICAgICAgICAgICAgVU5QQUNLRURfTEFCRUxTLAogICAgICAgICAgICAgICAgTEFURU5DWV9BVkdfNU0sCiAgICAgICAgICAgICAgICBMQVRFTkNZX0FWR18xSCwKICAgICAgICAgICAgICAgIFBSRURJQ1RJT05TX1BFUl9TRUNPTkQsCiAgICAgICAgICAgICAgICBQUkVESUNUSU9OU19DT1VOVF81TSwKICAgICAgICAgICAgICAgIFBSRURJQ1RJT05TX0NPVU5UXzFILAogICAgICAgICAgICAgICAgRklSU1RfUkVRVUVTVCwKICAgICAgICAgICAgICAgIExBU1RfUkVRVUVTVCwKICAgICAgICAgICAgICAgIEVSUk9SX0NPVU5ULAogICAgICAgICAgICBdCiAgICAgICAgfQogICAgICAgICMgVW5wYWNrIGxhYmVscyBkaWN0aW9uYXJ5CiAgICAgICAgZSA9IHsqKmUsICoqZS5wb3AoVU5QQUNLRURfTEFCRUxTLCB7fSl9CiAgICAgICAgIyBXcml0ZSBsYWJlbHMgdG8ga3YgYXMganNvbiBzdHJpbmcgdG8gYmUgcHJlc2VudGFibGUgbGF0ZXIKICAgICAgICBlW0xBQkVMU10gPSBqc29uLmR1bXBzKGVbTEFCRUxTXSkKICAgICAgICByZXR1cm4gZQoKCmNsYXNzIFByb2Nlc3NCZWZvcmVUU0RCKE1hcENsYXNzKToKICAgIGRlZiBfX2luaXRfXyhzZWxmLCAqKmt3YXJncyk6CiAgICAgICAgc3VwZXIoKS5fX2luaXRfXygqKmt3YXJncykKCiAgICBkZWYgZG8oc2VsZiwgZXZlbnQpOgogICAgICAgICMgY29tcHV0ZSBwcmVkaWN0aW9uIHBlciBzZWNvbmQKICAgICAgICBldmVudFtQUkVESUNUSU9OU19QRVJfU0VDT05EXSA9IGZsb2F0KGV2ZW50W1BSRURJQ1RJT05TX0NPVU5UXzVNXSkgLyAzMDAKICAgICAgICBiYXNlX2ZpZWxkcyA9IFtUSU1FU1RBTVAsIEVORFBPSU5UX0lEXQoKICAgICAgICBiYXNlX2V2ZW50ID0ge2s6IGV2ZW50W2tdIGZvciBrIGluIGJhc2VfZmllbGRzfQogICAgICAgIGJhc2VfZXZlbnRbVElNRVNUQU1QXSA9IHBkLnRvX2RhdGV0aW1lKAogICAgICAgICAgICBiYXNlX2V2ZW50W1RJTUVTVEFNUF0sIGZvcm1hdD1USU1FX0ZPUk1BVAogICAgICAgICkKCiAgICAgICAgYmFzZV9tZXRyaWNzID0gewogICAgICAgICAgICBSRUNPUkRfVFlQRTogQkFTRV9NRVRSSUNTLAogICAgICAgICAgICBQUkVESUNUSU9OU19QRVJfU0VDT05EOiBldmVudFtQUkVESUNUSU9OU19QRVJfU0VDT05EXSwKICAgICAgICAgICAgUFJFRElDVElPTlNfQ09VTlRfNU06IGV2ZW50W1BSRURJQ1RJT05TX0NPVU5UXzVNXSwKICAgICAgICAgICAgUFJFRElDVElPTlNfQ09VTlRfMUg6IGV2ZW50W1BSRURJQ1RJT05TX0NPVU5UXzFIXSwKICAgICAgICAgICAgTEFURU5DWV9BVkdfNU06IGV2ZW50W0xBVEVOQ1lfQVZHXzVNXSwKICAgICAgICAgICAgTEFURU5DWV9BVkdfMUg6IGV2ZW50W0xBVEVOQ1lfQVZHXzFIXSwKICAgICAgICAgICAgKipiYXNlX2V2ZW50LAogICAgICAgIH0KCiAgICAgICAgZW5kcG9pbnRfZmVhdHVyZXMgPSB7CiAgICAgICAgICAgIFJFQ09SRF9UWVBFOiBFTkRQT0lOVF9GRUFUVVJFUywKICAgICAgICAgICAgKipldmVudFtOQU1FRF9QUkVESUNUSU9OU10sCiAgICAgICAgICAgICoqZXZlbnRbTkFNRURfRkVBVFVSRVNdLAogICAgICAgICAgICAqKmJhc2VfZXZlbnQsCiAgICAgICAgfQoKICAgICAgICBwcm9jZXNzZWQgPSB7QkFTRV9NRVRSSUNTOiBiYXNlX21ldHJpY3MsIEVORFBPSU5UX0ZFQVRVUkVTOiBlbmRwb2ludF9mZWF0dXJlc30KCiAgICAgICAgaWYgZXZlbnRbTUVUUklDU106CiAgICAgICAgICAgIHByb2Nlc3NlZFtDVVNUT01fTUVUUklDU10gPSB7CiAgICAgICAgICAgICAgICBSRUNPUkRfVFlQRTogQ1VTVE9NX01FVFJJQ1MsCiAgICAgICAgICAgICAgICAqKmV2ZW50W01FVFJJQ1NdLAogICAgICAgICAgICAgICAgKipiYXNlX2V2ZW50LAogICAgICAgICAgICB9CgogICAgICAgIHJldHVybiBwcm9jZXNzZWQKCgpjbGFzcyBQcm9jZXNzQmVmb3JlUGFycXVldChNYXBDbGFzcyk6CiAgICBkZWYgX19pbml0X18oc2VsZiwgKiprd2FyZ3MpOgogICAgICAgIHN1cGVyKCkuX19pbml0X18oKiprd2FyZ3MpCgogICAgZGVmIGRvKHNlbGYsIGV2ZW50KToKICAgICAgICBsb2dnZXIuaW5mbygiUHJvY2Vzc0JlZm9yZVBhcnF1ZXQxIiwgZXZlbnQ9ZXZlbnQpCiAgICAgICAgZm9yIGtleSBpbiBbVU5QQUNLRURfTEFCRUxTLCBGRUFUVVJFU106CiAgICAgICAgICAgIGV2ZW50LnBvcChrZXksIE5vbmUpCiAgICAgICAgdmFsdWUgPSBldmVudC5nZXQoImVudGl0aWVzIikKICAgICAgICBpZiB2YWx1ZSBpcyBub3QgTm9uZToKICAgICAgICAgICAgZXZlbnQgPSB7Kip2YWx1ZSwgKipldmVudH0KICAgICAgICBmb3Iga2V5IGluIFtMQUJFTFMsIE1FVFJJQ1MsIEVOVElUSUVTXToKICAgICAgICAgICAgaWYgbm90IGV2ZW50LmdldChrZXkpOgogICAgICAgICAgICAgICAgZXZlbnRba2V5XSA9IE5vbmUKICAgICAgICBsb2dnZXIuaW5mbygiUHJvY2Vzc0JlZm9yZVBhcnF1ZXQyIiwgZXZlbnQ9ZXZlbnQpCiAgICAgICAgcmV0dXJuIGV2ZW50CgoKY2xhc3MgUHJvY2Vzc0VuZHBvaW50RXZlbnQoTWFwQ2xhc3MpOgogICAgZGVmIF9faW5pdF9fKHNlbGYsIGt2X2NvbnRhaW5lcjogc3RyLCBrdl9wYXRoOiBzdHIsIHYzaW9fYWNjZXNzX2tleTogc3RyLCAqKmt3YXJncyk6CiAgICAgICAgc3VwZXIoKS5fX2luaXRfXygqKmt3YXJncykKICAgICAgICBzZWxmLmt2X2NvbnRhaW5lcjogc3RyID0ga3ZfY29udGFpbmVyCiAgICAgICAgc2VsZi5rdl9wYXRoOiBzdHIgPSBrdl9wYXRoCiAgICAgICAgc2VsZi52M2lvX2FjY2Vzc19rZXk6IHN0ciA9IHYzaW9fYWNjZXNzX2tleQogICAgICAgIHNlbGYuZmlyc3RfcmVxdWVzdDogRGljdFtzdHIsIHN0cl0gPSBkaWN0KCkKICAgICAgICBzZWxmLmxhc3RfcmVxdWVzdDogRGljdFtzdHIsIHN0cl0gPSBkaWN0KCkKICAgICAgICBzZWxmLmVycm9yX2NvdW50OiBEaWN0W3N0ciwgaW50XSA9IGRlZmF1bHRkaWN0KGludCkKICAgICAgICBzZWxmLmVuZHBvaW50czogU2V0W3N0cl0gPSBzZXQoKQoKICAgIGRlZiBkbyhzZWxmLCBmdWxsX2V2ZW50KToKICAgICAgICBldmVudCA9IGZ1bGxfZXZlbnQuYm9keQoKICAgICAgICAjIGNvZGUgdGhhdCBjYWxjdWxhdGVzIHRoZSBlbmRwcGludCBpZC4gc2hvdWxkIGJlCiAgICAgICAgZnVuY3Rpb25fdXJpID0gZXZlbnQuZ2V0KEZVTkNUSU9OX1VSSSkKICAgICAgICBpZiBub3QgaXNfbm90X25vbmUoZnVuY3Rpb25fdXJpLCBbRlVOQ1RJT05fVVJJXSk6CiAgICAgICAgICAgIHJldHVybiBOb25lCgogICAgICAgIG1vZGVsID0gZXZlbnQuZ2V0KE1PREVMKQogICAgICAgIGlmIG5vdCBpc19ub3Rfbm9uZShtb2RlbCwgW01PREVMXSk6CiAgICAgICAgICAgIHJldHVybiBOb25lCgogICAgICAgIHZlcnNpb24gPSBldmVudC5nZXQoVkVSU0lPTikKICAgICAgICB2ZXJzaW9uZWRfbW9kZWwgPSBmInttb2RlbH06e3ZlcnNpb259IiBpZiB2ZXJzaW9uIGVsc2UgZiJ7bW9kZWx9OmxhdGVzdCIKCiAgICAgICAgZW5kcG9pbnRfaWQgPSBjcmVhdGVfbW9kZWxfZW5kcG9pbnRfaWQoCiAgICAgICAgICAgIGZ1bmN0aW9uX3VyaT1mdW5jdGlvbl91cmksCiAgICAgICAgICAgIHZlcnNpb25lZF9tb2RlbD12ZXJzaW9uZWRfbW9kZWwsCiAgICAgICAgKQogICAgICAgIGVuZHBvaW50X2lkID0gc3RyKGVuZHBvaW50X2lkKQoKICAgICAgICBldmVudFtWRVJTSU9ORURfTU9ERUxdID0gdmVyc2lvbmVkX21vZGVsCiAgICAgICAgZXZlbnRbRU5EUE9JTlRfSURdID0gZW5kcG9pbnRfaWQKCiAgICAgICAgIyBJbiBjYXNlIHRoaXMgcHJvY2VzcyBmYWlscywgcmVzdW1lIHN0YXRlIGZyb20gZXhpc3RpbmcgcmVjb3JkCiAgICAgICAgc2VsZi5yZXN1bWVfc3RhdGUoZW5kcG9pbnRfaWQpCgogICAgICAgICMgSGFuZGxlIGVycm9ycyBjb21pbmcgZnJvbSBzdHJlYW0KICAgICAgICBmb3VuZF9lcnJvcnMgPSBzZWxmLmhhbmRsZV9lcnJvcnMoZW5kcG9pbnRfaWQsIGV2ZW50KQogICAgICAgIGlmIGZvdW5kX2Vycm9yczoKICAgICAgICAgICAgcmV0dXJuIE5vbmUKCiAgICAgICAgIyBWYWxpZGF0ZSBldmVudCBmaWVsZHMKICAgICAgICBtb2RlbF9jbGFzcyA9IGV2ZW50LmdldCgibW9kZWxfY2xhc3MiKSBvciBldmVudC5nZXQoImNsYXNzIikKICAgICAgICB0aW1lc3RhbXAgPSBldmVudC5nZXQoIndoZW4iKQogICAgICAgIHJlcXVlc3RfaWQgPSBldmVudC5nZXQoInJlcXVlc3QiLCB7fSkuZ2V0KCJpZCIpIG9yIGV2ZW50LmdldCgicmVzcCIsIHt9KS5nZXQoCiAgICAgICAgICAgICJpZCIKICAgICAgICApCiAgICAgICAgbGF0ZW5jeSA9IGV2ZW50LmdldCgibWljcm9zZWMiKQogICAgICAgIGZlYXR1cmVzID0gZXZlbnQuZ2V0KCJyZXF1ZXN0Iiwge30pLmdldCgiaW5wdXRzIikKICAgICAgICBwcmVkaWN0aW9ucyA9IGV2ZW50LmdldCgicmVzcCIsIHt9KS5nZXQoIm91dHB1dHMiKQoKICAgICAgICBpZiBub3Qgc2VsZi5pc192YWxpZCgKICAgICAgICAgICAgZW5kcG9pbnRfaWQsCiAgICAgICAgICAgIGlzX25vdF9ub25lLAogICAgICAgICAgICB0aW1lc3RhbXAsCiAgICAgICAgICAgIFsid2hlbiJdLAogICAgICAgICk6CiAgICAgICAgICAgIHJldHVybiBOb25lCgogICAgICAgIGlmIGVuZHBvaW50X2lkIG5vdCBpbiBzZWxmLmZpcnN0X3JlcXVlc3Q6CiAgICAgICAgICAgIHNlbGYuZmlyc3RfcmVxdWVzdFtlbmRwb2ludF9pZF0gPSB0aW1lc3RhbXAKICAgICAgICBzZWxmLmxhc3RfcmVxdWVzdFtlbmRwb2ludF9pZF0gPSB0aW1lc3RhbXAKCiAgICAgICAgaWYgbm90IHNlbGYuaXNfdmFsaWQoCiAgICAgICAgICAgIGVuZHBvaW50X2lkLAogICAgICAgICAgICBpc19ub3Rfbm9uZSwKICAgICAgICAgICAgcmVxdWVzdF9pZCwKICAgICAgICAgICAgWyJyZXF1ZXN0IiwgImlkIl0sCiAgICAgICAgKToKICAgICAgICAgICAgcmV0dXJuIE5vbmUKICAgICAgICBpZiBub3Qgc2VsZi5pc192YWxpZCgKICAgICAgICAgICAgZW5kcG9pbnRfaWQsCiAgICAgICAgICAgIGlzX25vdF9ub25lLAogICAgICAgICAgICBsYXRlbmN5LAogICAgICAgICAgICBbIm1pY3Jvc2VjIl0sCiAgICAgICAgKToKICAgICAgICAgICAgcmV0dXJuIE5vbmUKICAgICAgICBpZiBub3Qgc2VsZi5pc192YWxpZCgKICAgICAgICAgICAgZW5kcG9pbnRfaWQsCiAgICAgICAgICAgIGlzX25vdF9ub25lLAogICAgICAgICAgICBmZWF0dXJlcywKICAgICAgICAgICAgWyJyZXF1ZXN0IiwgImlucHV0cyJdLAogICAgICAgICk6CiAgICAgICAgICAgIHJldHVybiBOb25lCiAgICAgICAgaWYgbm90IHNlbGYuaXNfdmFsaWQoCiAgICAgICAgICAgIGVuZHBvaW50X2lkLAogICAgICAgICAgICBpc19ub3Rfbm9uZSwKICAgICAgICAgICAgcHJlZGljdGlvbnMsCiAgICAgICAgICAgIFsicmVzcCIsICJvdXRwdXRzIl0sCiAgICAgICAgKToKICAgICAgICAgICAgcmV0dXJuIE5vbmUKCiAgICAgICAgdW5wYWNrZWRfbGFiZWxzID0ge2YiX3trfSI6IHYgZm9yIGssIHYgaW4gZXZlbnQuZ2V0KExBQkVMUywge30pLml0ZW1zKCl9CgogICAgICAgICMgU2VwYXJhdGUgZWFjaCBtb2RlbCBpbnZvY2F0aW9uIGludG8gc3ViIGV2ZW50cwogICAgICAgIGV2ZW50cyA9IFtdCiAgICAgICAgZm9yIGksIChmZWF0dXJlLCBwcmVkaWN0aW9uKSBpbiBlbnVtZXJhdGUoemlwKGZlYXR1cmVzLCBwcmVkaWN0aW9ucykpOgogICAgICAgICAgICBpZiBub3Qgc2VsZi5pc192YWxpZCgKICAgICAgICAgICAgICAgIGVuZHBvaW50X2lkLAogICAgICAgICAgICAgICAgc2VsZi5pc19saXN0X29mX251bWVyaWNzLAogICAgICAgICAgICAgICAgZmVhdHVyZSwKICAgICAgICAgICAgICAgIFsicmVxdWVzdCIsICJpbnB1dHMiLCBmIlt7aX1dIl0sCiAgICAgICAgICAgICk6CiAgICAgICAgICAgICAgICByZXR1cm4gTm9uZQoKICAgICAgICAgICAgaWYgbm90IGlzaW5zdGFuY2UocHJlZGljdGlvbiwgbGlzdCk6CiAgICAgICAgICAgICAgICBwcmVkaWN0aW9uID0gW3ByZWRpY3Rpb25dCgogICAgICAgICAgICBldmVudHMuYXBwZW5kKAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEZVTkNUSU9OX1VSSTogZnVuY3Rpb25fdXJpLAogICAgICAgICAgICAgICAgICAgIE1PREVMOiB2ZXJzaW9uZWRfbW9kZWwsCiAgICAgICAgICAgICAgICAgICAgTU9ERUxfQ0xBU1M6IG1vZGVsX2NsYXNzLAogICAgICAgICAgICAgICAgICAgIFRJTUVTVEFNUDogdGltZXN0YW1wLAogICAgICAgICAgICAgICAgICAgIEVORFBPSU5UX0lEOiBlbmRwb2ludF9pZCwKICAgICAgICAgICAgICAgICAgICBSRVFVRVNUX0lEOiByZXF1ZXN0X2lkLAogICAgICAgICAgICAgICAgICAgIExBVEVOQ1k6IGxhdGVuY3ksCiAgICAgICAgICAgICAgICAgICAgRkVBVFVSRVM6IGZlYXR1cmUsCiAgICAgICAgICAgICAgICAgICAgUFJFRElDVElPTjogcHJlZGljdGlvbiwKICAgICAgICAgICAgICAgICAgICBGSVJTVF9SRVFVRVNUOiBzZWxmLmZpcnN0X3JlcXVlc3RbZW5kcG9pbnRfaWRdLAogICAgICAgICAgICAgICAgICAgIExBU1RfUkVRVUVTVDogc2VsZi5sYXN0X3JlcXVlc3RbZW5kcG9pbnRfaWRdLAogICAgICAgICAgICAgICAgICAgIEVSUk9SX0NPVU5UOiBzZWxmLmVycm9yX2NvdW50W2VuZHBvaW50X2lkXSwKICAgICAgICAgICAgICAgICAgICBMQUJFTFM6IGV2ZW50LmdldChMQUJFTFMsIHt9KSwKICAgICAgICAgICAgICAgICAgICBNRVRSSUNTOiBldmVudC5nZXQoTUVUUklDUywge30pLAogICAgICAgICAgICAgICAgICAgIEVOVElUSUVTOiBldmVudC5nZXQoInJlcXVlc3QiLCB7fSkuZ2V0KEVOVElUSUVTLCB7fSksCiAgICAgICAgICAgICAgICAgICAgVU5QQUNLRURfTEFCRUxTOiB1bnBhY2tlZF9sYWJlbHMsCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkKCiAgICAgICAgc3RvcmV5X2V2ZW50ID0gRXZlbnQoYm9keT1ldmVudHMsIGtleT1lbmRwb2ludF9pZCwgdGltZT10aW1lc3RhbXApCiAgICAgICAgcmV0dXJuIHN0b3JleV9ldmVudAoKICAgIGRlZiBpc19saXN0X29mX251bWVyaWNzKAogICAgICAgIHNlbGYsIGZpZWxkOiBMaXN0W1VuaW9uW2ludCwgZmxvYXQsIGRpY3QsIGxpc3RdXSwgZGljdF9wYXRoOiBMaXN0W3N0cl0KICAgICk6CiAgICAgICAgaWYgYWxsKGlzaW5zdGFuY2UoeCwgaW50KSBvciBpc2luc3RhbmNlKHgsIGZsb2F0KSBmb3IgeCBpbiBmaWVsZCk6CiAgICAgICAgICAgIHJldHVybiBUcnVlCiAgICAgICAgbG9nZ2VyLmVycm9yKAogICAgICAgICAgICBmIkxpc3QgZG9lcyBub3QgY29uc2lzdCBvZiBvbmx5IG51bWVyaWMgdmFsdWVzOiB7ZmllbGR9IFtFdmVudCAtPiB7JywnLmpvaW4oZGljdF9wYXRoKX1dIgogICAgICAgICkKICAgICAgICByZXR1cm4gRmFsc2UKCiAgICBkZWYgcmVzdW1lX3N0YXRlKHNlbGYsIGVuZHBvaW50X2lkKToKICAgICAgICAjIE1ha2Ugc3VyZSBwcm9jZXNzIGlzIHJlc3VtYWJsZSwgaWYgcHJvY2VzcyBmYWlscyBmb3IgYW55IHJlYXNvbiwgYmUgYWJsZSB0byBwaWNrIHRoaW5ncyB1cCBjbG9zZSB0byB3aGVyZSB3ZQogICAgICAgICMgbGVmdCB0aGVtCiAgICAgICAgaWYgZW5kcG9pbnRfaWQgbm90IGluIHNlbGYuZW5kcG9pbnRzOgogICAgICAgICAgICBsb2dnZXIuaW5mbygiVHJ5aW5nIHRvIHJlc3VtZSBzdGF0ZSIsIGVuZHBvaW50X2lkPWVuZHBvaW50X2lkKQogICAgICAgICAgICBlbmRwb2ludF9yZWNvcmQgPSBnZXRfZW5kcG9pbnRfcmVjb3JkKAogICAgICAgICAgICAgICAga3ZfY29udGFpbmVyPXNlbGYua3ZfY29udGFpbmVyLAogICAgICAgICAgICAgICAga3ZfcGF0aD1zZWxmLmt2X3BhdGgsCiAgICAgICAgICAgICAgICBlbmRwb2ludF9pZD1lbmRwb2ludF9pZCwKICAgICAgICAgICAgICAgIGFjY2Vzc19rZXk9c2VsZi52M2lvX2FjY2Vzc19rZXksCiAgICAgICAgICAgICkKICAgICAgICAgICAgaWYgZW5kcG9pbnRfcmVjb3JkOgogICAgICAgICAgICAgICAgZmlyc3RfcmVxdWVzdCA9IGVuZHBvaW50X3JlY29yZC5nZXQoRklSU1RfUkVRVUVTVCkKICAgICAgICAgICAgICAgIGlmIGZpcnN0X3JlcXVlc3Q6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5maXJzdF9yZXF1ZXN0W2VuZHBvaW50X2lkXSA9IGZpcnN0X3JlcXVlc3QKICAgICAgICAgICAgICAgIGVycm9yX2NvdW50ID0gZW5kcG9pbnRfcmVjb3JkLmdldChFUlJPUl9DT1VOVCkKICAgICAgICAgICAgICAgIGlmIGVycm9yX2NvdW50OgogICAgICAgICAgICAgICAgICAgIHNlbGYuZXJyb3JfY291bnRbZW5kcG9pbnRfaWRdID0gZXJyb3JfY291bnQKICAgICAgICAgICAgc2VsZi5lbmRwb2ludHMuYWRkKGVuZHBvaW50X2lkKQoKICAgIGRlZiBpc192YWxpZCgKICAgICAgICBzZWxmLCBlbmRwb2ludF9pZDogc3RyLCB2YWxpZGF0aW9uX2Z1bmN0aW9uLCBmaWVsZDogQW55LCBkaWN0X3BhdGg6IExpc3Rbc3RyXQogICAgKToKICAgICAgICBpZiB2YWxpZGF0aW9uX2Z1bmN0aW9uKGZpZWxkLCBkaWN0X3BhdGgpOgogICAgICAgICAgICByZXR1cm4gVHJ1ZQogICAgICAgIHNlbGYuZXJyb3JfY291bnRbZW5kcG9pbnRfaWRdICs9IDEKICAgICAgICByZXR1cm4gRmFsc2UKCiAgICBkZWYgaGFuZGxlX2Vycm9ycyhzZWxmLCBlbmRwb2ludF9pZCwgZXZlbnQpIC0+IGJvb2w6CiAgICAgICAgaWYgImVycm9yIiBpbiBldmVudDoKICAgICAgICAgICAgc2VsZi5lcnJvcl9jb3VudFtlbmRwb2ludF9pZF0gKz0gMQogICAgICAgICAgICByZXR1cm4gVHJ1ZQoKICAgICAgICByZXR1cm4gRmFsc2UKCgpkZWYgZW5yaWNoX2V2ZW5fZGV0YWlscyhldmVudCkgLT4gT3B0aW9uYWxbZGljdF06CiAgICBmdW5jdGlvbl91cmkgPSBldmVudC5nZXQoRlVOQ1RJT05fVVJJKQoKICAgIGlmIG5vdCBpc19ub3Rfbm9uZShmdW5jdGlvbl91cmksIFtGVU5DVElPTl9VUkldKToKICAgICAgICByZXR1cm4gTm9uZQoKICAgIG1vZGVsID0gZXZlbnQuZ2V0KE1PREVMKQogICAgaWYgbm90IGlzX25vdF9ub25lKG1vZGVsLCBbTU9ERUxdKToKICAgICAgICByZXR1cm4gTm9uZQoKICAgIHZlcnNpb24gPSBldmVudC5nZXQoVkVSU0lPTikKICAgIHZlcnNpb25lZF9tb2RlbCA9IGYie21vZGVsfTp7dmVyc2lvbn0iIGlmIHZlcnNpb24gZWxzZSBmInttb2RlbH06bGF0ZXN0IgoKICAgIGVuZHBvaW50X2lkID0gY3JlYXRlX21vZGVsX2VuZHBvaW50X2lkKAogICAgICAgIGZ1bmN0aW9uX3VyaT1mdW5jdGlvbl91cmksCiAgICAgICAgdmVyc2lvbmVkX21vZGVsPXZlcnNpb25lZF9tb2RlbCwKICAgICkKCiAgICBlbmRwb2ludF9pZCA9IHN0cihlbmRwb2ludF9pZCkKCiAgICBldmVudFtWRVJTSU9ORURfTU9ERUxdID0gdmVyc2lvbmVkX21vZGVsCiAgICBldmVudFtFTkRQT0lOVF9JRF0gPSBlbmRwb2ludF9pZAoKICAgIHJldHVybiBldmVudAoKCmRlZiBpc19ub3Rfbm9uZShmaWVsZDogQW55LCBkaWN0X3BhdGg6IExpc3Rbc3RyXSk6CiAgICBpZiBmaWVsZCBpcyBub3QgTm9uZToKICAgICAgICByZXR1cm4gVHJ1ZQogICAgbG9nZ2VyLmVycm9yKAogICAgICAgIGYiRXhwZWN0ZWQgZXZlbnQgZmllbGQgaXMgbWlzc2luZzoge2ZpZWxkfSBbRXZlbnQgLT4geycsJy5qb2luKGRpY3RfcGF0aCl9XSIKICAgICkKICAgIHJldHVybiBGYWxzZQoKCmNsYXNzIEZpbHRlckFuZFVucGFja0tleXMoTWFwQ2xhc3MpOgogICAgZGVmIF9faW5pdF9fKHNlbGYsIGtleXMsICoqa3dhcmdzKToKICAgICAgICBzdXBlcigpLl9faW5pdF9fKCoqa3dhcmdzKQogICAgICAgIHNlbGYua2V5cyA9IGtleXMKCiAgICBkZWYgZG8oc2VsZiwgZXZlbnQpOgogICAgICAgIG5ld19ldmVudCA9IHt9CiAgICAgICAgZm9yIGtleSBpbiBzZWxmLmtleXM6CiAgICAgICAgICAgIGlmIGtleSBpbiBldmVudDoKICAgICAgICAgICAgICAgIG5ld19ldmVudFtrZXldID0gZXZlbnRba2V5XQogICAgICAgIHVucGFja2VkID0ge30KICAgICAgICBmb3Iga2V5IGluIG5ld19ldmVudC5rZXlzKCk6CiAgICAgICAgICAgIGlmIGtleSBpbiBzZWxmLmtleXM6CiAgICAgICAgICAgICAgICB1bnBhY2tlZCA9IHsqKnVucGFja2VkLCAqKm5ld19ldmVudFtrZXldfQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgdW5wYWNrZWRba2V5XSA9IG5ld19ldmVudFtrZXldCiAgICAgICAgcmV0dXJuIHVucGFja2VkIGlmIHVucGFja2VkIGVsc2UgTm9uZQoKCmNsYXNzIE1hcEZlYXR1cmVOYW1lcyhNYXBDbGFzcyk6CiAgICBkZWYgX19pbml0X18oCiAgICAgICAgc2VsZiwKICAgICAgICBrdl9jb250YWluZXI6IHN0ciwKICAgICAgICBrdl9wYXRoOiBzdHIsCiAgICAgICAgYWNjZXNzX2tleTogc3RyLAogICAgICAgIGluZmVyX2NvbHVtbnNfZnJvbV9kYXRhOiBib29sID0gRmFsc2UsCiAgICAgICAgKiprd2FyZ3MsCiAgICApOgogICAgICAgIHN1cGVyKCkuX19pbml0X18oKiprd2FyZ3MpCiAgICAgICAgc2VsZi5rdl9jb250YWluZXIgPSBrdl9jb250YWluZXIKICAgICAgICBzZWxmLmt2X3BhdGggPSBrdl9wYXRoCiAgICAgICAgc2VsZi5hY2Nlc3Nfa2V5ID0gYWNjZXNzX2tleQogICAgICAgIHNlbGYuX2luZmVyX2NvbHVtbnNfZnJvbV9kYXRhID0gaW5mZXJfY29sdW1uc19mcm9tX2RhdGEKICAgICAgICBzZWxmLmZlYXR1cmVfbmFtZXMgPSB7fQogICAgICAgIHNlbGYubGFiZWxfY29sdW1ucyA9IHt9CgogICAgZGVmIF9pbmZlcl9mZWF0dXJlX25hbWVzX2Zyb21fZGF0YShzZWxmLCBldmVudCk6CiAgICAgICAgZm9yIGVuZHBvaW50X2lkIGluIHNlbGYuZmVhdHVyZV9uYW1lczoKICAgICAgICAgICAgaWYgbGVuKHNlbGYuZmVhdHVyZV9uYW1lc1tlbmRwb2ludF9pZF0pID49IGxlbihldmVudFtGRUFUVVJFU10pOgogICAgICAgICAgICAgICAgcmV0dXJuIHNlbGYuZmVhdHVyZV9uYW1lc1tlbmRwb2ludF9pZF0KICAgICAgICByZXR1cm4gTm9uZQoKICAgIGRlZiBfaW5mZXJfbGFiZWxfY29sdW1uc19mcm9tX2RhdGEoc2VsZiwgZXZlbnQpOgogICAgICAgIGZvciBlbmRwb2ludF9pZCBpbiBzZWxmLmxhYmVsX2NvbHVtbnM6CiAgICAgICAgICAgIGlmIGxlbihzZWxmLmxhYmVsX2NvbHVtbnNbZW5kcG9pbnRfaWRdKSA+PSBsZW4oZXZlbnRbUFJFRElDVElPTl0pOgogICAgICAgICAgICAgICAgcmV0dXJuIHNlbGYubGFiZWxfY29sdW1uc1tlbmRwb2ludF9pZF0KICAgICAgICByZXR1cm4gTm9uZQoKICAgIGRlZiBkbyhzZWxmLCBldmVudDogRGljdCk6CiAgICAgICAgZW5kcG9pbnRfaWQgPSBldmVudFtFTkRQT0lOVF9JRF0KCiAgICAgICAgaWYgZW5kcG9pbnRfaWQgbm90IGluIHNlbGYuZmVhdHVyZV9uYW1lczoKICAgICAgICAgICAgZW5kcG9pbnRfcmVjb3JkID0gZ2V0X2VuZHBvaW50X3JlY29yZCgKICAgICAgICAgICAgICAgIGt2X2NvbnRhaW5lcj1zZWxmLmt2X2NvbnRhaW5lciwKICAgICAgICAgICAgICAgIGt2X3BhdGg9c2VsZi5rdl9wYXRoLAogICAgICAgICAgICAgICAgZW5kcG9pbnRfaWQ9ZW5kcG9pbnRfaWQsCiAgICAgICAgICAgICAgICBhY2Nlc3Nfa2V5PXNlbGYuYWNjZXNzX2tleSwKICAgICAgICAgICAgKQogICAgICAgICAgICBmZWF0dXJlX25hbWVzID0gZW5kcG9pbnRfcmVjb3JkLmdldChGRUFUVVJFX05BTUVTKQogICAgICAgICAgICBmZWF0dXJlX25hbWVzID0ganNvbi5sb2FkcyhmZWF0dXJlX25hbWVzKSBpZiBmZWF0dXJlX25hbWVzIGVsc2UgTm9uZQoKICAgICAgICAgICAgbGFiZWxfY29sdW1ucyA9IGVuZHBvaW50X3JlY29yZC5nZXQoTEFCRUxfQ09MVU1OUykKICAgICAgICAgICAgbGFiZWxfY29sdW1ucyA9IGpzb24ubG9hZHMobGFiZWxfY29sdW1ucykgaWYgbGFiZWxfY29sdW1ucyBlbHNlIE5vbmUKCiAgICAgICAgICAgIGlmIG5vdCBmZWF0dXJlX25hbWVzIGFuZCBzZWxmLl9pbmZlcl9jb2x1bW5zX2Zyb21fZGF0YToKICAgICAgICAgICAgICAgIGZlYXR1cmVfbmFtZXMgPSBzZWxmLl9pbmZlcl9mZWF0dXJlX25hbWVzX2Zyb21fZGF0YShldmVudCkKCiAgICAgICAgICAgIGlmIG5vdCBmZWF0dXJlX25hbWVzOgogICAgICAgICAgICAgICAgbG9nZ2VyLndhcm4oCiAgICAgICAgICAgICAgICAgICAgIkZlYXR1cmUgbmFtZXMgYXJlIG5vdCBpbml0aWFsaXplZCwgdGhleSB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIiwKICAgICAgICAgICAgICAgICAgICBlbmRwb2ludF9pZD1lbmRwb2ludF9pZCwKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIGZlYXR1cmVfbmFtZXMgPSBbZiJme2l9IiBmb3IgaSwgXyBpbiBlbnVtZXJhdGUoZXZlbnRbRkVBVFVSRVNdKV0KICAgICAgICAgICAgICAgIGdldF92M2lvX2NsaWVudCgpLmt2LnVwZGF0ZSgKICAgICAgICAgICAgICAgICAgICBjb250YWluZXI9c2VsZi5rdl9jb250YWluZXIsCiAgICAgICAgICAgICAgICAgICAgdGFibGVfcGF0aD1zZWxmLmt2X3BhdGgsCiAgICAgICAgICAgICAgICAgICAgYWNjZXNzX2tleT1zZWxmLmFjY2Vzc19rZXksCiAgICAgICAgICAgICAgICAgICAga2V5PWV2ZW50W0VORFBPSU5UX0lEXSwKICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzPXtGRUFUVVJFX05BTUVTOiBqc29uLmR1bXBzKGZlYXR1cmVfbmFtZXMpfSwKICAgICAgICAgICAgICAgICAgICByYWlzZV9mb3Jfc3RhdHVzPVJhaXNlRm9yU3RhdHVzLmFsd2F5cywKICAgICAgICAgICAgICAgICkKCiAgICAgICAgICAgIGlmIG5vdCBsYWJlbF9jb2x1bW5zIGFuZCBzZWxmLl9pbmZlcl9jb2x1bW5zX2Zyb21fZGF0YToKICAgICAgICAgICAgICAgIGxhYmVsX2NvbHVtbnMgPSBzZWxmLl9pbmZlcl9sYWJlbF9jb2x1bW5zX2Zyb21fZGF0YShldmVudCkKCiAgICAgICAgICAgIGlmIG5vdCBsYWJlbF9jb2x1bW5zOgogICAgICAgICAgICAgICAgbG9nZ2VyLndhcm4oCiAgICAgICAgICAgICAgICAgICAgImxhYmVsIGNvbHVtbiBuYW1lcyBhcmUgbm90IGluaXRpYWxpemVkLCB0aGV5IHdpbGwgYmUgYXV0b21hdGljYWxseSBnZW5lcmF0ZWQiLAogICAgICAgICAgICAgICAgICAgIGVuZHBvaW50X2lkPWVuZHBvaW50X2lkLAogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgbGFiZWxfY29sdW1ucyA9IFtmInB7aX0iIGZvciBpLCBfIGluIGVudW1lcmF0ZShldmVudFtQUkVESUNUSU9OXSldCiAgICAgICAgICAgICAgICBnZXRfdjNpb19jbGllbnQoKS5rdi51cGRhdGUoCiAgICAgICAgICAgICAgICAgICAgY29udGFpbmVyPXNlbGYua3ZfY29udGFpbmVyLAogICAgICAgICAgICAgICAgICAgIHRhYmxlX3BhdGg9c2VsZi5rdl9wYXRoLAogICAgICAgICAgICAgICAgICAgIGFjY2Vzc19rZXk9c2VsZi5hY2Nlc3Nfa2V5LAogICAgICAgICAgICAgICAgICAgIGtleT1ldmVudFtFTkRQT0lOVF9JRF0sCiAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlcz17TEFCRUxfQ09MVU1OUzoganNvbi5kdW1wcyhsYWJlbF9jb2x1bW5zKX0sCiAgICAgICAgICAgICAgICAgICAgcmFpc2VfZm9yX3N0YXR1cz1SYWlzZUZvclN0YXR1cy5hbHdheXMsCiAgICAgICAgICAgICAgICApCgogICAgICAgICAgICBzZWxmLmxhYmVsX2NvbHVtbnNbZW5kcG9pbnRfaWRdID0gbGFiZWxfY29sdW1ucwogICAgICAgICAgICBzZWxmLmZlYXR1cmVfbmFtZXNbZW5kcG9pbnRfaWRdID0gZmVhdHVyZV9uYW1lcwoKICAgICAgICAgICAgbG9nZ2VyLmluZm8oCiAgICAgICAgICAgICAgICAiTGFiZWwgY29sdW1ucyIsIGVuZHBvaW50X2lkPWVuZHBvaW50X2lkLCBsYWJlbF9jb2x1bW5zPWxhYmVsX2NvbHVtbnMKICAgICAgICAgICAgKQogICAgICAgICAgICBsb2dnZXIuaW5mbygKICAgICAgICAgICAgICAgICJGZWF0dXJlIG5hbWVzIiwgZW5kcG9pbnRfaWQ9ZW5kcG9pbnRfaWQsIGZlYXR1cmVfbmFtZXM9ZmVhdHVyZV9uYW1lcwogICAgICAgICAgICApCgogICAgICAgIGZlYXR1cmVfbmFtZXMgPSBzZWxmLmZlYXR1cmVfbmFtZXNbZW5kcG9pbnRfaWRdCiAgICAgICAgZmVhdHVyZXMgPSBldmVudFtGRUFUVVJFU10KICAgICAgICBldmVudFtOQU1FRF9GRUFUVVJFU10gPSB7CiAgICAgICAgICAgIG5hbWU6IGZlYXR1cmUgZm9yIG5hbWUsIGZlYXR1cmUgaW4gemlwKGZlYXR1cmVfbmFtZXMsIGZlYXR1cmVzKQogICAgICAgIH0KCiAgICAgICAgbGFiZWxfY29sdW1ucyA9IHNlbGYubGFiZWxfY29sdW1uc1tlbmRwb2ludF9pZF0KICAgICAgICBwcmVkaWN0aW9uID0gZXZlbnRbUFJFRElDVElPTl0KICAgICAgICBldmVudFtOQU1FRF9QUkVESUNUSU9OU10gPSB7CiAgICAgICAgICAgIG5hbWU6IHByZWRpY3Rpb24gZm9yIG5hbWUsIHByZWRpY3Rpb24gaW4gemlwKGxhYmVsX2NvbHVtbnMsIHByZWRpY3Rpb24pCiAgICAgICAgfQogICAgICAgIGxvZ2dlci5pbmZvKCJNYXBwZWQgZXZlbnQiLCBldmVudD1ldmVudCkKICAgICAgICByZXR1cm4gZXZlbnQKCgpjbGFzcyBXcml0ZVRvS1YoTWFwQ2xhc3MpOgogICAgZGVmIF9faW5pdF9fKHNlbGYsIGNvbnRhaW5lcjogc3RyLCB0YWJsZTogc3RyLCAqKmt3YXJncyk6CiAgICAgICAgc3VwZXIoKS5fX2luaXRfXygqKmt3YXJncykKICAgICAgICBzZWxmLmNvbnRhaW5lciA9IGNvbnRhaW5lcgogICAgICAgIHNlbGYudGFibGUgPSB0YWJsZQoKICAgIGRlZiBkbyhzZWxmLCBldmVudDogRGljdCk6CiAgICAgICAgZ2V0X3YzaW9fY2xpZW50KCkua3YudXBkYXRlKAogICAgICAgICAgICBjb250YWluZXI9c2VsZi5jb250YWluZXIsCiAgICAgICAgICAgIHRhYmxlX3BhdGg9c2VsZi50YWJsZSwKICAgICAgICAgICAga2V5PWV2ZW50W0VORFBPSU5UX0lEXSwKICAgICAgICAgICAgYXR0cmlidXRlcz1ldmVudCwKICAgICAgICApCiAgICAgICAgcmV0dXJuIGV2ZW50CgoKY2xhc3MgSW5mZXJTY2hlbWEoTWFwQ2xhc3MpOgogICAgZGVmIF9faW5pdF9fKAogICAgICAgIHNlbGYsCiAgICAgICAgdjNpb19hY2Nlc3Nfa2V5OiBzdHIsCiAgICAgICAgdjNpb19mcmFtZXNkOiBzdHIsCiAgICAgICAgY29udGFpbmVyOiBzdHIsCiAgICAgICAgdGFibGU6IHN0ciwKICAgICAgICAqKmt3YXJncywKICAgICk6CiAgICAgICAgc3VwZXIoKS5fX2luaXRfXygqKmt3YXJncykKICAgICAgICBzZWxmLmNvbnRhaW5lciA9IGNvbnRhaW5lcgogICAgICAgIHNlbGYudjNpb19hY2Nlc3Nfa2V5ID0gdjNpb19hY2Nlc3Nfa2V5CiAgICAgICAgc2VsZi52M2lvX2ZyYW1lc2QgPSB2M2lvX2ZyYW1lc2QKICAgICAgICBzZWxmLnRhYmxlID0gdGFibGUKICAgICAgICBzZWxmLmtleXMgPSBzZXQoKQoKICAgIGRlZiBkbyhzZWxmLCBldmVudDogRGljdCk6CiAgICAgICAga2V5X3NldCA9IHNldChldmVudC5rZXlzKCkpCiAgICAgICAgaWYgbm90IGtleV9zZXQuaXNzdWJzZXQoc2VsZi5rZXlzKToKICAgICAgICAgICAgc2VsZi5rZXlzLnVwZGF0ZShrZXlfc2V0KQogICAgICAgICAgICBnZXRfZnJhbWVzX2NsaWVudCgKICAgICAgICAgICAgICAgIHRva2VuPXNlbGYudjNpb19hY2Nlc3Nfa2V5LAogICAgICAgICAgICAgICAgY29udGFpbmVyPXNlbGYuY29udGFpbmVyLAogICAgICAgICAgICAgICAgYWRkcmVzcz1zZWxmLnYzaW9fZnJhbWVzZCwKICAgICAgICAgICAgKS5leGVjdXRlKGJhY2tlbmQ9Imt2IiwgdGFibGU9c2VsZi50YWJsZSwgY29tbWFuZD0iaW5mZXJfc2NoZW1hIikKICAgICAgICAgICAgbG9nZ2VyLmluZm8oCiAgICAgICAgICAgICAgICAiRm91bmQgbmV3IGtleXMsIGluZmVycmVkIHNjaGVtYSIsIHRhYmxlPXNlbGYudGFibGUsIGV2ZW50PWV2ZW50CiAgICAgICAgICAgICkKICAgICAgICByZXR1cm4gZXZlbnQKCgpkZWYgZ2V0X2VuZHBvaW50X3JlY29yZCgKICAgIGt2X2NvbnRhaW5lcjogc3RyLCBrdl9wYXRoOiBzdHIsIGVuZHBvaW50X2lkOiBzdHIsIGFjY2Vzc19rZXk6IHN0cgopIC0+IE9wdGlvbmFsW2RpY3RdOgogICAgbG9nZ2VyLmluZm8oCiAgICAgICAgIkdyYWJiaW5nIGVuZHBvaW50IGRhdGEiLAogICAgICAgIGNvbnRhaW5lcj1rdl9jb250YWluZXIsCiAgICAgICAgdGFibGVfcGF0aD1rdl9wYXRoLAogICAgICAgIGtleT1lbmRwb2ludF9pZCwKICAgICkKICAgIHRyeToKICAgICAgICBlbmRwb2ludF9yZWNvcmQgPSAoCiAgICAgICAgICAgIGdldF92M2lvX2NsaWVudCgpCiAgICAgICAgICAgIC5rdi5nZXQoCiAgICAgICAgICAgICAgICBjb250YWluZXI9a3ZfY29udGFpbmVyLAogICAgICAgICAgICAgICAgdGFibGVfcGF0aD1rdl9wYXRoLAogICAgICAgICAgICAgICAga2V5PWVuZHBvaW50X2lkLAogICAgICAgICAgICAgICAgYWNjZXNzX2tleT1hY2Nlc3Nfa2V5LAogICAgICAgICAgICAgICAgcmFpc2VfZm9yX3N0YXR1cz12M2lvLmRhdGFwbGFuZS5SYWlzZUZvclN0YXR1cy5hbHdheXMsCiAgICAgICAgICAgICkKICAgICAgICAgICAgLm91dHB1dC5pdGVtCiAgICAgICAgKQogICAgICAgIHJldHVybiBlbmRwb2ludF9yZWNvcmQKICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgcmV0dXJuIE5vbmUKCmZyb20gbWxydW4ucnVudGltZXMgaW1wb3J0IG51Y2xpb19pbml0X2hvb2sKZGVmIGluaXRfY29udGV4dChjb250ZXh0KToKICAgIG51Y2xpb19pbml0X2hvb2soY29udGV4dCwgZ2xvYmFscygpLCAnc2VydmluZ192MicpCgpkZWYgaGFuZGxlcihjb250ZXh0LCBldmVudCk6CiAgICByZXR1cm4gY29udGV4dC5tbHJ1bl9oYW5kbGVyKGNvbnRleHQsIGV2ZW50KQo=", - "baseImage": "datanode-registry.iguazio-platform.app.product-3-4.iguazio-cd1.com:80/quay.io/mlrun/mlrun:1.0.0" - }, - "triggers": { - "monitoring_stream_trigger": { - "kind": "v3ioStream", - "url": "http://v3io-webapi:8081", - "attributes": { - "containerName": "users", - "streamPath": "pipelines/default/model-endpoints/stream", - "consumerGroup": "serving", - "sequenceNumberCommitInterval": "1s", - "workerAllocationMode": "pool", - "sessionTimeout": "10s", - "heartbeatInterval": "3s", - "seekTo": "earliest", - "readBatchSize": 256, - "pollingIntervalMs": 500 - }, - "name": "monitoring_stream_trigger", - "maxWorkers": 1, - "password": "76ceea19-4b10-47d9-afbb-f687c91b9231" - }, - "http": { - "kind": "http", - "name": "http", - "maxWorkers": 1, - "workerAvailabilityTimeoutMilliseconds": 10000, - "attributes": { - "ingresses": { - "0": { - "paths": [ - "/" - ], - "hostTemplate": "@nuclio.fromDefault" - } - }, - "serviceType": "ClusterIP" - } - } - }, - "serviceType": "ClusterIP", - "resources": { - "requests": { - "memory": "1Mi", - "cpu": "25m" - }, - "limits": { - "memory": "20Gi", - "cpu": "2" - } - }, - "PreemptionMode": "prevent", - "priorityClassName": "igz-workload-medium", - "minReplicas": 1, - "maxReplicas": 1 - } - }, - "source": "", - "function_kind": "serving_v2", - "graph": { - "steps": { - "ProcessEndpointEvent": { - "kind": "task", - "class_name": "ProcessEndpointEvent", - "class_args": { - "kv_container": "users", - "kv_path": "pipelines/default/model-endpoints/endpoints/", - "v3io_access_key": "76ceea19-4b10-47d9-afbb-f687c91b9231" - }, - "full_event": true - }, - "filter_none": { - "kind": "task", - "class_name": "storey.Filter", - "class_args": { - "_fn": "(event is not None)" - }, - "after": [ - "ProcessEndpointEvent" - ] - }, - "flatten_events": { - "kind": "task", - "class_name": "storey.FlatMap", - "class_args": { - "_fn": "(event)" - }, - "after": [ - "filter_none" - ] - }, - "MapFeatureNames": { - "kind": "task", - "class_name": "MapFeatureNames", - "class_args": { - "kv_container": "users", - "kv_path": "pipelines/default/model-endpoints/endpoints/", - "access_key": "76ceea19-4b10-47d9-afbb-f687c91b9231", - "infer_columns_from_data": true - }, - "after": [ - "flatten_events" - ] - }, - "Aggregates": { - "kind": "task", - "class_name": "storey.AggregateByKey", - "class_args": { - "aggregates": [ - { - "name": "predictions", - "column": "endpoint_id", - "operations": [ - "count" - ], - "windows": [ - "5m", - "1h" - ], - "period": "30s" - }, - { - "name": "latency", - "column": "latency", - "operations": [ - "avg" - ], - "windows": [ - "5m", - "1h" - ], - "period": "30s" - } - ], - "table": "." - }, - "after": [ - "MapFeatureNames" - ] - }, - "sample": { - "kind": "task", - "class_name": "storey.steps.SampleWindow", - "class_args": { - "window_size": 10, - "key": "endpoint_id" - }, - "after": [ - "Aggregates" - ] - }, - "ProcessBeforeKV": { - "kind": "task", - "class_name": "ProcessBeforeKV", - "after": [ - "sample" - ] - }, - "WriteToKV": { - "kind": "task", - "class_name": "WriteToKV", - "class_args": { - "container": "users", - "table": "pipelines/default/model-endpoints/endpoints/" - }, - "after": [ - "ProcessBeforeKV" - ] - }, - "InferSchema": { - "kind": "task", - "class_name": "InferSchema", - "class_args": { - "v3io_access_key": "76ceea19-4b10-47d9-afbb-f687c91b9231", - "v3io_framesd": "http://framesd:8080", - "container": "users", - "table": "pipelines/default/model-endpoints/endpoints/" - }, - "after": [ - "WriteToKV" - ] - }, - "ProcessBeforeTSDB": { - "kind": "task", - "class_name": "ProcessBeforeTSDB", - "after": [ - "sample" - ] - }, - "FilterAndUnpackKeys1": { - "kind": "task", - "class_name": "FilterAndUnpackKeys", - "class_args": { - "keys": [ - "base_metrics" - ] - }, - "after": [ - "ProcessBeforeTSDB" - ] - }, - "tsdb1": { - "kind": "task", - "class_name": "storey.TSDBTarget", - "class_args": { - "path": "users/pipelines/default/model-endpoints/events/", - "rate": "10/m", - "time_col": "timestamp", - "container": "users", - "access_key": "76ceea19-4b10-47d9-afbb-f687c91b9231", - "v3io_frames": "http://framesd:8080", - "index_cols": [ - "endpoint_id", - "record_type" - ], - "max_events": 10, - "timeout_secs": 300, - "key": "endpoint_id" - }, - "after": [ - "FilterAndUnpackKeys1" - ] - }, - "FilterAndUnpackKeys2": { - "kind": "task", - "class_name": "FilterAndUnpackKeys", - "class_args": { - "keys": [ - "endpoint_features" - ] - }, - "after": [ - "ProcessBeforeTSDB" - ] - }, - "tsdb2": { - "kind": "task", - "class_name": "storey.TSDBTarget", - "class_args": { - "path": "users/pipelines/default/model-endpoints/events/", - "rate": "10/m", - "time_col": "timestamp", - "container": "users", - "access_key": "76ceea19-4b10-47d9-afbb-f687c91b9231", - "v3io_frames": "http://framesd:8080", - "index_cols": [ - "endpoint_id", - "record_type" - ], - "max_events": 10, - "timeout_secs": 300, - "key": "endpoint_id" - }, - "after": [ - "FilterAndUnpackKeys2" - ] - }, - "FilterAndUnpackKeys3": { - "kind": "task", - "class_name": "FilterAndUnpackKeys", - "class_args": { - "keys": [ - "custom_metrics" - ] - }, - "after": [ - "ProcessBeforeTSDB" - ] - }, - "FilterNotNone": { - "kind": "task", - "class_name": "storey.Filter", - "class_args": { - "_fn": "(event is not None)" - }, - "after": [ - "FilterAndUnpackKeys3" - ] - }, - "tsdb3": { - "kind": "task", - "class_name": "storey.TSDBTarget", - "class_args": { - "path": "users/pipelines/default/model-endpoints/events/", - "rate": "10/m", - "time_col": "timestamp", - "container": "users", - "access_key": "76ceea19-4b10-47d9-afbb-f687c91b9231", - "v3io_frames": "http://framesd:8080", - "index_cols": [ - "endpoint_id", - "record_type" - ], - "max_events": 10, - "timeout_secs": 300, - "key": "endpoint_id" - }, - "after": [ - "FilterNotNone" - ] - }, - "ProcessBeforeParquet": { - "kind": "task", - "class_name": "ProcessBeforeParquet", - "class_args": { - "_fn": "(event)" - }, - "after": [ - "MapFeatureNames" - ] - } + "max_events": 10, + "timeout_secs": 300, + "key": "endpoint_id" + }, + "after": [ + "FilterNotNone" + ] }, - "final_step": "ProcessBeforeParquet" + "ProcessBeforeParquet": { + "kind": "task", + "class_name": "ProcessBeforeParquet", + "class_args": { + "_fn": "(event)" + }, + "after": [ + "MapFeatureNames" + ] + } + }, + "final_step": "ProcessBeforeParquet" }, "graph_initializer": "mlrun.feature_store.ingestion.featureset_initializer", "parameters": { - "infer_options": 0, - "overwrite": null, - "featureset": "store://feature-sets/default/monitoring", - "source": { - "kind": "http", - "online": true - }, - "targets": [ - { - "name": "parquet", - "kind": "parquet", - "path": "v3io:///projects/default/model-endpoints/parquet", - "after_step": "ProcessBeforeParquet", - "attributes": { - "infer_columns_from_data": true - }, - "partitioned": true, - "key_bucketing_number": 0, - "time_partitioning_granularity": "hour", - "max_events": 10000, - "flush_after_seconds": 1800, - "storage_options": { - "v3io_access_key": "55a0d13c-7d9a-44ab-a556-dd213d8c7165", - "v3io_api": "http://v3io-webapi:8081" - } - } - ] + "infer_options": 0, + "overwrite": null, + "featureset": "store://feature-sets/default/monitoring", + "source": { + "kind": "http", + "online": true + }, + "targets": [ + { + "name": "parquet", + "kind": "parquet", + "path": "v3io:///projects/default/model-endpoints/parquet", + "after_step": "ProcessBeforeParquet", + "attributes": { + "infer_columns_from_data": true + }, + "partitioned": true, + "key_bucketing_number": 0, + "time_partitioning_granularity": "hour", + "max_events": 10000, + "flush_after_seconds": 1800, + "storage_options": { + "v3io_access_key": "55a0d13c-7d9a-44ab-a556-dd213d8c7165", + "v3io_api": "http://v3io-webapi:8081" + } + } + ] }, "secret_sources": [], "affinity": null, "tolerations": null - }, - "status": { + }, + "status": { "nuclio_name": "default-model-monitoring-stream", "internal_invocation_urls": [], "external_invocation_urls": [] + }, + "verbose": false }, - "verbose": false -}, { "kind": "job", "metadata": { @@ -30309,6 +30507,274 @@ "updated": "2024-10-08T14:06:44.563424+00:00" }, "status": {} - } + }, + { + "metadata": { + "hash": "93124a9c66fcefbe27b24109a729691f8dbea5c0", + "credentials": { + "access_key": "$ref:mlrun-auth-secrets.b262111796186bb2718523bd3377fc4871b1e6c702992140099210de" + }, + "updated": "2025-09-04T12:45:44.659000+00:00", + "project": "default", + "tag": "latest", + "name": "test-func-oyn", + "uid": "93124a9c66fcefbe27b24109a729691f8dbea5c0" + }, + "verbose": false, + "spec": { + "build": { + "code_origin": "https://github.com/mlrun/test-notebooks-ui#77469ce3b66b43562f6dfff0be3f620fd1f231bd:fnxot.py", + "origin_filename": "fnxot.py", + "functionSourceCode": "ZGVmIGhhbmRsZXIoKToKICAgIHJhaXNlIEV4Y2VwdGlvbigiVGhpcyBmdW5jdGlvbiBpbnRlbnRpb25hbGx5IGZhaWxzIikKICAgICAgICAgICAgCg==" + }, + "state_thresholds": { + "pending_scheduled": "1h", + "pending_not_scheduled": "-1", + "image_pull_backoff": "1h", + "executing": "24h" + }, + "default_handler": "handler", + "entry_points": { + "handler": { + "has_kwargs": false, + "has_varargs": false, + "doc": "", + "lineno": 1, + "name": "handler" + } + }, + "image": "mlrun/mlrun", + "preemption_mode": "prevent", + "description": "", + "command": "", + "disable_auto_mount": true, + "priority_class_name": "igz-workload-medium", + "tolerations": null, + "env": [ + { + "name": "V3IO_API", + "value": "v3io-webapi.default-tenant.svc:8081" + }, + { + "name": "V3IO_USERNAME", + "value": "normal-user" + }, + { + "name": "V3IO_ACCESS_KEY", + "valueFrom": { + "secretKeyRef": { + "key": "accessKey", + "name": "mlrun-auth-secrets.9a60a83c83d08d712a722becb0d2c7bc308be38d59c4a904c6d89696" + } + } + }, + { + "name": "V3IO_FRAMESD", + "value": "framesd:8081" + }, + { + "name": "MLRUN_AUTH_SESSION", + "valueFrom": { + "secretKeyRef": { + "key": "accessKey", + "name": "mlrun-auth-secrets.b262111796186bb2718523bd3377fc4871b1e6c702992140099210de" + } + } + } + ], + "affinity": null, + "node_selector": {}, + "resources": { + "requests": { + "memory": "1Mi", + "cpu": "25m" + }, + "limits": { + "memory": "20Gi", + "cpu": "2" + } + } + }, + "status": { + "state": null + }, + "kind": "job" + }, + { + "status": { + "nuclio_name": "llmdeploy332-function-with-llm", + "internal_invocation_urls": [ + "nuclio-llmdeploy332-function-with-llm.default-tenant.svc.cluster.local:8080" + ], + "address": "llmdeploy332-function-with-llm.default-tenant.app.vmdev36.lab.iguazeng.com/", + "container_image": "docker-registry.default-tenant.app.vmdev36.lab.iguazeng.com:80/nuclio/llmdeploy332-llmdeploy332-function-with-llm-processor:latest", + "external_invocation_urls": [ + "llmdeploy332-function-with-llm.default-tenant.app.vmdev36.lab.iguazeng.com/" + ], + "state": "ready" + }, + "metadata": { + "credentials": { + "access_key": "$ref:mlrun-auth-secrets.5d8a1734cc89d6337fde8ee93c9a2649613519b15ed817fb3e8ecc47" + }, + "project": "llmdeploy332", + "name": "function-with-llm", + "tag": "latest", + "hash": "fc40337727c37256a3d81cb6114515bf3239fb17", + "updated": "2025-08-11T11:58:14.322000+00:00", + "uid": "unversioned-latest" + }, + "spec": { + "function_kind": "serving_v2", + "min_replicas": 1, + "image": "mlrun/mlrun", + "base_image_pull": false, + "command": "http://llmdeploy332-function-with-llm.default-tenant.app.vmdev36.lab.iguazeng.com/", + "disable_auto_mount": true, + "function_handler": "function-with-llm-nuclio:handler", + "default_handler": "", + "description": "", + "max_replicas": 4, + "preemption_mode": "prevent", + "priority_class_name": "igz-workload-medium", + "build": { + "code_origin": "./function_with_llm.py", + "secret": "", + "functionSourceCode": "IyBDb3B5cmlnaHQgMjAyNSBJZ3VhemlvCiMKIyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiMgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiMKIyAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAojCiMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQojIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiMgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAojIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgoKZnJvbSBtbHJ1bi5zZXJ2aW5nIGltcG9ydCBMTE1vZGVsCmltcG9ydCBtbHJ1biAKZnJvbSBtbHJ1bi51dGlscyBpbXBvcnQgbG9nZ2VyCmZyb20gbWxydW4uc2VydmluZy5zdGF0ZXMgaW1wb3J0IE1vZGVsLCBNb2RlbFJ1bm5lclN0ZXAsIE1vZGVsU2VsZWN0b3IKZnJvbSB0eXBpbmcgaW1wb3J0IE9wdGlvbmFsCgpjbGFzcyBNeU1vZGVsU2VsZWN0b3IoTW9kZWxTZWxlY3Rvcik6CiAgICBkZWYgc2VsZWN0KHNlbGYsIGV2ZW50LCBhdmFpbGFibGVfbW9kZWxzOiBsaXN0W01vZGVsXSkgLT4gT3B0aW9uYWxbbGlzdFtzdHJdXToKICAgICAgICByZXR1cm4gZXZlbnQuYm9keS5nZXQoIm1vZGVscyIpCgpjbGFzcyBNeUxMTShMTE1vZGVsKToKICAgIGRlZiBwcmVkaWN0KHNlbGYsIGJvZHksIG1lc3NhZ2VzLCBtb2RlbF9jb25maWd1cmF0aW9uKToKICAgICAgICBib2R5WyJ1cmwiXSA9IHNlbGYubW9kZWxfYXJ0aWZhY3QubW9kZWxfdXJsCiAgICAgICAgYm9keVsiZGVmYXVsdF9jb25maWciXSA9IHNlbGYubW9kZWxfYXJ0aWZhY3QuZGVmYXVsdF9jb25maWcKICAgICAgICBib2R5WyJwcm9tcHQiXSA9IG1lc3NhZ2VzCiAgICAgICAgcmV0dXJuIGJvZHkKICAgIAojZnJvbSBtbHJ1bi5zZXJ2aW5nIGltcG9ydCBMTE1vZGVsCgpjbGFzcyBNeUxMTUNvbmZpZyhMTE1vZGVsKTogICAgICAgIAogICAgZGVmIHByZWRpY3Qoc2VsZiwgYm9keSwgbWVzc2FnZXMsIG1vZGVsX2NvbmZpZ3VyYXRpb24pOgogICAgICAgIHByb21wdF9hcnRpZmFjdCA9IGdldGF0dHIoc2VsZiwgImludm9jYXRpb25fYXJ0aWZhY3QiLCBOb25lKQogICAgICAgIG1vZGVsX2FydGlmYWN0ID0gZ2V0YXR0cihzZWxmLCAibW9kZWxfYXJ0aWZhY3QiLCBOb25lKQoKICAgICAgICByZXR1cm4gewogICAgICAgICAgICAiaW5wdXRzIjogYm9keSwKICAgICAgICAgICAgInByb21wdCI6IG1lc3NhZ2VzLAogICAgICAgICAgICAibW9kZWxfY29uZmlnIjogbW9kZWxfY29uZmlndXJhdGlvbiwKICAgICAgICAgICAgImRlZmF1bHRfY29uZmlnIjogZ2V0YXR0cihtb2RlbF9hcnRpZmFjdCwgImRlZmF1bHRfY29uZmlnIiwge30pLAogICAgICAgICAgICAibGFiZWxzIjogZ2V0YXR0cihwcm9tcHRfYXJ0aWZhY3QsICJsYWJlbHMiLCB7fSksCiAgICAgICAgICAgICJ0ZW1wbGF0ZV9wYXJhbXMiOiBnZXRhdHRyKHByb21wdF9hcnRpZmFjdCwgInRlbXBsYXRlX3BhcmFtcyIsIHt9KSwKICAgICAgICB9CiAgICAKY2xhc3MgTXlMTE1Db25maWcxKExMTW9kZWwpOgogICAgZGVmIGxvYWQoc2VsZik6CiAgICAgICAgcGFzcwogICAgICAgIAogICAgZGVmIHByZWRpY3Qoc2VsZiwgYm9keSwgbWVzc2FnZXMsIG1vZGVsX2NvbmZpZ3VyYXRpb24pOgogICAgICAgIHByb21wdF9hcnRpZmFjdCA9IGdldGF0dHIoc2VsZiwgImludm9jYXRpb25fYXJ0aWZhY3QiLCBOb25lKQogICAgICAgIG1vZGVsX2FydGlmYWN0ID0gZ2V0YXR0cihzZWxmLCAibW9kZWxfYXJ0aWZhY3QiLCBOb25lKQoKICAgICAgICByZXR1cm4gewogICAgICAgICAgICAiaW5wdXRzIjogYm9keSwKICAgICAgICAgICAgInByb21wdCI6IG1lc3NhZ2VzLAogICAgICAgICAgICAibW9kZWxfY29uZmlnIjogbW9kZWxfY29uZmlndXJhdGlvbiwKICAgICAgICAgICAgImRlZmF1bHRfY29uZmlnIjogZ2V0YXR0cihtb2RlbF9hcnRpZmFjdCwgImRlZmF1bHRfY29uZmlnIiwge30pLAogICAgICAgICAgICAibGFiZWxzIjogZ2V0YXR0cihwcm9tcHRfYXJ0aWZhY3QsICJsYWJlbHMiLCB7fSksCiAgICAgICAgICAgICJ0ZW1wbGF0ZV9wYXJhbXMiOiBnZXRhdHRyKHByb21wdF9hcnRpZmFjdCwgInRlbXBsYXRlX3BhcmFtcyIsIHt9KSwKICAgICAgICB9CmZyb20gbWxydW4ucnVudGltZXMgaW1wb3J0IG51Y2xpb19pbml0X2hvb2sKZGVmIGluaXRfY29udGV4dChjb250ZXh0KToKICAgIG51Y2xpb19pbml0X2hvb2soY29udGV4dCwgZ2xvYmFscygpLCAnc2VydmluZ192MicpCgpkZWYgaGFuZGxlcihjb250ZXh0LCBldmVudCk6CiAgICByZXR1cm4gY29udGV4dC5tbHJ1bl9oYW5kbGVyKGNvbnRleHQsIGV2ZW50KQo=", + "origin_filename": "./function_with_llm.py" + }, + "source": "", + "graph": { + "engine": "async", + "shared_models_mechanism": { + "model-deployment": "naive" + }, + "shared_models": { + "model-deployment": [ + "MyLLM", + { + "name": "model-deployment", + "artifact_uri": "store://models/llmdeploy332/model_art1#0@418c1ad0-ab41-45df-afb9-722d48d5d65a^bff98dcfd64bd3db006488b7808e9d2dcf37b56f" + } + ] + }, + "track_models": false, + "model_endpoints_names": [ + "my-endpoint" + ], + "steps": { + "model-runner": { + "class_args": { + "model_selector": null, + "execution_mechanism_by_model_name": { + "my-endpoint": "shared_executor" + }, + "models": { + "my-endpoint": [ + "mlrun.serving.Model", + { + "name": "my-endpoint", + "shared_runnable_name": "model-deployment", + "artifact_uri": "store://llm-prompts/llmdeploy332/my_llm#0@c00325f6-c2cb-4c62-ad93-8d5de6d0d10d^1d459c52a1102adcbbe242e6bb36e99129f2a8b9" + } + ] + }, + "monitoring_data": { + "my-endpoint": { + "inputs": null, + "outputs": [], + "input_path": null, + "result_path": null, + "creation_strategy": "inplace", + "labels": null, + "model_path": "store://llm-prompts/llmdeploy332/my_llm#0@c00325f6-c2cb-4c62-ad93-8d5de6d0d10d^1d459c52a1102adcbbe242e6bb36e99129f2a8b9", + "model_class": "mlrun.serving.Model", + "model_endpoint_uid": "b2a773fdd4a94719850102cfffb25601" + } + } + }, + "class_name": "mlrun.serving.ModelRunner", + "responder": true, + "endpoint_type": 1, + "shape": "folder", + "model_endpoint_creation_strategy": "skip", + "raise_exception": true, + "kind": "model_runner", + "_shared_proxy_mapping": { + "model-deployment": { + "my-endpoint": "store://llm-prompts/llmdeploy332/my_llm#0@c00325f6-c2cb-4c62-ad93-8d5de6d0d10d^1d459c52a1102adcbbe242e6bb36e99129f2a8b9" + } + } + } + } + }, + "affinity": null, + "volumes": [ + { + "name": "serving-conf", + "configMap": { + "name": "serving-conf-llmdeploy332-function-with-llm" + } + } + ], + "resources": { + "requests": { + "memory": "1Mi", + "cpu": "25m" + }, + "limits": { + "memory": "20Gi", + "cpu": "2" + } + }, + "tolerations": null, + "env": [ + { + "name": "MLRUN_HTTPDB__NUCLIO__EXPLICIT_ACK", + "value": "enabled" + }, + { + "name": "V3IO_API", + "value": "v3io-webapi.default-tenant.svc:8081" + }, + { + "name": "V3IO_USERNAME", + "value": "normal-user" + }, + { + "name": "V3IO_FRAMESD", + "value": "framesd:8081" + }, + { + "name": "V3IO_ACCESS_KEY", + "valueFrom": { + "secretKeyRef": { + "key": "accessKey", + "name": "mlrun-auth-secrets.bd42717290ba28bb58f058523ca25adff9762c83ad2a60157d7478db" + } + } + }, + { + "name": "MLRUN_AUTH_SESSION", + "valueFrom": { + "secretKeyRef": { + "key": "accessKey", + "name": "mlrun-auth-secrets.5d8a1734cc89d6337fde8ee93c9a2649613519b15ed817fb3e8ecc47" + } + } + } + ], + "volume_mounts": [ + { + "name": "serving-conf", + "mountPath": "/tmp/mlrun/serving-conf", + "readOnly": true + } + ], + "node_selector": {} + }, + "verbose": false, + "kind": "serving" + } ] } diff --git a/tests/mockServer/data/iguazioProjects.json b/tests/mockServer/data/iguazioProjects.json index 3014df2207..6d0cab3d9e 100644 --- a/tests/mockServer/data/iguazioProjects.json +++ b/tests/mockServer/data/iguazioProjects.json @@ -1,5 +1,131 @@ { "data": [ + { + "type": "project", + "id": "090b1327-ceff-45c7-867b-4769680238386", + "attributes": { + "name": "auto-generated-data", + "created_at": "2022-03-10T10:24:36.235000+00:00", + "updated_at": "2022-03-14T14:01:13.399000+00:00", + "admin_status": "online", + "operational_status": "online", + "labels": [], + "annotations": [], + "mlrun_project": "{\"kind\": \"project\", \"metadata\": {}, \"spec\": {\"functions\": [{\"name\": \"step3\", \"spec\": {\"kind\": \"job\", \"metadata\": {\"name\": \"step3\", \"tag\": \"\", \"project\": \"proj1\"}, \"spec\": {\"command\": \"\", \"args\": [], \"image\": \"mlrun/mlrun\", \"build\": {\"functionSourceCode\": \"aW1wb3J0IHRpbWUKZGVmIGhhbmRsZXIgKGNvbnRleHQpOgogICAgY29udGV4dC5sb2dnZXIuaW5mbygnc3RhcnQnKQogICAgdGltZS5zbGVlcCgxMCkKICAgIGNvbnRleHQubG9nZ2VyLmluZm8oJ2VuZCcp\", \"commands\": [], \"code_origin\": \"/User/demos/getting-started-tutorial/scale/step1.py\", \"origin_filename\": \"/User/demos/getting-started-tutorial/scale/step1.py\"}, \"entry_points\": {\"handler\": {\"name\": \"handler\", \"doc\": \"\", \"parameters\": [{\"name\": \"context\", \"default\": \"\"}], \"outputs\": [{\"default\": \"\"}], \"lineno\": 2}}, \"description\": \"\", \"default_handler\": \"handler\", \"disable_auto_mount\": false, \"env\": [], \"priority_class_name\": \"igz-workload-medium\", \"affinity\": null}, \"verbose\": false}}], \"workflows\": [{\"name\": \"dummy_workflow\", \"path\": \"/User/demos/getting-started-tutorial/scale/pipelines.py\", \"handler\": \"dummy_workflow\", \"engine\": null}], \"artifacts\": [], \"source\": \"\", \"subpath\": \"\", \"origin_url\": \"\", \"disable_auto_mount\": false}, \"status\": {}}" + } + }, + { + "type": "project", + "id": "090b1327-ceff-45c7-867b-476968023838622", + "attributes": { + "name": "model-deployment-pipeline-admin", + "created_at": "2022-03-10T10:24:36.235000+00:00", + "updated_at": "2022-03-14T14:01:13.399000+00:00", + "admin_status": "online", + "operational_status": "online", + "labels": [], + "annotations": [], + "mlrun_project": "{\"kind\": \"project\", \"metadata\": {}, \"spec\": {\"functions\": [{\"name\": \"step3\", \"spec\": {\"kind\": \"job\", \"metadata\": {\"name\": \"step3\", \"tag\": \"\", \"project\": \"proj1\"}, \"spec\": {\"command\": \"\", \"args\": [], \"image\": \"mlrun/mlrun\", \"build\": {\"functionSourceCode\": \"aW1wb3J0IHRpbWUKZGVmIGhhbmRsZXIgKGNvbnRleHQpOgogICAgY29udGV4dC5sb2dnZXIuaW5mbygnc3RhcnQnKQogICAgdGltZS5zbGVlcCgxMCkKICAgIGNvbnRleHQubG9nZ2VyLmluZm8oJ2VuZCcp\", \"commands\": [], \"code_origin\": \"/User/demos/getting-started-tutorial/scale/step1.py\", \"origin_filename\": \"/User/demos/getting-started-tutorial/scale/step1.py\"}, \"entry_points\": {\"handler\": {\"name\": \"handler\", \"doc\": \"\", \"parameters\": [{\"name\": \"context\", \"default\": \"\"}], \"outputs\": [{\"default\": \"\"}], \"lineno\": 2}}, \"description\": \"\", \"default_handler\": \"handler\", \"disable_auto_mount\": false, \"env\": [], \"priority_class_name\": \"igz-workload-medium\", \"affinity\": null}, \"verbose\": false}}], \"workflows\": [{\"name\": \"dummy_workflow\", \"path\": \"/User/demos/getting-started-tutorial/scale/pipelines.py\", \"handler\": \"dummy_workflow\", \"engine\": null}], \"artifacts\": [], \"source\": \"\", \"subpath\": \"\", \"origin_url\": \"\", \"disable_auto_mount\": false}, \"status\": {}}" + } + }, + { + "type": "project", + "id": "090b1327-ceff-45c7-867b-4769680238386111", + "attributes": { + "name": "moreofthesame", + "created_at": "2022-03-10T10:24:36.235000+00:00", + "updated_at": "2022-03-14T14:01:13.399000+00:00", + "admin_status": "online", + "operational_status": "online", + "labels": [], + "annotations": [], + "mlrun_project": "{\"kind\": \"project\", \"metadata\": {}, \"spec\": {\"functions\": [{\"name\": \"step3\", \"spec\": {\"kind\": \"job\", \"metadata\": {\"name\": \"step3\", \"tag\": \"\", \"project\": \"proj1\"}, \"spec\": {\"command\": \"\", \"args\": [], \"image\": \"mlrun/mlrun\", \"build\": {\"functionSourceCode\": \"aW1wb3J0IHRpbWUKZGVmIGhhbmRsZXIgKGNvbnRleHQpOgogICAgY29udGV4dC5sb2dnZXIuaW5mbygnc3RhcnQnKQogICAgdGltZS5zbGVlcCgxMCkKICAgIGNvbnRleHQubG9nZ2VyLmluZm8oJ2VuZCcp\", \"commands\": [], \"code_origin\": \"/User/demos/getting-started-tutorial/scale/step1.py\", \"origin_filename\": \"/User/demos/getting-started-tutorial/scale/step1.py\"}, \"entry_points\": {\"handler\": {\"name\": \"handler\", \"doc\": \"\", \"parameters\": [{\"name\": \"context\", \"default\": \"\"}], \"outputs\": [{\"default\": \"\"}], \"lineno\": 2}}, \"description\": \"\", \"default_handler\": \"handler\", \"disable_auto_mount\": false, \"env\": [], \"priority_class_name\": \"igz-workload-medium\", \"affinity\": null}, \"verbose\": false}}], \"workflows\": [{\"name\": \"dummy_workflow\", \"path\": \"/User/demos/getting-started-tutorial/scale/pipelines.py\", \"handler\": \"dummy_workflow\", \"engine\": null}], \"artifacts\": [], \"source\": \"\", \"subpath\": \"\", \"origin_url\": \"\", \"disable_auto_mount\": false}, \"status\": {}}" + } + }, + { + "type": "project", + "id": "090b1327-ceff-45c7-867b-867b867b867b867b2", + "attributes": { + "name": "network-operations", + "created_at": "2022-03-10T10:24:36.235000+00:00", + "updated_at": "2022-03-14T14:01:13.399000+00:00", + "admin_status": "online", + "operational_status": "online", + "labels": [], + "annotations": [], + "mlrun_project": "{\"kind\": \"project\", \"metadata\": {}, \"spec\": {\"functions\": [{\"name\": \"step3\", \"spec\": {\"kind\": \"job\", \"metadata\": {\"name\": \"step3\", \"tag\": \"\", \"project\": \"proj1\"}, \"spec\": {\"command\": \"\", \"args\": [], \"image\": \"mlrun/mlrun\", \"build\": {\"functionSourceCode\": \"aW1wb3J0IHRpbWUKZGVmIGhhbmRsZXIgKGNvbnRleHQpOgogICAgY29udGV4dC5sb2dnZXIuaW5mbygnc3RhcnQnKQogICAgdGltZS5zbGVlcCgxMCkKICAgIGNvbnRleHQubG9nZ2VyLmluZm8oJ2VuZCcp\", \"commands\": [], \"code_origin\": \"/User/demos/getting-started-tutorial/scale/step1.py\", \"origin_filename\": \"/User/demos/getting-started-tutorial/scale/step1.py\"}, \"entry_points\": {\"handler\": {\"name\": \"handler\", \"doc\": \"\", \"parameters\": [{\"name\": \"context\", \"default\": \"\"}], \"outputs\": [{\"default\": \"\"}], \"lineno\": 2}}, \"description\": \"\", \"default_handler\": \"handler\", \"disable_auto_mount\": false, \"env\": [], \"priority_class_name\": \"igz-workload-medium\", \"affinity\": null}, \"verbose\": false}}], \"workflows\": [{\"name\": \"dummy_workflow\", \"path\": \"/User/demos/getting-started-tutorial/scale/pipelines.py\", \"handler\": \"dummy_workflow\", \"engine\": null}], \"artifacts\": [], \"source\": \"\", \"subpath\": \"\", \"origin_url\": \"\", \"disable_auto_mount\": false}, \"status\": {}}" + } + }, + { + "type": "project", + "id": "090b1327-ceff-45c7-867b-867b867b867b867b2221", + "attributes": { + "name": "network-operations-admin", + "created_at": "2022-03-10T10:24:36.235000+00:00", + "updated_at": "2022-03-14T14:01:13.399000+00:00", + "admin_status": "online", + "operational_status": "online", + "labels": [], + "annotations": [], + "mlrun_project": "{\"kind\": \"project\", \"metadata\": {}, \"spec\": {\"functions\": [{\"name\": \"step3\", \"spec\": {\"kind\": \"job\", \"metadata\": {\"name\": \"step3\", \"tag\": \"\", \"project\": \"proj1\"}, \"spec\": {\"command\": \"\", \"args\": [], \"image\": \"mlrun/mlrun\", \"build\": {\"functionSourceCode\": \"aW1wb3J0IHRpbWUKZGVmIGhhbmRsZXIgKGNvbnRleHQpOgogICAgY29udGV4dC5sb2dnZXIuaW5mbygnc3RhcnQnKQogICAgdGltZS5zbGVlcCgxMCkKICAgIGNvbnRleHQubG9nZ2VyLmluZm8oJ2VuZCcp\", \"commands\": [], \"code_origin\": \"/User/demos/getting-started-tutorial/scale/step1.py\", \"origin_filename\": \"/User/demos/getting-started-tutorial/scale/step1.py\"}, \"entry_points\": {\"handler\": {\"name\": \"handler\", \"doc\": \"\", \"parameters\": [{\"name\": \"context\", \"default\": \"\"}], \"outputs\": [{\"default\": \"\"}], \"lineno\": 2}}, \"description\": \"\", \"default_handler\": \"handler\", \"disable_auto_mount\": false, \"env\": [], \"priority_class_name\": \"igz-workload-medium\", \"affinity\": null}, \"verbose\": false}}], \"workflows\": [{\"name\": \"dummy_workflow\", \"path\": \"/User/demos/getting-started-tutorial/scale/pipelines.py\", \"handler\": \"dummy_workflow\", \"engine\": null}], \"artifacts\": [], \"source\": \"\", \"subpath\": \"\", \"origin_url\": \"\", \"disable_auto_mount\": false}, \"status\": {}}" + } + }, + { + "type": "project", + "id": "090b1327-ceff-45c7-867b-867ba99a82jdk", + "attributes": { + "name": "sk-project-admin", + "created_at": "2022-03-10T10:24:36.235000+00:00", + "updated_at": "2022-03-14T14:01:13.399000+00:00", + "admin_status": "online", + "operational_status": "online", + "labels": [], + "annotations": [], + "mlrun_project": "{\"kind\": \"project\", \"metadata\": {}, \"spec\": {\"functions\": [{\"name\": \"step3\", \"spec\": {\"kind\": \"job\", \"metadata\": {\"name\": \"step3\", \"tag\": \"\", \"project\": \"proj1\"}, \"spec\": {\"command\": \"\", \"args\": [], \"image\": \"mlrun/mlrun\", \"build\": {\"functionSourceCode\": \"aW1wb3J0IHRpbWUKZGVmIGhhbmRsZXIgKGNvbnRleHQpOgogICAgY29udGV4dC5sb2dnZXIuaW5mbygnc3RhcnQnKQogICAgdGltZS5zbGVlcCgxMCkKICAgIGNvbnRleHQubG9nZ2VyLmluZm8oJ2VuZCcp\", \"commands\": [], \"code_origin\": \"/User/demos/getting-started-tutorial/scale/step1.py\", \"origin_filename\": \"/User/demos/getting-started-tutorial/scale/step1.py\"}, \"entry_points\": {\"handler\": {\"name\": \"handler\", \"doc\": \"\", \"parameters\": [{\"name\": \"context\", \"default\": \"\"}], \"outputs\": [{\"default\": \"\"}], \"lineno\": 2}}, \"description\": \"\", \"default_handler\": \"handler\", \"disable_auto_mount\": false, \"env\": [], \"priority_class_name\": \"igz-workload-medium\", \"affinity\": null}, \"verbose\": false}}], \"workflows\": [{\"name\": \"dummy_workflow\", \"path\": \"/User/demos/getting-started-tutorial/scale/pipelines.py\", \"handler\": \"dummy_workflow\", \"engine\": null}], \"artifacts\": [], \"source\": \"\", \"subpath\": \"\", \"origin_url\": \"\", \"disable_auto_mount\": false}, \"status\": {}}" + } + }, + { + "type": "project", + "id": "090b1327-ceff-45c7-867b-ooos992ksl", + "attributes": { + "name": "stocks", + "created_at": "2022-03-10T10:24:36.235000+00:00", + "updated_at": "2022-03-14T14:01:13.399000+00:00", + "admin_status": "online", + "operational_status": "online", + "labels": [], + "annotations": [], + "mlrun_project": "{\"kind\": \"project\", \"metadata\": {}, \"spec\": {\"functions\": [{\"name\": \"step3\", \"spec\": {\"kind\": \"job\", \"metadata\": {\"name\": \"step3\", \"tag\": \"\", \"project\": \"proj1\"}, \"spec\": {\"command\": \"\", \"args\": [], \"image\": \"mlrun/mlrun\", \"build\": {\"functionSourceCode\": \"aW1wb3J0IHRpbWUKZGVmIGhhbmRsZXIgKGNvbnRleHQpOgogICAgY29udGV4dC5sb2dnZXIuaW5mbygnc3RhcnQnKQogICAgdGltZS5zbGVlcCgxMCkKICAgIGNvbnRleHQubG9nZ2VyLmluZm8oJ2VuZCcp\", \"commands\": [], \"code_origin\": \"/User/demos/getting-started-tutorial/scale/step1.py\", \"origin_filename\": \"/User/demos/getting-started-tutorial/scale/step1.py\"}, \"entry_points\": {\"handler\": {\"name\": \"handler\", \"doc\": \"\", \"parameters\": [{\"name\": \"context\", \"default\": \"\"}], \"outputs\": [{\"default\": \"\"}], \"lineno\": 2}}, \"description\": \"\", \"default_handler\": \"handler\", \"disable_auto_mount\": false, \"env\": [], \"priority_class_name\": \"igz-workload-medium\", \"affinity\": null}, \"verbose\": false}}], \"workflows\": [{\"name\": \"dummy_workflow\", \"path\": \"/User/demos/getting-started-tutorial/scale/pipelines.py\", \"handler\": \"dummy_workflow\", \"engine\": null}], \"artifacts\": [], \"source\": \"\", \"subpath\": \"\", \"origin_url\": \"\", \"disable_auto_mount\": false}, \"status\": {}}" + } + }, + { + "type": "project", + "id": "090b1327-ceff-45c7-867b-2ososolzmn221l", + "attributes": { + "name": "stocks-admin", + "created_at": "2022-03-10T10:24:36.235000+00:00", + "updated_at": "2022-03-14T14:01:13.399000+00:00", + "admin_status": "online", + "operational_status": "online", + "labels": [], + "annotations": [], + "mlrun_project": "{\"kind\": \"project\", \"metadata\": {}, \"spec\": {\"functions\": [{\"name\": \"step3\", \"spec\": {\"kind\": \"job\", \"metadata\": {\"name\": \"step3\", \"tag\": \"\", \"project\": \"proj1\"}, \"spec\": {\"command\": \"\", \"args\": [], \"image\": \"mlrun/mlrun\", \"build\": {\"functionSourceCode\": \"aW1wb3J0IHRpbWUKZGVmIGhhbmRsZXIgKGNvbnRleHQpOgogICAgY29udGV4dC5sb2dnZXIuaW5mbygnc3RhcnQnKQogICAgdGltZS5zbGVlcCgxMCkKICAgIGNvbnRleHQubG9nZ2VyLmluZm8oJ2VuZCcp\", \"commands\": [], \"code_origin\": \"/User/demos/getting-started-tutorial/scale/step1.py\", \"origin_filename\": \"/User/demos/getting-started-tutorial/scale/step1.py\"}, \"entry_points\": {\"handler\": {\"name\": \"handler\", \"doc\": \"\", \"parameters\": [{\"name\": \"context\", \"default\": \"\"}], \"outputs\": [{\"default\": \"\"}], \"lineno\": 2}}, \"description\": \"\", \"default_handler\": \"handler\", \"disable_auto_mount\": false, \"env\": [], \"priority_class_name\": \"igz-workload-medium\", \"affinity\": null}, \"verbose\": false}}], \"workflows\": [{\"name\": \"dummy_workflow\", \"path\": \"/User/demos/getting-started-tutorial/scale/pipelines.py\", \"handler\": \"dummy_workflow\", \"engine\": null}], \"artifacts\": [], \"source\": \"\", \"subpath\": \"\", \"origin_url\": \"\", \"disable_auto_mount\": false}, \"status\": {}}" + } + }, + { + "type": "project", + "id": "090b1327-ceff-45c7-867b-ooos992kslas2", + "attributes": { + "name": "test-test", + "created_at": "2022-03-10T10:24:36.235000+00:00", + "updated_at": "2022-03-14T14:01:13.399000+00:00", + "admin_status": "online", + "operational_status": "online", + "labels": [], + "annotations": [], + "mlrun_project": "{\"kind\": \"project\", \"metadata\": {}, \"spec\": {\"functions\": [{\"name\": \"step3\", \"spec\": {\"kind\": \"job\", \"metadata\": {\"name\": \"step3\", \"tag\": \"\", \"project\": \"proj1\"}, \"spec\": {\"command\": \"\", \"args\": [], \"image\": \"mlrun/mlrun\", \"build\": {\"functionSourceCode\": \"aW1wb3J0IHRpbWUKZGVmIGhhbmRsZXIgKGNvbnRleHQpOgogICAgY29udGV4dC5sb2dnZXIuaW5mbygnc3RhcnQnKQogICAgdGltZS5zbGVlcCgxMCkKICAgIGNvbnRleHQubG9nZ2VyLmluZm8oJ2VuZCcp\", \"commands\": [], \"code_origin\": \"/User/demos/getting-started-tutorial/scale/step1.py\", \"origin_filename\": \"/User/demos/getting-started-tutorial/scale/step1.py\"}, \"entry_points\": {\"handler\": {\"name\": \"handler\", \"doc\": \"\", \"parameters\": [{\"name\": \"context\", \"default\": \"\"}], \"outputs\": [{\"default\": \"\"}], \"lineno\": 2}}, \"description\": \"\", \"default_handler\": \"handler\", \"disable_auto_mount\": false, \"env\": [], \"priority_class_name\": \"igz-workload-medium\", \"affinity\": null}, \"verbose\": false}}], \"workflows\": [{\"name\": \"dummy_workflow\", \"path\": \"/User/demos/getting-started-tutorial/scale/pipelines.py\", \"handler\": \"dummy_workflow\", \"engine\": null}], \"artifacts\": [], \"source\": \"\", \"subpath\": \"\", \"origin_url\": \"\", \"disable_auto_mount\": false}, \"status\": {}}" + } + }, { "type": "project", "id": "090b1327-ceff-45c7-867b-476968022be6", diff --git a/tests/mockServer/data/iguazioSelf.json b/tests/mockServer/data/iguazioSelf.json index ce77daf4b1..e6fad8548f 100644 --- a/tests/mockServer/data/iguazioSelf.json +++ b/tests/mockServer/data/iguazioSelf.json @@ -1,7 +1,7 @@ { "data": { "type": "user", - "id": "20ab4d74-3b45-447c-aef7-47797b7a31d5", + "id": "08debad1-e697-48b1-891c-6c9029aeee03", "attributes": { "username": "admin", "first_name": "Administrator", diff --git a/tests/mockServer/data/iguazioUserRelations.json b/tests/mockServer/data/iguazioUserRelations.json index 063ba48c99..d9f3495172 100644 --- a/tests/mockServer/data/iguazioUserRelations.json +++ b/tests/mockServer/data/iguazioUserRelations.json @@ -1,5 +1,50 @@ { "08debad1-e697-48b1-891c-6c9029aeee03": [ + { + "type": "project", + "id": "090b1327-ceff-45c7-867b-4769680238386", + "relationships": null + }, + { + "type": "project", + "id": "090b1327-ceff-45c7-867b-476968023838622", + "relationships": null + }, + { + "type": "project", + "id": "090b1327-ceff-45c7-867b-4769680238386111", + "relationships": null + }, + { + "type": "project", + "id": "090b1327-ceff-45c7-867b-867b867b867b867b2", + "relationships": null + }, + { + "type": "project", + "id": "090b1327-ceff-45c7-867b-867b867b867b867b2221", + "relationships": null + }, + { + "type": "project", + "id": "090b1327-ceff-45c7-867b-867ba99a82jdk", + "relationships": null + }, + { + "type": "project", + "id": "090b1327-ceff-45c7-867b-ooos992ksl", + "relationships": null + }, + { + "type": "project", + "id": "090b1327-ceff-45c7-867b-2ososolzmn221l", + "relationships": null + }, + { + "type": "project", + "id": "090b1327-ceff-45c7-867b-ooos992kslas2", + "relationships": null + }, { "type": "project", "id": "1e287a06-3dd7-498d-ac0f-f38ce413a7eb", diff --git a/tests/mockServer/data/logs.json b/tests/mockServer/data/logs.json index 90dd701a6e..59e688a76a 100644 --- a/tests/mockServer/data/logs.json +++ b/tests/mockServer/data/logs.json @@ -2074,5 +2074,24 @@ { "uid": "c236200fde53460784065bdf65e4ede8", "log": "Traceback (most recent call last):\n File \"/usr/local/bin/mlrun\", line 8, in \n sys.exit(main())\n File \"/usr/local/lib/python3.7/site-packages/click/core.py\", line 829, in __call__\n return self.main(*args, **kwargs)\n File \"/usr/local/lib/python3.7/site-packages/click/core.py\", line 782, in main\n rv = self.invoke(ctx)\n File \"/usr/local/lib/python3.7/site-packages/click/core.py\", line 1259, in invoke\n return _process_result(sub_ctx.command.invoke(sub_ctx))\n File \"/usr/local/lib/python3.7/site-packages/click/core.py\", line 1066, in invoke\n return ctx.invoke(self.callback, **ctx.params)\n File \"/usr/local/lib/python3.7/site-packages/click/core.py\", line 610, in invoke\n return callback(*args, **kwargs)\n File \"/usr/local/lib/python3.7/site-packages/mlrun/__main__.py\", line 333, in run\n resp = fn.run(runobj, watch=watch, schedule=schedule, local=local)\n File \"/usr/local/lib/python3.7/site-packages/mlrun/runtimes/base.py\", line 483, in run\n resp = self._run(runspec, execution)\n File \"/usr/local/lib/python3.7/site-packages/mlrun/runtimes/local.py\", line 232, in _run\n mod, fn = self._get_handler(handler)\n File \"/usr/local/lib/python3.7/site-packages/mlrun/runtimes/local.py\", line 185, in _get_handler\n return load_module(self.spec.command, handler)\n File \"/usr/local/lib/python3.7/site-packages/mlrun/runtimes/local.py\", line 308, in load_module\n spec.loader.exec_module(mod)\n File \"\", line 728, in exec_module\n File \"\", line 219, in _call_with_frames_removed\n File \"main.py\", line 4, in \n import pyhive\nModuleNotFoundError: No module named 'pyhive'\n" + }, + { + "uid": "98418b756c4b4307be9a3e7c39e66f21", + "log": [ + "> 2025-09-04 12:45:48,842 [error] Execution error, Traceback (most recent call last):", + " File \"/opt/conda/lib/python3.9/site-packages/mlrun/runtimes/local.py\", line 501, in exec_from_params", + " val = mlrun.handler(", + " File \"/opt/conda/lib/python3.9/site-packages/mlrun/package/__init__.py\", line 137, in wrapper", + " func_outputs = func(*args, **kwargs)", + " File \"fnxot.py\", line 2, in handler", + " raise Exception(\"This function intentionally fails\")", + "Exception: This function intentionally fails", + "> 2025-09-04 12:45:48,886 [error] Exec error - This function intentionally fails", + "This function intentionally fails", + "> 2025-09-04 12:45:48,933 [info] To track results use the CLI: {\"info_cmd\":\"mlrun get run 98418b756c4b4307be9a3e7c39e66f21 -p mm-alerts-proj\",\"logs_cmd\":\"mlrun logs 98418b756c4b4307be9a3e7c39e66f21 -p mm-alerts-proj\"}", + "> 2025-09-04 12:45:48,933 [info] Or click for UI: {\"ui_url\":\"https://dashboard.default-tenant.app.vmdev82.lab.iguazeng.com/mlprojects/mm-alerts-proj/jobs/monitor-jobs/test-func-oyn-handler/98418b756c4b4307be9a3e7c39e66f21/overview\"}", + "> 2025-09-04 12:45:48,934 [info] Run execution finished: {\"name\":\"test-func-oyn-handler\",\"status\":\"error\"}", + "Runtime error: This function intentionally fails" + ] } ] diff --git a/tests/mockServer/data/metrics.json b/tests/mockServer/data/metrics.json index 7b9c00f846..056fc370c0 100644 --- a/tests/mockServer/data/metrics.json +++ b/tests/mockServer/data/metrics.json @@ -12,30 +12,231 @@ "project": "default" }, { - "full_name": "default.histogram-data-drift-1.metric.tvdar_mean_1", + "full_name": "default.monitorAppV1.metric.tvdar_mean_1", "type": "metric", - "app": "histogram-data-drift-1", + "app": "monitorAppV1", "name": "tvdar_mean_1", "project": "default" }, { - "full_name": "default.histogram-data-drift-1.metric.tvdop_mean_1", + "full_name": "default.monitorAppV1.metric.tvdop_mean_1", "type": "metric", - "app": "histogram-data-drift-1", + "app": "monitorAppV1", "name": "tvdop_mean_1", "project": "default" }, { - "full_name": "default.histogram-data-drift-1.metric.tvds_mean_1", + "full_name": "default.monitorAppV1.metric.tvds_mean_1", "type": "metric", - "app": "histogram-data-drift-1", + "app": "monitorAppV1", "name": "tvds_mean_1", "project": "default" }, { - "full_name": "default.evidently-app-test.result.hellinger_mean_1", + "full_name": "default.monitorAppV1.result.hellinger_mean_1", "type": "result", - "app": "evidently-app-test", + "app": "monitorAppV1", + "name": "hellinger_mean_1", + "project": "default" + }, + { + "full_name": "default.monitorAppV1.metric.data_drift_test_1", + "type": "metric", + "app": "monitorAppV1", + "name": "data_drift_test_1", + "project": "default" + }, + { + "full_name": "default.monitorAppV1.metric.general_drift_1", + "type": "metric", + "app": "monitorAppV1", + "name": "general_drift_1", + "project": "default" + }, + { + "full_name": "default.monitorAppV1.result.model_perf_1", + "type": "result", + "app": "monitorAppV1", + "name": "model_perf_1", + "project": "default" + }, + { + "full_name": "default.monitorAppV1.metric.kld_mean_1", + "type": "metric", + "app": "monitorAppV1", + "name": "kld_mean_1", + "project": "default" + }, + { + "full_name": "default.monitorAppV2.metric.kld_mean_1", + "type": "metric", + "app": "monitorAppV2", + "name": "kld_mean_1", + "project": "default" + } + ], + "metricsValues": [ + { + "full_name": "default.rujmfi.result.data_drift_test", + "type": "result", + "data": "true", + "values": [ + 10 + ] + }, + { + "full_name": "default.hskoyl.result.data_drift_test", + "type": "result", + "data": "true", + "values": [ + 5 + ] + }, + { + "full_name": "default.mlrun-infra.metric.invocations-rate", + "type": "metric", + "data": "true", + "values": [ + 10, true + ] + }, + { + "full_name": "default.monitorAppV1.metric.tvdar_mean_1", + "type": "metric", + "data": "true", + "values": [ + 10 + ] + }, + { + "full_name": "default.monitorAppV1.metric.tvdop_mean_1", + "type": "metric", + "data": "true", + "values": [ + 10 + ] + }, + { + "full_name": "default.monitorAppV1.metric.tvds_mean_1", + "type": "metric", + "data": false + }, + { + "full_name": "default.monitorAppV1.result.hellinger_mean_1", + "type": "result", + "result_kind": 0, + "data": "true", + "values": [ + 10 + ] + }, + { + "full_name": "default.monitorAppV1.metric.data_drift_test_1", + "type": "metric", + "data": "true", + "values": [ + 10 + ] + }, + { + "full_name": "default.monitorAppV1.metric.general_drift_1", + "type": "metric", + "data": "true", + "values": [ + 10 + ] + }, + { + "full_name": "default.monitorAppV1.result.model_perf_1", + "type": "result", + "result_kind": 1, + "data": "true", + "values": [ + 10 + ] + }, + { + "full_name": "default.monitorAppV1.metric.kld_mean_1", + "type": "metric", + "data": "true", + "values": [ + 10 + ] + }, + { + "full_name": "default.monitorAppV2.metric.kld_mean_1", + "type": "metric", + "data": "true", + "values": [ + 10 + ] + } + ] + }, + { + "modelEndpointUID": "a7c95783e6a726a1a233e581ea898ba44fa7e342", + "project": "default", + "metricsOptions": [ + { + "full_name": "default.mlrun-infra.metric.invocations-rate", + "type": "metric", + "app": "mlrun-infra", + "name": "invocations-rate", + "project": "default" + }, + { + "full_name": "default.monitorAppV1.metric.tvdar_mean_1", + "type": "metric", + "app": "monitorAppV1", + "name": "tvdar_mean_1", + "project": "default" + }, + { + "full_name": "default.monitorAppV2.metric.tvdar_mean_1", + "type": "metric", + "app": "monitorAppV2", + "name": "tvdar_mean_1", + "project": "default" + }, + { + "full_name": "default.monitorAppV3.metric.tvdar_mean_1", + "type": "metric", + "app": "monitorAppV3", + "name": "tvdar_mean_1", + "project": "default" + }, + { + "full_name": "default.monitorAppV1.metric.tvdop_mean_1", + "type": "metric", + "app": "monitorAppV1", + "name": "tvdop_mean_1", + "project": "default" + }, + { + "full_name": "default.monitorAppV2.metric.tvdop_mean_1", + "type": "metric", + "app": "monitorAppV2", + "name": "tvdop_mean_1", + "project": "default" + }, + { + "full_name": "default.monitorAppV1.metric.tvds_mean_1", + "type": "metric", + "app": "monitorAppV1", + "name": "tvds_mean_1", + "project": "default" + }, + { + "full_name": "default.monitorAppV3.metric.tvds_mean_1", + "type": "metric", + "app": "monitorAppV3", + "name": "tvds_mean_1", + "project": "default" + }, + { + "full_name": "default.monitorAppV1.result.hellinger_mean_1", + "type": "result", + "app": "monitorAppV1", "name": "hellinger_mean_1", "project": "default" }, @@ -101,7 +302,7 @@ ] }, { - "full_name": "default.histogram-data-drift-1.metric.tvdar_mean_1", + "full_name": "default.monitorAppV1.metric.tvdar_mean_1", "type": "metric", "data": "true", "values": [ @@ -109,7 +310,7 @@ ] }, { - "full_name": "default.histogram-data-drift-1.metric.tvdop_mean_1", + "full_name": "default.monitorAppV2.metric.tvdar_mean_1", "type": "metric", "data": "true", "values": [ @@ -117,12 +318,41 @@ ] }, { - "full_name": "default.histogram-data-drift-1.metric.tvds_mean_1", + "full_name": "default.monitorAppV3.metric.tvdar_mean_1", + "type": "metric", + "data": "true", + "values": [ + 10 + ] + }, + { + "full_name": "default.monitorAppV2.metric.tvdop_mean_1", + "type": "metric", + "data": "true", + "values": [ + 10 + ] + }, + { + "full_name": "default.monitorAppV1.metric.tvdop_mean_1", + "type": "metric", + "data": "true", + "values": [ + 10 + ] + }, + { + "full_name": "default.monitorAppV1.metric.tvds_mean_1", + "type": "metric", + "data": false + }, + { + "full_name": "default.monitorAppV3.metric.tvds_mean_1", "type": "metric", "data": false }, { - "full_name": "default.evidently-app-test.result.hellinger_mean_1", + "full_name": "default.monitorAppV1.result.hellinger_mean_1", "type": "result", "result_kind": 0, "data": "true", diff --git a/tests/mockServer/data/modelEndpoints.json b/tests/mockServer/data/modelEndpoints.json index 96ac7a9b0c..6c8b119d92 100644 --- a/tests/mockServer/data/modelEndpoints.json +++ b/tests/mockServer/data/modelEndpoints.json @@ -1,5 +1,54 @@ { "endpoints": [ + { + "kind": "model-endpoint", + "metadata": { + "name": "my-endpoint", + "project": "default", + "tag": null, + "labels": { + "example": "single", + "hebrew": "english" + }, + "updated": "2025-10-06T14:34:14.015000", + "created": "2025-09-30T19:45:05.516000", + "uid": "c3e9308aaab54e53b1013ecda9234e43", + "endpoint_type": 1, + "mode": 0 + }, + "spec": { + "model_class": "MyLLM", + "function_name": "function-with-llm", + "function_tag": "latest", + "model_path": "store://llm-prompts/default/my_llm4#0@be464b11-8bff-4d57-9ad5-89d7d641f35e^5523a661476a8ab1ba573c704308f036e62b8d17", + "model_name": "my_llm4", + "model_tags": [ + "latest" + ], + "feature_names": [], + "label_names": [], + "feature_stats": {}, + "function_uri": "default/function-with-llm@unversioned-latest", + "model_uri": "store://llm-prompts/default/my_llm4#0@9c0c8773-b1ce-4fa0-ac94-2f6c1fb71554^d28e010ba24e272a3ba2ba522f6caecde05ff383", + "children": null, + "children_uids": null, + "monitoring_feature_set_uri": "" + }, + "status": { + "state": "ready", + "first_request": null, + "monitoring_mode": "disabled", + "sampling_percentage": 100, + "last_request": null, + "result_status": -1, + "avg_latency": null, + "error_count": 0, + "current_stats": {}, + "current_stats_timestamp": null, + "drift_measures": {}, + "drift_measures_timestamp": null + } + }, { "kind": "model-endpoint", "metadata": { @@ -10,6 +59,7 @@ "v3io_user": "admin" }, "endpoint_type": 3, + "mode": 0, "name": "RandomForestClassifier", "created": "2024-11-03T09:18:59.079000", "updated": "2024-11-03T09:40:58.317000", @@ -266,23 +316,28 @@ "kind": "model-endpoint", "metadata": { "project": "default", - "labels": {}, + "labels": { + "my-key": "my-value", + "owner": "admin", + "v3io_user": "admin" + }, "endpoint_type": 3, - "name": "GradientBoostingClassifier", - "created": "2024-12-03T09:18:59.079000", - "updated": "2024-12-03T09:40:58.317000", - "uid": "d6df9915e64e9ba9441a82983d9fc7f874550b31" + "mode": 1, + "name": "RandomForestClassifier2", + "created": "2024-11-03T09:18:59.079000", + "updated": "2024-11-03T09:40:58.317000", + "uid": "a7c95783e6a726a1a233e581ea898ba44fa7e342" }, "spec": { "function_name": "transaction-fraud", "function_tag": "latest", "function_uid": "unversioned-latest", - "function_uri": "default/vizro@69200c7de5447f61f15bd28913714c5970b831eb", - "model_name": "GradientBoostingClassifier", + "function_uri": "default/aggregate@79fd83704a8514dc2415bded0e9d0ffd94262e92", + "model_name": "RandomForestClassifier", + "model_class": "ClassifierModel", "model_uid": "898baa010eb35b914558182ad487bc582defde34", "model_tag": null, - "model_class": "ClassifierModel", - "model_uri": "store://models/default/train_model:latest", + "model_uri": "store://models/default/model_default:latest", "feature_names": [ "amount_max_2h", "amount_sum_2h", @@ -389,7 +444,7 @@ ] } }, - "monitoring_feature_set_uri": "store://feature-sets/default/test-m2:latest" + "monitoring_feature_set_uri": "store://feature-sets/default/stocks:latest" }, "status": { "state": null, @@ -479,11 +534,11 @@ ] } }, - "first_request": "2022-05-02 11:14:21.082452+00:00", - "last_request": "2022-05-19 09:43:49.502382+00:00", + "first_request": "2022-05-02 11:14:21.082236+00:00", + "last_request": "2022-05-19 09:43:49.502045+00:00", "error_count": null, - "avg_latency": null, "drift_status": "DRIFT_DETECTED", + "avg_latency": null, "drift_measures": { "amount_max_2h": { "tvd": 0.9006299904768882, @@ -517,7 +572,624 @@ "kld": 3.8755852058078455 } }, - "sampling_percentage": null + "sampling_percentage": 20 + } + }, + { + "kind": "model-endpoint", + "metadata": { + "project": "default", + "labels": {}, + "endpoint_type": 3, + "mode": 0, + "name": "GradientBoostingClassifier", + "created": "2024-12-03T09:18:59.079000", + "updated": "2024-12-03T09:40:58.317000", + "uid": "d6df9915e64e9ba9441a82983d9fc7f874550b31" + }, + "spec": { + "function_name": "transaction-fraud", + "function_tag": "latest", + "function_uid": "unversioned-latest", + "function_uri": "default/vizro@69200c7de5447f61f15bd28913714c5970b831eb", + "model_name": "GradientBoostingClassifier", + "model_uid": "898baa010eb35b914558182ad487bc582defde34", + "model_tag": null, + "model_class": "ClassifierModel", + "model_uri": "store://models/default/train_model:latest", + "feature_names": [ + "amount_max_2h", + "amount_sum_2h", + "amount_count_2h", + "amount_avg_2h", + "amount_max_12h", + "label" + ], + "label_names": ["label", "__index_level_0__"], + "children": null, + "children_uids": null, + "feature_stats": { + "amount_max_2h": { + "count": 7446, + "mean": 41.994970453935, + "std": 104.4010819361322, + "min": 0, + "max": 4759.79, + "hist": [ + [7352, 57, 19, 6, 2, 2, 0, 1, 3, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1], + [ + 0, 237.9895, 475.979, 713.9685, 951.958, 1189.9475, 1427.937, 1665.9265, 1903.916, + 2141.9055, 2379.895, 2617.8845, 2855.874, 3093.8635, 3331.853, 3569.8424999999997, + 3807.832, 4045.8215, 4283.811, 4521.8005, 4759.79 + ] + ] + }, + "amount_sum_2h": { + "count": 7446, + "mean": 46.912805533172175, + "std": 107.48110128941029, + "min": -147.49, + "max": 4770.01, + "hist": [ + [6920, 467, 32, 13, 2, 3, 1, 0, 4, 0, 2, 0, 0, 1, 0, 0, 0, 0, 0, 1], + [ + -147.49, 98.38499999999999, 344.26, 590.135, 836.01, 1081.885, 1327.76, 1573.635, + 1819.51, 2065.385, 2311.26, 2557.135, 2803.01, 3048.885, 3294.76, 3540.635, 3786.51, + 4032.385, 4278.26, 4524.135, 4770.01 + ] + ] + }, + "amount_count_2h": { + "count": 7446, + "mean": 1.2539618587160892, + "std": 0.5436930806122989, + "min": -1, + "max": 6, + "hist": [ + [6, 0, 0, 0, 0, 5860, 0, 0, 1306, 0, 0, 229, 0, 0, 42, 0, 0, 2, 0, 1], + [ + -1, -0.65, -0.30000000000000004, 0.04999999999999982, 0.3999999999999999, 0.75, + 1.0999999999999996, 1.4499999999999997, 1.7999999999999998, 2.15, 2.5, + 2.8499999999999996, 3.1999999999999993, 3.55, 3.8999999999999995, 4.25, 4.6, + 4.949999999999999, 5.3, 5.6499999999999995, 6 + ] + ] + }, + "amount_avg_2h": { + "count": 7446, + "mean": 38.96664405945027, + "std": 140.24284088047725, + "min": -107.44000000000001, + "max": 6405.95, + "hist": [ + [7366, 49, 19, 4, 0, 0, 3, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2], + [ + -107.44000000000001, 218.22949999999997, 543.8989999999999, 869.5684999999999, + 1195.2379999999998, 1520.9074999999998, 1846.5769999999998, 2172.2464999999997, + 2497.9159999999997, 2823.5854999999997, 3149.2549999999997, 3474.9244999999996, + 3800.5939999999996, 4126.2635, 4451.933, 4777.6025, 5103.272, 5428.9415, 5754.611, + 6080.2805, 6405.95 + ] + ] + }, + "amount_max_12h": { + "count": 7446, + "mean": 53.890123556271824, + "std": 122.18467228149133, + "min": 0, + "max": 4759.79, + "hist": [ + [7300, 92, 24, 13, 3, 4, 0, 2, 3, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1], + [ + 0, 237.9895, 475.979, 713.9685, 951.958, 1189.9475, 1427.937, 1665.9265, 1903.916, + 2141.9055, 2379.895, 2617.8845, 2855.874, 3093.8635, 3331.853, 3569.8424999999997, + 3807.832, 4045.8215, 4283.811, 4521.8005, 4759.79 + ] + ] + }, + "label": { + "count": 7446, + "mean": 0.014907332796132152, + "std": 0.12119025003595912, + "min": 0, + "max": 1, + "hist": [ + [7335, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111], + [ + 0, 0.05, 0.1, 0.15000000000000002, 0.2, 0.25, 0.30000000000000004, + 0.35000000000000003, 0.4, 0.45, 0.5, 0.55, 0.6000000000000001, 0.65, + 0.7000000000000001, 0.75, 0.8, 0.8500000000000001, 0.9, 0.9500000000000001, 1 + ] + ] + } + }, + "monitoring_feature_set_uri": "store://feature-sets/default/test-m2:latest" + }, + "status": { + "state": null, + "monitoring_mode": "enabled", + "current_stats": { + "amount_avg_2h": { + "count": 11, + "mean": 28.0887273020327, + "std": 11.304901433309531, + "min": 12.19, + "max": 38.615200064471935, + "hist": [ + [1, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5], + [ + 12.19, 13.511260003223596, 14.832520006447194, 16.15378000967079, + 17.475040012894386, 18.796300016117982, 20.117560019341582, 21.438820022565178, + 22.760080025788774, 24.08134002901237, 25.402600032235966, 26.723860035459566, + 28.04512003868316, 29.36638004190676, 30.687640045130358, 32.00890004835395, + 33.33016005157755, 34.65142005480114, 35.97268005802474, 37.29394006124834, + 38.615200064471935 + ] + ] + }, + "amount_count_2h": { + "count": 11, + "mean": 0.5454545454545454, + "std": 0.5222329678670935, + "min": 0, + "max": 1, + "hist": [ + [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6], + [ + 0, 0.05, 0.1, 0.15000000000000002, 0.2, 0.25, 0.30000000000000004, + 0.35000000000000003, 0.4, 0.45, 0.5, 0.55, 0.6000000000000001, 0.65, + 0.7000000000000001, 0.75, 0.8, 0.8500000000000001, 0.9, 0.9500000000000001, 1 + ] + ] + }, + "amount_max_12h": { + "count": 11, + "mean": 55.03636363636363, + "std": 57.971923596293976, + "min": 20.92, + "max": 224.11, + "hist": [ + [3, 4, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], + [ + 20.92, 31.079500000000003, 41.239000000000004, 51.3985, 61.558, 71.7175, 81.877, + 92.0365, 102.196, 112.35549999999999, 122.515, 132.6745, 142.834, + 152.99349999999998, 163.15300000000002, 173.3125, 183.47199999999998, + 193.63150000000002, 203.791, 213.95049999999998, 224.11 + ] + ] + }, + "amount_max_2h": { + "count": 11, + "mean": 29.96273243391514, + "std": 13.260285022445734, + "min": 12.19, + "max": 42.738011354613306, + "hist": [ + [1, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 5], + [ + 12.19, 13.717400567730666, 15.24480113546133, 16.772201703191996, + 18.299602270922662, 19.82700283865333, 21.354403406383994, 22.881803974114657, + 24.409204541845323, 25.93660510957599, 27.464005677306652, 28.991406245037318, + 30.518806812767984, 32.04620738049865, 33.573607948229316, 35.10100851595998, + 36.62840908369065, 38.155809651421315, 39.68321021915198, 41.21061078688264, + 42.738011354613306 + ] + ] + }, + "amount_sum_2h": { + "count": 11, + "mean": 10.536363636363637, + "std": 11.31334457419845, + "min": 0, + "max": 30.42, + "hist": [ + [5, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1], + [ + 0, 1.5210000000000001, 3.0420000000000003, 4.563000000000001, 6.0840000000000005, + 7.605, 9.126000000000001, 10.647, 12.168000000000001, 13.689000000000002, 15.21, + 16.731, 18.252000000000002, 19.773000000000003, 21.294, 22.815, 24.336000000000002, + 25.857000000000003, 27.378000000000004, 28.899, 30.42 + ] + ] + } + }, + "first_request": "2022-05-02 11:14:21.082452+00:00", + "last_request": "2022-05-19 09:43:49.502382+00:00", + "error_count": null, + "avg_latency": null, + "drift_status": "DRIFT_DETECTED", + "drift_measures": { + "amount_max_2h": { + "tvd": 0.9006299904768882, + "hellinger": 0.8026729143746129, + "kld": 8.03097275516625 + }, + "tvd_sum": 4.0574683173393895, + "tvd_mean": 0.8114936634678779, + "hellinger_sum": 3.7935228606235265, + "hellinger_mean": 0.7587045721247053, + "kld_sum": 40.22159405569385, + "kld_mean": 8.04431881113877, + "amount_count_2h": { + "tvd": 0.9990598979317755, + "hellinger": 0.9860541717475733, + "kld": 15.975132772583372 + }, + "amount_avg_2h": { + "tvd": 0.9019729934314947, + "hellinger": 0.8046642697553347, + "kld": 7.91538219147246 + }, + "amount_sum_2h": { + "tvd": 0.5447830439772423, + "hellinger": 0.5827239245591163, + "kld": 4.424521130663923 + }, + "amount_max_12h": { + "tvd": 0.7110223915219885, + "hellinger": 0.6174075801868897, + "kld": 3.8755852058078455 + } + }, + "sampling_percentage": null + } + }, + { + "kind": "model-endpoint", + "metadata": { + "project": "default", + "labels": {}, + "endpoint_type": 3, + "mode": 1, + "name": "GradientBoostingClassifier2", + "created": "2024-12-03T09:18:59.079000", + "updated": "2024-12-03T09:40:58.317000", + "uid": "d6df9915e64e9ba9441a82983c4yc7f874550b31" + }, + "spec": { + "function_name": "transaction-fraud", + "function_tag": "latest", + "function_uid": "unversioned-latest", + "function_uri": "default/vizro@69200c7de5447f61f15bd28913714c5970b831eb", + "model_name": "GradientBoostingClassifier2", + "model_uid": "898baa010eb35b914558182ad487bc582defde34", + "model_tag": null, + "model_class": "ClassifierModel", + "model_uri": "store://models/default/train_model:latest", + "feature_names": [ + "amount_max_2h", + "amount_sum_2h", + "amount_count_2h", + "amount_avg_2h", + "amount_max_12h", + "label" + ], + "label_names": ["label", "__index_level_0__"], + "children": null, + "children_uids": null, + "feature_stats": { + "amount_max_2h": { + "count": 7446, + "mean": 41.994970453935, + "std": 104.4010819361322, + "min": 0, + "max": 4759.79, + "hist": [ + [7352, 57, 19, 6, 2, 2, 0, 1, 3, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1], + [ + 0, 237.9895, 475.979, 713.9685, 951.958, 1189.9475, 1427.937, 1665.9265, 1903.916, + 2141.9055, 2379.895, 2617.8845, 2855.874, 3093.8635, 3331.853, 3569.8424999999997, + 3807.832, 4045.8215, 4283.811, 4521.8005, 4759.79 + ] + ] + }, + "amount_sum_2h": { + "count": 7446, + "mean": 46.912805533172175, + "std": 107.48110128941029, + "min": -147.49, + "max": 4770.01, + "hist": [ + [6920, 467, 32, 13, 2, 3, 1, 0, 4, 0, 2, 0, 0, 1, 0, 0, 0, 0, 0, 1], + [ + -147.49, 98.38499999999999, 344.26, 590.135, 836.01, 1081.885, 1327.76, 1573.635, + 1819.51, 2065.385, 2311.26, 2557.135, 2803.01, 3048.885, 3294.76, 3540.635, 3786.51, + 4032.385, 4278.26, 4524.135, 4770.01 + ] + ] + }, + "amount_count_2h": { + "count": 7446, + "mean": 1.2539618587160892, + "std": 0.5436930806122989, + "min": -1, + "max": 6, + "hist": [ + [6, 0, 0, 0, 0, 5860, 0, 0, 1306, 0, 0, 229, 0, 0, 42, 0, 0, 2, 0, 1], + [ + -1, -0.65, -0.30000000000000004, 0.04999999999999982, 0.3999999999999999, 0.75, + 1.0999999999999996, 1.4499999999999997, 1.7999999999999998, 2.15, 2.5, + 2.8499999999999996, 3.1999999999999993, 3.55, 3.8999999999999995, 4.25, 4.6, + 4.949999999999999, 5.3, 5.6499999999999995, 6 + ] + ] + }, + "amount_avg_2h": { + "count": 7446, + "mean": 38.96664405945027, + "std": 140.24284088047725, + "min": -107.44000000000001, + "max": 6405.95, + "hist": [ + [7366, 49, 19, 4, 0, 0, 3, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2], + [ + -107.44000000000001, 218.22949999999997, 543.8989999999999, 869.5684999999999, + 1195.2379999999998, 1520.9074999999998, 1846.5769999999998, 2172.2464999999997, + 2497.9159999999997, 2823.5854999999997, 3149.2549999999997, 3474.9244999999996, + 3800.5939999999996, 4126.2635, 4451.933, 4777.6025, 5103.272, 5428.9415, 5754.611, + 6080.2805, 6405.95 + ] + ] + }, + "amount_max_12h": { + "count": 7446, + "mean": 53.890123556271824, + "std": 122.18467228149133, + "min": 0, + "max": 4759.79, + "hist": [ + [7300, 92, 24, 13, 3, 4, 0, 2, 3, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1], + [ + 0, 237.9895, 475.979, 713.9685, 951.958, 1189.9475, 1427.937, 1665.9265, 1903.916, + 2141.9055, 2379.895, 2617.8845, 2855.874, 3093.8635, 3331.853, 3569.8424999999997, + 3807.832, 4045.8215, 4283.811, 4521.8005, 4759.79 + ] + ] + }, + "label": { + "count": 7446, + "mean": 0.014907332796132152, + "std": 0.12119025003595912, + "min": 0, + "max": 1, + "hist": [ + [7335, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111], + [ + 0, 0.05, 0.1, 0.15000000000000002, 0.2, 0.25, 0.30000000000000004, + 0.35000000000000003, 0.4, 0.45, 0.5, 0.55, 0.6000000000000001, 0.65, + 0.7000000000000001, 0.75, 0.8, 0.8500000000000001, 0.9, 0.9500000000000001, 1 + ] + ] + } + }, + "monitoring_feature_set_uri": "store://feature-sets/default/test-m2:latest" + }, + "status": { + "state": null, + "monitoring_mode": "enabled", + "current_stats": { + "amount_avg_2h": { + "count": 11, + "mean": 28.0887273020327, + "std": 11.304901433309531, + "min": 12.19, + "max": 38.615200064471935, + "hist": [ + [1, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5], + [ + 12.19, 13.511260003223596, 14.832520006447194, 16.15378000967079, + 17.475040012894386, 18.796300016117982, 20.117560019341582, 21.438820022565178, + 22.760080025788774, 24.08134002901237, 25.402600032235966, 26.723860035459566, + 28.04512003868316, 29.36638004190676, 30.687640045130358, 32.00890004835395, + 33.33016005157755, 34.65142005480114, 35.97268005802474, 37.29394006124834, + 38.615200064471935 + ] + ] + }, + "amount_count_2h": { + "count": 11, + "mean": 0.5454545454545454, + "std": 0.5222329678670935, + "min": 0, + "max": 1, + "hist": [ + [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6], + [ + 0, 0.05, 0.1, 0.15000000000000002, 0.2, 0.25, 0.30000000000000004, + 0.35000000000000003, 0.4, 0.45, 0.5, 0.55, 0.6000000000000001, 0.65, + 0.7000000000000001, 0.75, 0.8, 0.8500000000000001, 0.9, 0.9500000000000001, 1 + ] + ] + }, + "amount_max_12h": { + "count": 11, + "mean": 55.03636363636363, + "std": 57.971923596293976, + "min": 20.92, + "max": 224.11, + "hist": [ + [3, 4, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], + [ + 20.92, 31.079500000000003, 41.239000000000004, 51.3985, 61.558, 71.7175, 81.877, + 92.0365, 102.196, 112.35549999999999, 122.515, 132.6745, 142.834, + 152.99349999999998, 163.15300000000002, 173.3125, 183.47199999999998, + 193.63150000000002, 203.791, 213.95049999999998, 224.11 + ] + ] + }, + "amount_max_2h": { + "count": 11, + "mean": 29.96273243391514, + "std": 13.260285022445734, + "min": 12.19, + "max": 42.738011354613306, + "hist": [ + [1, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 5], + [ + 12.19, 13.717400567730666, 15.24480113546133, 16.772201703191996, + 18.299602270922662, 19.82700283865333, 21.354403406383994, 22.881803974114657, + 24.409204541845323, 25.93660510957599, 27.464005677306652, 28.991406245037318, + 30.518806812767984, 32.04620738049865, 33.573607948229316, 35.10100851595998, + 36.62840908369065, 38.155809651421315, 39.68321021915198, 41.21061078688264, + 42.738011354613306 + ] + ] + }, + "amount_sum_2h": { + "count": 11, + "mean": 10.536363636363637, + "std": 11.31334457419845, + "min": 0, + "max": 30.42, + "hist": [ + [5, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1], + [ + 0, 1.5210000000000001, 3.0420000000000003, 4.563000000000001, 6.0840000000000005, + 7.605, 9.126000000000001, 10.647, 12.168000000000001, 13.689000000000002, 15.21, + 16.731, 18.252000000000002, 19.773000000000003, 21.294, 22.815, 24.336000000000002, + 25.857000000000003, 27.378000000000004, 28.899, 30.42 + ] + ] + } + }, + "first_request": "2022-05-02 11:14:21.082452+00:00", + "last_request": "2022-05-19 09:43:49.502382+00:00", + "error_count": null, + "avg_latency": null, + "drift_status": "DRIFT_DETECTED", + "drift_measures": { + "amount_max_2h": { + "tvd": 0.9006299904768882, + "hellinger": 0.8026729143746129, + "kld": 8.03097275516625 + }, + "tvd_sum": 4.0574683173393895, + "tvd_mean": 0.8114936634678779, + "hellinger_sum": 3.7935228606235265, + "hellinger_mean": 0.7587045721247053, + "kld_sum": 40.22159405569385, + "kld_mean": 8.04431881113877, + "amount_count_2h": { + "tvd": 0.9990598979317755, + "hellinger": 0.9860541717475733, + "kld": 15.975132772583372 + }, + "amount_avg_2h": { + "tvd": 0.9019729934314947, + "hellinger": 0.8046642697553347, + "kld": 7.91538219147246 + }, + "amount_sum_2h": { + "tvd": 0.5447830439772423, + "hellinger": 0.5827239245591163, + "kld": 4.424521130663923 + }, + "amount_max_12h": { + "tvd": 0.7110223915219885, + "hellinger": 0.6174075801868897, + "kld": 3.8755852058078455 + } + }, + "sampling_percentage": null + } + }, + { + "kind": "model-endpoint", + "metadata": { + "name": "my-endpoint", + "project": "llmdeploy335", + "tag": null, + "labels": { + "example": "single", + "hebrew": "english" + }, + "updated": "2025-08-27T14:29:33.747000", + "created": "2025-08-12T09:05:30.007000", + "uid": "f7172d26e7f94233994e0998aa404efb", + "endpoint_type": 1, + "mode": 0 + }, + "spec": { + "model_class": "mlrun.serving.Model", + "function_name": "function-with-llm", + "function_tag": "latest", + "model_path": "store://llm-prompts/llmdeploy335/my_llm#0@5780e34d-c0ed-46ed-ab49-39addf35a7ec^5ddece12a48b7199688a122911344f3a217addd7", + "model_name": "my_llm", + "model_tags": [ + "latest", + "111" + ], + "feature_names": [], + "label_names": [], + "feature_stats": {}, + "function_uri": "llmdeploy335/function-with-llm@unversioned-latest", + "model_uri": "store://llm-prompts/llmdeploy335/my_llm#0@9dea0dcc-8251-4f4e-94a8-c76b9a64db45^dc193ddf0914485f8c49d734d4cf8e240dcae118", + "children": null, + "children_uids": null, + "monitoring_feature_set_uri": "" + }, + "status": { + "state": "ready", + "first_request": null, + "monitoring_mode": "disabled", + "sampling_percentage": 100.0, + "last_request": null, + "result_status": -1, + "avg_latency": null, + "error_count": 0, + "current_stats": {}, + "current_stats_timestamp": null, + "drift_measures": {}, + "drift_measures_timestamp": null + } + }, + { + "kind": "model-endpoint", + "metadata": { + "name": "my-endpoint", + "project": "llmdeploy332", + "tag": null, + "labels": { + "example": "single", + "hebrew": "english" + }, + "updated": "2025-08-11T11:56:13.020000", + "created": "2025-08-11T11:56:13.020000", + "uid": "b2a773fdd4a94719850102cfffb25601", + "endpoint_type": 1, + "mode": 0 + }, + "spec": { + "model_class": "mlrun.serving.Model", + "function_name": "function-with-llm", + "function_tag": "latest", + "model_path": "store://llm-prompts/llmdeploy332/my_llm#0@c00325f6-c2cb-4c62-ad93-8d5de6d0d10d^1d459c52a1102adcbbe242e6bb36e99129f2a8b9", + "model_name": "my_llm", + "model_tags": [ + "latest" + ], + "feature_names": [], + "label_names": [], + "feature_stats": {}, + "function_uri": "llmdeploy332/function-with-llm@unversioned-latest", + "model_uri": "store://llm-prompts/llmdeploy332/my_llm#0@c00325f6-c2cb-4c62-ad93-8d5de6d0d10d^1d459c52a1102adcbbe242e6bb36e99129f2a8b9", + "children": null, + "children_uids": null, + "monitoring_feature_set_uri": "" + }, + "status": { + "state": "ready", + "first_request": null, + "monitoring_mode": "disabled", + "sampling_percentage": 100.0, + "last_request": null, + "result_status": -1, + "avg_latency": null, + "error_count": 0, + "current_stats": {}, + "current_stats_timestamp": null, + "drift_measures": {}, + "drift_measures_timestamp": null } } ] diff --git a/tests/mockServer/data/monitoringApplications.json b/tests/mockServer/data/monitoringApplications.json index 5a4c12422e..b4eb779df0 100644 --- a/tests/mockServer/data/monitoringApplications.json +++ b/tests/mockServer/data/monitoringApplications.json @@ -8,10 +8,14 @@ "base_period": 10, "nuclio_function_uri": "default/functions/default-modelMonitoringController/", "stats": { - "detections": 1245, - "potential_detections": 98, - "lag": 12, - "committed_offset": 398742 + "detected": 1245, + "potential_detection": 98, + "stream_stats": { + "0": { + "lag": 12, + "committed": 398742 + } + } }, "status": "ready" }, @@ -23,10 +27,14 @@ "base_period": 10, "nuclio_function_uri": "default/functions/default-modelMonitoringStream/", "stats": { - "detections": 567, - "potential_detections": 34, - "lag": 0, - "committed_offset": 10598 + "detected": 567, + "potential_detection": 34, + "stream_stats": { + "0": { + "lag": 12, + "committed": 39874222 + } + } }, "status": "ready" }, @@ -38,10 +46,14 @@ "base_period": 10, "nuclio_function_uri": "default/functions/default-modelMonitoringWriter/", "stats": { - "detections": 2567, - "potential_detections": 134, - "lag": 10, - "committed_offset": 110598 + "detected": 2567, + "potential_detection": 134, + "stream_stats": { + "0": { + "lag": 11, + "committed": 328742 + } + } }, "status": "ready" }, @@ -53,10 +65,14 @@ "base_period": 10, "nuclio_function_uri": "my-project/functions/my-project-monitorAppV1/", "stats": { - "detections": 1245, - "potential_detections": 98, - "lag": 2, - "committed_offset": 110, + "detected": 1245, + "potential_detection": 98, + "stream_stats": { + "0": { + "lag": 1222, + "committed": 22742 + } + }, "shards": { "1": { "committed": 50, @@ -72,7 +88,7 @@ { "type": "result", "time": "2025-05-07T09:07:14+00:00", - "name": "some_result", + "result_name": "some_result", "kind": "data-drift", "status": "Detection", "value": 0.95 @@ -80,7 +96,7 @@ { "type": "metric", "time": "2025-05-07T09:07:14+00:00", - "name": "some_metric", + "metric_name": "some_metric", "value": 0.4 } ] @@ -95,10 +111,14 @@ "base_period": 10, "nuclio_function_uri": "default/functions/default-monitorAppV2/", "stats": { - "detections": 567, - "potential_detections": 34, - "lag": 0, - "committed_offset": 10598, + "detected": 567, + "potential_detection": 34, + "stream_stats": { + "0": { + "lag": 2, + "committed": 742 + } + }, "shards": { "1": { "committed": 50, @@ -114,7 +134,7 @@ { "type": "result", "time": "2025-05-07T09:07:14+00:00", - "name": "some_result", + "result_name": "some_result", "kind": 0, "status": 2, "value": 0.95 @@ -122,7 +142,7 @@ { "type": "metric", "time": "2025-05-07T09:07:14+00:00", - "name": "some_metric", + "metric_name": "some_metric", "value": 0.4 } ] @@ -137,10 +157,14 @@ "base_period": 15, "nuclio_function_uri": "default/functions/default-monitorAppV3/", "stats": { - "detections": 850, - "potential_detections": 60, - "lag": 5, - "committed_offset": 203498, + "detected": 850, + "potential_detection": 60, + "stream_stats": { + "0": { + "lag": 5, + "committed": 42 + } + }, "shards": { "1": { "committed": 50, @@ -156,7 +180,7 @@ { "type": "result", "time": "2025-05-07T09:07:14+00:00", - "name": "some_result", + "result_name": "some_result", "kind": 0, "status": 2, "value": 0.95 @@ -164,12 +188,58 @@ { "type": "metric", "time": "2025-05-07T09:07:14+00:00", - "name": "some_metric", + "metric_name": "some_metric", "value": 0.4 } ] }, "status": "ready" + }, + { + "name": "monitorAppV4", + "application_class": "MyAppV4", + "started_at": "2025-05-02T09:00:00Z", + "updated_time": "2025-05-08T11:00:00Z", + "base_period": 15, + "nuclio_function_uri": "default/functions/default-monitorAppV4/", + "stats": { + "detected": 850, + "potential_detection": 60, + "stream_stats": { + "0": { + "lag": 5, + "committed": 42 + } + }, + "shards": { + "1": { + "committed": 50, + "lag": 2 + }, + "2": { + "committed": 60, + "lag": 0 + } + }, + "processed_model_endpoints": 8, + "metrics": [ + { + "type": "result", + "time": "2025-05-07T09:07:14+00:00", + "result_name": "some_result", + "kind": 0, + "status": 2, + "value": 0.95 + }, + { + "type": "metric", + "time": "2025-05-07T09:07:14+00:00", + "metric_name": "some_metric", + "value": 0.4 + } + ] + }, + "status": "error" } ] } diff --git a/tests/mockServer/data/nuclioFunctions.json b/tests/mockServer/data/nuclioFunctions.json index 353dbce763..25bb06f7ee 100644 --- a/tests/mockServer/data/nuclioFunctions.json +++ b/tests/mockServer/data/nuclioFunctions.json @@ -582,7 +582,8 @@ "namespace": "default-tenant", "labels": { "mlrun/class": "serving", - "nuclio.io/project-name": "default" + "nuclio.io/project-name": "default", + "mlrun__type": "mlrun__model-monitoring-application" }, "resourceVersion": "30099716" }, @@ -3950,7 +3951,8 @@ "name": "test", "namespace": "default-tenant", "labels": { - "nuclio.io/project-name": "cat-vs-dog-classification" + "nuclio.io/project-name": "cat-vs-dog-classification", + "mlrun__type": "mlrun__model-monitoring-infra" }, "resourceVersion": "37855264" }, @@ -4009,7 +4011,8 @@ "name": "test1", "namespace": "default-tenant", "labels": { - "nuclio.io/project-name": "default" + "nuclio.io/project-name": "default", + "mlrun__type": "mlrun__model-monitoring-infra" }, "resourceVersion": "28276699" }, @@ -4070,7 +4073,8 @@ "name": "test2", "namespace": "default-tenant", "labels": { - "nuclio.io/project-name": "default" + "nuclio.io/project-name": "default", + "mlrun__type": "mlrun__model-monitoring-infra" }, "resourceVersion": "37855235" }, diff --git a/tests/mockServer/data/pipelines.json b/tests/mockServer/data/pipelines.json index e2556b2aa9..d931d3e65b 100644 --- a/tests/mockServer/data/pipelines.json +++ b/tests/mockServer/data/pipelines.json @@ -204,7 +204,7 @@ "created_at": "2021-08-30 05:36:36+00:00", "scheduled_at": "1970-01-01 00:00:00+00:00", "finished_at": "2021-08-30 05:38:29+00:00", - "status": "Error", + "status": "Running", "error": "None", "project": "stocks-admin" } diff --git a/tests/mockServer/data/piplineIDs.json b/tests/mockServer/data/piplineIDs.json index d3f0ac3aca..22a3b7fb2d 100644 --- a/tests/mockServer/data/piplineIDs.json +++ b/tests/mockServer/data/piplineIDs.json @@ -1558,7 +1558,7 @@ "created_at": "2021-08-30 05:36:36+00:00", "scheduled_at": "1970-01-01 00:00:00+00:00", "finished_at": "2021-08-30 05:38:29+00:00", - "status": "Error", + "status": "Running", "error": "None", "project": "stocks-admin", "message": "" diff --git a/tests/mockServer/data/projects.json b/tests/mockServer/data/projects.json index 4d1941f5a2..7b57c9f5fb 100644 --- a/tests/mockServer/data/projects.json +++ b/tests/mockServer/data/projects.json @@ -12,7 +12,7 @@ }, "spec": { "description": "auto generated data for different purposes", - "owner": null, + "owner": "admin", "goals": "test goals", "params": {}, "functions": null, @@ -40,7 +40,7 @@ }, "spec": { "description": "123", - "owner": null, + "owner": "igz_nobody", "goals": "321", "params": { "se": "fg" @@ -193,7 +193,7 @@ }, "spec": { "description": "", - "owner": null, + "owner": "igz_nobody", "goals": "bbbbb", "params": { "a": "a", @@ -360,7 +360,7 @@ }, "spec": { "description": "test summary", - "owner": null, + "owner": "igz_nobody", "goals": "test goals", "params": {}, "functions": null, @@ -388,7 +388,7 @@ }, "spec": { "description": null, - "owner": null, + "owner": "igz_nobody", "goals": null, "params": null, "functions": [], @@ -419,7 +419,7 @@ }, "spec": { "description": "", - "owner": null, + "owner": "igz_nobody", "goals": "", "params": {}, "functions": null, @@ -446,7 +446,7 @@ }, "spec": { "description": null, - "owner": null, + "owner": "igz_nobody", "goals": null, "params": null, "functions": [ @@ -500,7 +500,7 @@ }, "spec": { "description": null, - "owner": null, + "owner": "admin", "goals": null, "params": null, "functions": null, @@ -527,7 +527,7 @@ }, "spec": { "description": null, - "owner": null, + "owner": "igz_nobody", "goals": null, "params": null, "functions": [], @@ -555,7 +555,7 @@ }, "spec": { "description": null, - "owner": null, + "owner": "admin", "goals": null, "params": null, "functions": [ @@ -1272,7 +1272,7 @@ }, "spec": { "description": "test", - "owner": null, + "owner": "admin", "goals": null, "params": null, "functions": null, @@ -1303,7 +1303,7 @@ }, "spec": { "description": null, - "owner": null, + "owner": "admin", "goals": null, "params": null, "functions": null, @@ -1330,7 +1330,7 @@ }, "spec": { "description": null, - "owner": null, + "owner": "admin", "goals": null, "params": null, "functions": [ @@ -1425,7 +1425,7 @@ }, "spec": { "description": null, - "owner": null, + "owner": "admin", "goals": null, "params": null, "functions": [ @@ -1533,7 +1533,7 @@ }, "spec": { "description": null, - "owner": null, + "owner": "admin", "goals": null, "params": null, "functions": [], @@ -1561,7 +1561,7 @@ }, "spec": { "description": null, - "owner": null, + "owner": "admin", "goals": null, "params": { "PROJECT_NAME": "stocks-admin" @@ -1625,7 +1625,7 @@ }, "spec": { "description": "", - "owner": null, + "owner": "admin", "goals": null, "params": null, "functions": null, @@ -1641,6 +1641,68 @@ "status": { "state": "online" } + }, + { + "kind": "project", + "metadata": { + "name": "llmdeploy335", + "created": "2025-08-11T12:32:38.084000", + "labels": {}, + "annotations": {} + }, + "spec": { + "description": null, + "owner": "normal-user", + "goals": null, + "params": {}, + "functions": null, + "workflows": null, + "artifacts": null, + "artifact_path": null, + "conda": "", + "source": "", + "subpath": null, + "origin_url": null, + "desired_state": "online", + "custom_packagers": null, + "default_image": null, + "build": null, + "default_function_node_selector": {} + }, + "status": { + "state": "online" + } + }, + { + "kind": "project", + "metadata": { + "name": "llmdeploy332", + "created": "2025-08-11T11:54:20.014000", + "labels": {}, + "annotations": {} + }, + "spec": { + "description": null, + "owner": "normal-user", + "goals": null, + "params": {}, + "functions": null, + "workflows": null, + "artifacts": null, + "artifact_path": null, + "conda": "", + "source": "", + "subpath": null, + "origin_url": null, + "desired_state": "online", + "custom_packagers": null, + "default_image": null, + "build": null, + "default_function_node_selector": {} + }, + "status": { + "state": "online" + } } ] } diff --git a/tests/mockServer/data/run.json b/tests/mockServer/data/run.json index ae1f6903d6..c20282b9e3 100644 --- a/tests/mockServer/data/run.json +++ b/tests/mockServer/data/run.json @@ -24,7 +24,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -32,7 +38,8 @@ "start_time": "2021-11-08T16:24:30.312181+00:00", "last_update": "2021-11-08T16:24:30.472758+00:00", "artifacts": [], - "error": "handler dg not found in main.py" + "error": "handler dg not found in main.py", + "retry_count": 2 } }, { @@ -59,7 +66,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -67,7 +80,8 @@ "start_time": "2021-11-08T16:24:30.310633+00:00", "last_update": "2021-11-08T16:24:30.473678+00:00", "artifacts": [], - "error": "handler seg not found in main.py" + "error": "handler seg not found in main.py", + "retry_count": 2 } }, { @@ -94,14 +108,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-11-08T16:22:18.425595+00:00", "last_update": "2021-11-08T16:23:45.047882+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -127,7 +148,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -135,7 +162,8 @@ "start_time": "2021-10-26T10:23:46.201308+00:00", "last_update": "2021-10-26T10:23:46.326428+00:00", "artifacts": [], - "error": "handler seg not found in main.py" + "error": "handler seg not found in main.py", + "retry_count": 1 } }, { @@ -161,14 +189,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "aborted", "results": {}, "start_time": "2021-10-12T08:24:05.965500+00:00", "last_update": "2021-10-12T08:24:10.599070+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -194,14 +229,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "aborted", "results": {}, "start_time": "2021-09-14T09:30:33.692216+00:00", "last_update": "2021-09-14T09:30:45.398626+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -230,14 +272,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { - "state": "pending", + "state": "pendingRetry", "results": {}, "start_time": "2021-09-13T12:37:39.890790+00:00", "last_update": "2021-09-13T12:37:47.341825+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -263,7 +312,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -271,7 +326,8 @@ "start_time": "2021-09-10T11:49:26.170358+00:00", "last_update": "2021-09-10T11:49:26.249424+00:00", "artifacts": [], - "error": "(422)\nReason: Unprocessable Entity\nHTTP response headers: HTTPHeaderDict({'Cache-Control': 'no-cache, private', 'Content-Type': 'application/json', 'Date': 'Fri, 10 Sep 2021 11:49:26 GMT', 'Content-Length': '974'})\nHTTP response body: {\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"Pod \\\"test-i-sz7vd\\\" is invalid: [spec.volumes[0].name: Invalid value: \\\"NAME\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?'), spec.containers[0].volumeMounts[0].name: Not found: \\\"NAME\\\"]\",\"reason\":\"Invalid\",\"details\":{\"name\":\"test-i-sz7vd\",\"kind\":\"Pod\",\"causes\":[{\"reason\":\"FieldValueInvalid\",\"message\":\"Invalid value: \\\"NAME\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')\",\"field\":\"spec.volumes[0].name\"},{\"reason\":\"FieldValueNotFound\",\"message\":\"Not found: \\\"NAME\\\"\",\"field\":\"spec.containers[0].volumeMounts[0].name\"}]},\"code\":422}\n\n" + "error": "(422)\nReason: Unprocessable Entity\nHTTP response headers: HTTPHeaderDict({'Cache-Control': 'no-cache, private', 'Content-Type': 'application/json', 'Date': 'Fri, 10 Sep 2021 11:49:26 GMT', 'Content-Length': '974'})\nHTTP response body: {\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"Pod \\\"test-i-sz7vd\\\" is invalid: [spec.volumes[0].name: Invalid value: \\\"NAME\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?'), spec.containers[0].volumeMounts[0].name: Not found: \\\"NAME\\\"]\",\"reason\":\"Invalid\",\"details\":{\"name\":\"test-i-sz7vd\",\"kind\":\"Pod\",\"causes\":[{\"reason\":\"FieldValueInvalid\",\"message\":\"Invalid value: \\\"NAME\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')\",\"field\":\"spec.volumes[0].name\"},{\"reason\":\"FieldValueNotFound\",\"message\":\"Not found: \\\"NAME\\\"\",\"field\":\"spec.containers[0].volumeMounts[0].name\"}]},\"code\":422}\n\n", + "retry_count": 1 } }, { @@ -297,7 +353,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -305,7 +367,49 @@ "start_time": "2021-09-10T11:46:36.715480+00:00", "last_update": "2021-09-10T11:46:36.768280+00:00", "artifacts": [], - "error": "(422)\nReason: Unprocessable Entity\nHTTP response headers: HTTPHeaderDict({'Cache-Control': 'no-cache, private', 'Content-Type': 'application/json', 'Date': 'Fri, 10 Sep 2021 11:46:36 GMT', 'Content-Length': '970'})\nHTTP response body: {\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"Pod \\\"fesf-frtb9\\\" is invalid: [spec.volumes[0].name: Invalid value: \\\"NAME\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?'), spec.containers[0].volumeMounts[0].name: Not found: \\\"NAME\\\"]\",\"reason\":\"Invalid\",\"details\":{\"name\":\"fesf-frtb9\",\"kind\":\"Pod\",\"causes\":[{\"reason\":\"FieldValueInvalid\",\"message\":\"Invalid value: \\\"NAME\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')\",\"field\":\"spec.volumes[0].name\"},{\"reason\":\"FieldValueNotFound\",\"message\":\"Not found: \\\"NAME\\\"\",\"field\":\"spec.containers[0].volumeMounts[0].name\"}]},\"code\":422}\n\n" + "error": "(422)\nReason: Unprocessable Entity\nHTTP response headers: HTTPHeaderDict({'Cache-Control': 'no-cache, private', 'Content-Type': 'application/json', 'Date': 'Fri, 10 Sep 2021 11:46:36 GMT', 'Content-Length': '970'})\nHTTP response body: {\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"Pod \\\"fesf-frtb9\\\" is invalid: [spec.volumes[0].name: Invalid value: \\\"NAME\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?'), spec.containers[0].volumeMounts[0].name: Not found: \\\"NAME\\\"]\",\"reason\":\"Invalid\",\"details\":{\"name\":\"fesf-frtb9\",\"kind\":\"Pod\",\"causes\":[{\"reason\":\"FieldValueInvalid\",\"message\":\"Invalid value: \\\"NAME\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')\",\"field\":\"spec.volumes[0].name\"},{\"reason\":\"FieldValueNotFound\",\"message\":\"Not found: \\\"NAME\\\"\",\"field\":\"spec.containers[0].volumeMounts[0].name\"}]},\"code\":422}\n\n", + "retry_count": 0 + } + }, + { + "kind": "run", + "metadata": { + "name": "fesf", + "uid": "c1a32f275eb743f781fd13d7a316a657", + "iteration": 0, + "project": "fsdemo-admin", + "labels": { + "v3io_user": "admin", + "owner": "admin", + "kind": "job" + }, + "annotations": {} + }, + "spec": { + "function": "fsdemo-admin/fesf@cfa663e14f1c7b71c7072afbc91827a23a86e964", + "log_level": "info", + "parameters": {}, + "outputs": [], + "output_path": "v3io:///projects/fsdemo-admin/artifacts/c1a32f275eb743f781fd13d7a316a657", + "inputs": {}, + "hyperparams": {}, + "hyper_param_options": {}, + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } + }, + "status": { + "state": "error", + "results": {}, + "start_time": "2021-09-10T11:46:36.715480+00:00", + "last_update": "2021-09-10T11:46:36.768280+00:00", + "artifacts": [], + "error": "(422)\nReason: Unprocessable Entity\nHTTP response headers: HTTPHeaderDict({'Cache-Control': 'no-cache, private', 'Content-Type': 'application/json', 'Date': 'Fri, 10 Sep 2021 11:46:36 GMT', 'Content-Length': '970'})\nHTTP response body: {\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"Pod \\\"fesf-frtb9\\\" is invalid: [spec.volumes[0].name: Invalid value: \\\"NAME\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?'), spec.containers[0].volumeMounts[0].name: Not found: \\\"NAME\\\"]\",\"reason\":\"Invalid\",\"details\":{\"name\":\"fesf-frtb9\",\"kind\":\"Pod\",\"causes\":[{\"reason\":\"FieldValueInvalid\",\"message\":\"Invalid value: \\\"NAME\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')\",\"field\":\"spec.volumes[0].name\"},{\"reason\":\"FieldValueNotFound\",\"message\":\"Not found: \\\"NAME\\\"\",\"field\":\"spec.containers[0].volumeMounts[0].name\"}]},\"code\":422}\n\n", + "retry_count": 0 } }, { @@ -331,7 +435,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -339,7 +449,8 @@ "start_time": "2021-09-10T11:45:54.004341+00:00", "last_update": "2021-09-10T11:45:54.059573+00:00", "artifacts": [], - "error": "(422)\nReason: Unprocessable Entity\nHTTP response headers: HTTPHeaderDict({'Cache-Control': 'no-cache, private', 'Content-Type': 'application/json', 'Date': 'Fri, 10 Sep 2021 11:45:54 GMT', 'Content-Length': '970'})\nHTTP response body: {\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"Pod \\\"fesf-bk7xh\\\" is invalid: [spec.volumes[0].name: Invalid value: \\\"NAME\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?'), spec.containers[0].volumeMounts[0].name: Not found: \\\"NAME\\\"]\",\"reason\":\"Invalid\",\"details\":{\"name\":\"fesf-bk7xh\",\"kind\":\"Pod\",\"causes\":[{\"reason\":\"FieldValueInvalid\",\"message\":\"Invalid value: \\\"NAME\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')\",\"field\":\"spec.volumes[0].name\"},{\"reason\":\"FieldValueNotFound\",\"message\":\"Not found: \\\"NAME\\\"\",\"field\":\"spec.containers[0].volumeMounts[0].name\"}]},\"code\":422}\n\n" + "error": "(422)\nReason: Unprocessable Entity\nHTTP response headers: HTTPHeaderDict({'Cache-Control': 'no-cache, private', 'Content-Type': 'application/json', 'Date': 'Fri, 10 Sep 2021 11:45:54 GMT', 'Content-Length': '970'})\nHTTP response body: {\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"Pod \\\"fesf-bk7xh\\\" is invalid: [spec.volumes[0].name: Invalid value: \\\"NAME\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?'), spec.containers[0].volumeMounts[0].name: Not found: \\\"NAME\\\"]\",\"reason\":\"Invalid\",\"details\":{\"name\":\"fesf-bk7xh\",\"kind\":\"Pod\",\"causes\":[{\"reason\":\"FieldValueInvalid\",\"message\":\"Invalid value: \\\"NAME\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')\",\"field\":\"spec.volumes[0].name\"},{\"reason\":\"FieldValueNotFound\",\"message\":\"Not found: \\\"NAME\\\"\",\"field\":\"spec.containers[0].volumeMounts[0].name\"}]},\"code\":422}\n\n", + "retry_count": 0 } }, { @@ -365,7 +476,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -373,7 +490,8 @@ "start_time": "2021-09-10T11:45:44.673524+00:00", "last_update": "2021-09-10T11:45:44.804681+00:00", "artifacts": [], - "error": "handler sef not found in main.py" + "error": "handler sef not found in main.py", + "retry_count": 1 } }, { @@ -399,7 +517,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -407,7 +531,8 @@ "start_time": "2021-09-10T11:44:47.606870+00:00", "last_update": "2021-09-10T11:44:47.678370+00:00", "artifacts": [], - "error": "(422)\nReason: Unprocessable Entity\nHTTP response headers: HTTPHeaderDict({'Cache-Control': 'no-cache, private', 'Content-Type': 'application/json', 'Date': 'Fri, 10 Sep 2021 11:44:47 GMT', 'Content-Length': '970'})\nHTTP response body: {\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"Pod \\\"test-6wpgq\\\" is invalid: [spec.volumes[0].name: Invalid value: \\\"NAME\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?'), spec.containers[0].volumeMounts[0].name: Not found: \\\"NAME\\\"]\",\"reason\":\"Invalid\",\"details\":{\"name\":\"test-6wpgq\",\"kind\":\"Pod\",\"causes\":[{\"reason\":\"FieldValueInvalid\",\"message\":\"Invalid value: \\\"NAME\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')\",\"field\":\"spec.volumes[0].name\"},{\"reason\":\"FieldValueNotFound\",\"message\":\"Not found: \\\"NAME\\\"\",\"field\":\"spec.containers[0].volumeMounts[0].name\"}]},\"code\":422}\n\n" + "error": "(422)\nReason: Unprocessable Entity\nHTTP response headers: HTTPHeaderDict({'Cache-Control': 'no-cache, private', 'Content-Type': 'application/json', 'Date': 'Fri, 10 Sep 2021 11:44:47 GMT', 'Content-Length': '970'})\nHTTP response body: {\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"Pod \\\"test-6wpgq\\\" is invalid: [spec.volumes[0].name: Invalid value: \\\"NAME\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?'), spec.containers[0].volumeMounts[0].name: Not found: \\\"NAME\\\"]\",\"reason\":\"Invalid\",\"details\":{\"name\":\"test-6wpgq\",\"kind\":\"Pod\",\"causes\":[{\"reason\":\"FieldValueInvalid\",\"message\":\"Invalid value: \\\"NAME\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')\",\"field\":\"spec.volumes[0].name\"},{\"reason\":\"FieldValueNotFound\",\"message\":\"Not found: \\\"NAME\\\"\",\"field\":\"spec.containers[0].volumeMounts[0].name\"}]},\"code\":422}\n\n", + "retry_count": 1 } }, { @@ -434,14 +559,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "running", "results": {}, "start_time": "2021-09-03T13:58:12.581215+00:00", "last_update": "2021-09-03T13:58:12.581220+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -468,14 +600,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "running", "results": {}, "start_time": "2021-09-03T13:58:01.150086+00:00", "last_update": "2021-09-03T13:58:01.150091+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -502,14 +641,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "running", "results": {}, "start_time": "2021-09-03T13:57:20.120500+00:00", "last_update": "2021-09-03T13:57:20.120505+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -536,14 +682,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "running", "results": {}, "start_time": "2021-09-03T13:51:21.205831+00:00", "last_update": "2021-09-03T13:51:21.205834+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -571,14 +724,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "running", "results": {}, "start_time": "2021-09-03T13:51:05.027342+00:00", "last_update": "2021-09-03T13:51:05.027349+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -612,7 +772,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -620,7 +786,8 @@ "start_time": "2021-09-03T13:50:59.748610+00:00", "last_update": "2021-09-03T13:50:59.909427+00:00", "error": "[Errno 2] No such file or directory: ''", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -648,14 +815,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "running", "results": {}, "start_time": "2021-09-03T13:50:01.211460+00:00", "last_update": "2021-09-03T13:50:01.211465+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -702,7 +876,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -710,7 +890,8 @@ "start_time": "2021-08-29T20:01:45.738537+00:00", "last_update": "2021-08-29T20:02:01.827946+00:00", "artifacts": [], - "error": "2021-08-29 20:01:36.582972: W tensorflow/stream_executor/platform/default/dso_loader.cc:60] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /usr/local/lib:/usr/local/lib:\n2021-08-29 20:01:36.583019: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.\n2021-08-29 20:01:46.470042: I tensorflow/compiler/jit/xla_cpu_device.cc:41] Not creating XLA devices, tf_xla_enable_xla_devices not set\n2021-08-29 20:01:46.470263: W tensorflow/stream_executor/platform/default/dso_loader.cc:60] Could not load dynamic library 'libcuda.so.1'; dlerror: libcuda.so.1: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /usr/local/lib:/usr/local/lib:\n2021-08-29 20:01:46.470283: W tensorflow/stream_executor/cuda/cuda_driver.cc:326] failed call to cuInit: UNKNOWN ERROR (303)\n2021-08-29 20:01:46.470306: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:156] kernel driver does not appear to be running on this host (train-1193bacd-worker-0): /proc/driver/nvidia/version does not exist\n2021-08-29 20:01:46.518782: I tensorflow/core/platform/cpu_feature_guard.cc:142] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX2 FMA\nTo enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.\n2021-08-29 20:01:46.518927: I tensorflow/compiler/jit/xla_gpu_device.cc:99] Not creating XLA devices, tf_xla_enable_xla_devices not set\nSome callbacks may not have access to the averaged metrics, see https://github.com/horovod/horovod/issues/2440\nTraceback (most recent call last):\n File \"/User/demos/image-classification-with-distributed-training/src-tfv2/horovod-training.py\", line 116, in \n hvd.callbacks.LearningRateWarmupCallback(warmup_epochs=5, verbose=1),\nTypeError: __init__() missing 1 required positional argument: 'initial_lr'\n" + "error": "2021-08-29 20:01:36.582972: W tensorflow/stream_executor/platform/default/dso_loader.cc:60] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /usr/local/lib:/usr/local/lib:\n2021-08-29 20:01:36.583019: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.\n2021-08-29 20:01:46.470042: I tensorflow/compiler/jit/xla_cpu_device.cc:41] Not creating XLA devices, tf_xla_enable_xla_devices not set\n2021-08-29 20:01:46.470263: W tensorflow/stream_executor/platform/default/dso_loader.cc:60] Could not load dynamic library 'libcuda.so.1'; dlerror: libcuda.so.1: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /usr/local/lib:/usr/local/lib:\n2021-08-29 20:01:46.470283: W tensorflow/stream_executor/cuda/cuda_driver.cc:326] failed call to cuInit: UNKNOWN ERROR (303)\n2021-08-29 20:01:46.470306: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:156] kernel driver does not appear to be running on this host (train-1193bacd-worker-0): /proc/driver/nvidia/version does not exist\n2021-08-29 20:01:46.518782: I tensorflow/core/platform/cpu_feature_guard.cc:142] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX2 FMA\nTo enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.\n2021-08-29 20:01:46.518927: I tensorflow/compiler/jit/xla_gpu_device.cc:99] Not creating XLA devices, tf_xla_enable_xla_devices not set\nSome callbacks may not have access to the averaged metrics, see https://github.com/horovod/horovod/issues/2440\nTraceback (most recent call last):\n File \"/User/demos/image-classification-with-distributed-training/src-tfv2/horovod-training.py\", line 116, in \n hvd.callbacks.LearningRateWarmupCallback(warmup_epochs=5, verbose=1),\nTypeError: __init__() missing 1 required positional argument: 'initial_lr'\n", + "retry_count": 2 } }, { @@ -746,7 +927,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -764,7 +951,8 @@ "uid": "20-0", "tag": "latest" } - ] + ], + "retry_count": 1 } }, { @@ -795,7 +983,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -813,7 +1007,8 @@ "uid": "21-0", "tag": "latest" } - ] + ], + "retry_count": 0 } }, { @@ -865,7 +1060,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -1380,7 +1581,8 @@ "uid": "22-0", "tag": "latest" } - ] + ], + "retry_count": 1 } }, { @@ -1416,7 +1618,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -1424,7 +1632,8 @@ "start_time": "2021-11-09T15:39:58.595075+00:00", "last_update": "2021-11-09T15:39:58.910192+00:00", "error": "[Errno 2] No such file or directory: '/User/demos/customer-churn-prediction/data/pipeline/eaae138e-439a-47fa-93c6-ba0fe1dc3b79/tenured-test-set.csv'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -1452,14 +1661,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-11-09T15:39:25.398562+00:00", "last_update": "2021-11-09T15:39:25.473487+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -1495,7 +1711,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -1503,7 +1725,8 @@ "start_time": "2021-11-08T16:26:06.311262+00:00", "last_update": "2021-11-08T16:26:06.600147+00:00", "error": "[Errno 2] No such file or directory: '/User/demos/customer-churn-prediction/data/pipeline/eaae138e-439a-47fa-93c6-ba0fe1dc3b79/tenured-test-set.csv'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -1531,14 +1754,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-11-08T16:25:34.779339+00:00", "last_update": "2021-11-08T16:25:34.842229+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -1585,7 +1815,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -1593,7 +1829,8 @@ "start_time": "2021-11-08T16:25:23.418269+00:00", "last_update": "2021-11-08T16:25:23.647817+00:00", "error": "file type unhandled dataset", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -1641,7 +1878,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -1649,7 +1892,8 @@ "start_time": "2021-11-08T16:25:23.359533+00:00", "last_update": "2021-11-08T16:25:23.583287+00:00", "error": "'str' object has no attribute 'as_df'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -1687,7 +1931,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -1695,7 +1945,8 @@ "start_time": "2021-11-08T16:25:23.359185+00:00", "last_update": "2021-11-08T16:25:23.809551+00:00", "error": "file type unhandled test_set", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -1733,7 +1984,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -1741,7 +1998,8 @@ "start_time": "2021-11-08T16:25:23.359144+00:00", "last_update": "2021-11-08T16:25:23.584861+00:00", "error": "file type unhandled test_set", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -1779,7 +2037,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -1787,7 +2051,8 @@ "start_time": "2021-11-08T16:25:22.232499+00:00", "last_update": "2021-11-08T16:25:22.405691+00:00", "error": "file type unhandled src", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -1825,7 +2090,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -1833,7 +2104,8 @@ "start_time": "2021-11-08T16:25:20.324321+00:00", "last_update": "2021-11-08T16:25:20.517116+00:00", "error": "file type unhandled table", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -1861,14 +2133,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-11-08T16:25:16.966884+00:00", "last_update": "2021-11-08T16:25:17.038745+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -1897,7 +2176,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -1905,7 +2190,8 @@ "start_time": "2021-11-08T16:23:11.710713+00:00", "last_update": "2021-11-08T16:23:12.129908+00:00", "artifacts": [], - "error": ".run() can only be execute on \"mlrun\" kind, recreate with function kind \"mlrun\"" + "error": ".run() can only be execute on \"mlrun\" kind, recreate with function kind \"mlrun\"", + "retry_count": 2 } }, { @@ -1940,7 +2226,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -1948,7 +2240,8 @@ "start_time": "2021-09-16T08:00:05.727520+00:00", "last_update": "2021-09-16T08:00:06.112908+00:00", "error": "[Errno 2] No such file or directory: '/User/demos/customer-churn-prediction/data/pipeline/eaae138e-439a-47fa-93c6-ba0fe1dc3b79/test_set.csv'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -2005,7 +2298,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -2013,7 +2312,8 @@ "start_time": "2021-09-15T13:44:33.718770+00:00", "last_update": "2021-09-15T13:44:34.287133+00:00", "error": "file type unhandled v3io://test/test", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -2050,7 +2350,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -2058,7 +2364,8 @@ "start_time": "2021-09-03T14:02:21.992537+00:00", "last_update": "2021-09-03T14:02:22.143202+00:00", "error": "file type unhandled test_set", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -2095,7 +2402,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -2103,7 +2416,8 @@ "start_time": "2021-09-03T14:02:14.813451+00:00", "last_update": "2021-09-03T14:02:14.961434+00:00", "error": "file type unhandled test_set", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -2150,7 +2464,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -2158,7 +2478,8 @@ "start_time": "2021-09-03T14:02:06.911466+00:00", "last_update": "2021-09-03T14:02:07.047657+00:00", "error": "'str' object has no attribute 'as_df'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -2195,7 +2516,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -2203,7 +2530,8 @@ "start_time": "2021-09-03T14:01:57.400446+00:00", "last_update": "2021-09-03T14:01:57.593225+00:00", "error": "file type unhandled table", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -2249,7 +2577,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -2257,7 +2591,8 @@ "start_time": "2021-09-03T14:01:41.039404+00:00", "last_update": "2021-09-03T14:01:41.302859+00:00", "error": "file type unhandled dataset", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -2294,7 +2629,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -2302,7 +2643,8 @@ "start_time": "2021-09-03T14:01:25.207451+00:00", "last_update": "2021-09-03T14:01:25.372461+00:00", "error": "file type unhandled src", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -2349,7 +2691,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -2357,7 +2705,8 @@ "start_time": "2021-09-03T13:56:21.373049+00:00", "last_update": "2021-09-03T13:56:21.517709+00:00", "error": "'str' object has no attribute 'as_df'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -2394,7 +2743,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -2402,7 +2757,8 @@ "start_time": "2021-09-03T13:56:21.206337+00:00", "last_update": "2021-09-03T13:56:21.342459+00:00", "error": "file type unhandled test_set", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -2439,7 +2795,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -2447,7 +2809,8 @@ "start_time": "2021-09-03T13:56:19.700627+00:00", "last_update": "2021-09-03T13:56:19.856594+00:00", "error": "file type unhandled test_set", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -2493,7 +2856,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -2501,7 +2870,8 @@ "start_time": "2021-09-03T13:56:19.515710+00:00", "last_update": "2021-09-03T13:56:19.665883+00:00", "error": "file type unhandled dataset", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -2538,7 +2908,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -2546,7 +2922,8 @@ "start_time": "2021-09-03T13:56:16.478536+00:00", "last_update": "2021-09-03T13:56:16.600809+00:00", "error": "file type unhandled src", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -2583,7 +2960,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -2591,7 +2974,8 @@ "start_time": "2021-09-03T13:55:42.511622+00:00", "last_update": "2021-09-03T13:55:42.712944+00:00", "error": "file type unhandled table", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -2628,7 +3012,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -2719,7 +3109,8 @@ "uid": "49-4", "tag": "latest" } - ] + ], + "retry_count": 0 } }, { @@ -2756,7 +3147,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -3580,7 +3977,8 @@ "uid": "50-0", "tag": "latest" } - ] + ], + "retry_count": 1 } }, { @@ -3643,7 +4041,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -5812,7 +6216,8 @@ "uid": "51-6", "tag": "latest" } - ] + ], + "retry_count": 0 } }, { @@ -5847,7 +6252,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -5972,7 +6383,8 @@ "uid": "52-5", "tag": "latest" } - ] + ], + "retry_count": 0 } }, { @@ -6023,7 +6435,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -9552,7 +9970,8 @@ "uid": "53-5", "tag": "latest" } - ] + ], + "retry_count": 0 } }, { @@ -9590,7 +10009,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -12200,7 +12625,8 @@ "uid": "54-4", "tag": "latest" } - ] + ], + "retry_count": 1 } }, { @@ -12232,7 +12658,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -14842,7 +15274,8 @@ "uid": "55-4", "tag": "latest" } - ] + ], + "retry_count": 1 } }, { @@ -14887,7 +15320,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -14895,7 +15334,8 @@ "start_time": "2021-11-25T15:20:04.626994+00:00", "last_update": "2021-11-25T15:20:04.869705+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -14940,7 +15380,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -14948,7 +15394,8 @@ "start_time": "2021-11-25T15:10:04.547356+00:00", "last_update": "2021-11-25T15:10:04.740772+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -14993,7 +15440,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -15001,7 +15454,8 @@ "start_time": "2021-11-25T15:00:04.530198+00:00", "last_update": "2021-11-25T15:00:04.778945+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -15046,7 +15500,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -15054,7 +15514,8 @@ "start_time": "2021-11-25T14:50:04.689049+00:00", "last_update": "2021-11-25T14:50:04.876507+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -15099,7 +15560,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -15107,7 +15574,8 @@ "start_time": "2021-11-25T14:40:04.591290+00:00", "last_update": "2021-11-25T14:40:04.779383+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -15152,7 +15620,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -15160,7 +15634,8 @@ "start_time": "2021-11-25T14:30:04.478111+00:00", "last_update": "2021-11-25T14:30:04.671986+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -15205,7 +15680,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -15213,7 +15694,8 @@ "start_time": "2021-11-25T14:20:04.413115+00:00", "last_update": "2021-11-25T14:20:04.602205+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -15258,7 +15740,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -15266,7 +15754,8 @@ "start_time": "2021-11-25T14:10:04.748113+00:00", "last_update": "2021-11-25T14:10:04.936987+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -15311,7 +15800,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -15319,7 +15814,8 @@ "start_time": "2021-11-25T14:00:04.499287+00:00", "last_update": "2021-11-25T14:00:04.748608+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -15364,7 +15860,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -15372,7 +15874,8 @@ "start_time": "2021-11-25T13:50:04.460226+00:00", "last_update": "2021-11-25T13:50:04.663531+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -15417,7 +15920,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -15425,7 +15934,8 @@ "start_time": "2021-11-25T13:40:04.616903+00:00", "last_update": "2021-11-25T13:40:05.070431+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -15470,7 +15980,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -15478,7 +15994,8 @@ "start_time": "2021-11-25T13:30:04.482084+00:00", "last_update": "2021-11-25T13:30:04.682436+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -15523,7 +16040,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -15531,7 +16054,8 @@ "start_time": "2021-11-25T13:20:04.619182+00:00", "last_update": "2021-11-25T13:20:04.821367+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -15576,7 +16100,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -15584,7 +16114,8 @@ "start_time": "2021-11-25T13:10:04.530025+00:00", "last_update": "2021-11-25T13:10:04.725068+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -15629,7 +16160,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -15637,7 +16174,8 @@ "start_time": "2021-11-25T13:00:04.554031+00:00", "last_update": "2021-11-25T13:00:04.800899+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -15682,7 +16220,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -15690,7 +16234,8 @@ "start_time": "2021-11-25T12:50:04.498226+00:00", "last_update": "2021-11-25T12:50:04.692993+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -15735,7 +16280,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -15743,7 +16294,8 @@ "start_time": "2021-11-25T12:40:04.664771+00:00", "last_update": "2021-11-25T12:40:04.859887+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -15788,7 +16340,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -15796,7 +16354,8 @@ "start_time": "2021-11-25T12:30:04.506004+00:00", "last_update": "2021-11-25T12:30:04.697277+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -15841,7 +16400,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -15849,7 +16414,8 @@ "start_time": "2021-11-25T12:20:04.678686+00:00", "last_update": "2021-11-25T12:20:04.872209+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -15894,7 +16460,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -15902,7 +16474,8 @@ "start_time": "2021-11-25T12:10:04.672087+00:00", "last_update": "2021-11-25T12:10:04.889989+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -15947,7 +16520,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -15955,7 +16534,8 @@ "start_time": "2021-11-25T12:00:04.755738+00:00", "last_update": "2021-11-25T12:00:05.093911+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -16000,7 +16580,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -16008,7 +16594,8 @@ "start_time": "2021-11-25T11:50:04.480850+00:00", "last_update": "2021-11-25T11:50:04.677429+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -16053,7 +16640,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -16061,7 +16654,8 @@ "start_time": "2021-11-25T11:40:04.602256+00:00", "last_update": "2021-11-25T11:40:04.850283+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -16106,7 +16700,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -16114,7 +16714,8 @@ "start_time": "2021-11-25T11:30:04.426377+00:00", "last_update": "2021-11-25T11:30:04.636503+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -16159,7 +16760,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -16167,7 +16774,8 @@ "start_time": "2021-11-25T11:20:04.516140+00:00", "last_update": "2021-11-25T11:20:04.735509+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -16212,7 +16820,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -16220,7 +16834,8 @@ "start_time": "2021-11-25T11:10:04.472037+00:00", "last_update": "2021-11-25T11:10:04.664942+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -16265,7 +16880,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -16273,7 +16894,8 @@ "start_time": "2021-11-25T11:00:04.657896+00:00", "last_update": "2021-11-25T11:00:04.883672+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -16318,7 +16940,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -16326,7 +16954,8 @@ "start_time": "2021-11-25T10:50:04.647522+00:00", "last_update": "2021-11-25T10:50:04.836197+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -16371,7 +17000,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -16379,7 +17014,8 @@ "start_time": "2021-11-25T10:40:04.569781+00:00", "last_update": "2021-11-25T10:40:04.770749+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -16424,7 +17060,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -16432,7 +17074,8 @@ "start_time": "2021-11-25T10:30:04.676500+00:00", "last_update": "2021-11-25T10:30:04.860678+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -16477,7 +17120,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -16485,7 +17134,8 @@ "start_time": "2021-11-25T10:20:04.709992+00:00", "last_update": "2021-11-25T10:20:04.906660+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -16530,7 +17180,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -16538,7 +17194,8 @@ "start_time": "2021-11-25T10:10:04.654881+00:00", "last_update": "2021-11-25T10:10:04.877279+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -16583,7 +17240,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -16591,7 +17254,8 @@ "start_time": "2021-11-25T10:00:04.655647+00:00", "last_update": "2021-11-25T10:00:04.922516+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -16636,7 +17300,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -16644,7 +17314,8 @@ "start_time": "2021-11-25T09:50:05.301473+00:00", "last_update": "2021-11-25T09:50:05.506318+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -16689,7 +17360,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -16697,7 +17374,8 @@ "start_time": "2021-11-25T09:40:04.688485+00:00", "last_update": "2021-11-25T09:40:04.885575+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -16742,7 +17420,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -16750,7 +17434,8 @@ "start_time": "2021-11-25T09:30:04.526432+00:00", "last_update": "2021-11-25T09:30:04.714181+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -16795,7 +17480,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -16803,7 +17494,8 @@ "start_time": "2021-11-25T09:20:04.628475+00:00", "last_update": "2021-11-25T09:20:04.872881+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -16848,7 +17540,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -16856,7 +17554,8 @@ "start_time": "2021-11-25T09:10:04.450469+00:00", "last_update": "2021-11-25T09:10:04.777839+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -16901,7 +17600,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -16909,7 +17614,8 @@ "start_time": "2021-11-25T09:00:04.766381+00:00", "last_update": "2021-11-25T09:00:05.025565+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -16954,7 +17660,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -16962,7 +17674,8 @@ "start_time": "2021-11-25T08:50:04.418181+00:00", "last_update": "2021-11-25T08:50:04.595812+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -17007,7 +17720,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -17015,7 +17734,8 @@ "start_time": "2021-11-25T08:40:04.569381+00:00", "last_update": "2021-11-25T08:40:04.759896+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -17060,7 +17780,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -17068,7 +17794,8 @@ "start_time": "2021-11-25T08:30:04.600599+00:00", "last_update": "2021-11-25T08:30:04.848873+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -17113,7 +17840,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -17121,7 +17854,8 @@ "start_time": "2021-11-25T08:20:04.519720+00:00", "last_update": "2021-11-25T08:20:04.819565+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -17166,7 +17900,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -17174,7 +17914,8 @@ "start_time": "2021-11-25T08:10:04.578285+00:00", "last_update": "2021-11-25T08:10:04.758011+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -17219,7 +17960,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -17227,7 +17974,8 @@ "start_time": "2021-11-25T08:00:04.433436+00:00", "last_update": "2021-11-25T08:00:04.694042+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -17272,7 +18020,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -17280,7 +18034,8 @@ "start_time": "2021-11-25T07:50:04.643860+00:00", "last_update": "2021-11-25T07:50:04.894175+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -17325,7 +18080,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -17333,7 +18094,8 @@ "start_time": "2021-11-25T07:40:04.621111+00:00", "last_update": "2021-11-25T07:40:04.847086+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -17378,7 +18140,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -17386,7 +18154,8 @@ "start_time": "2021-11-25T07:30:04.433519+00:00", "last_update": "2021-11-25T07:30:04.623295+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -17431,7 +18200,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -17439,7 +18214,8 @@ "start_time": "2021-11-25T07:20:04.851092+00:00", "last_update": "2021-11-25T07:20:05.072058+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -17484,7 +18260,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -17492,7 +18274,8 @@ "start_time": "2021-11-25T07:10:04.701725+00:00", "last_update": "2021-11-25T07:10:04.891876+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -17537,7 +18320,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -17545,7 +18334,8 @@ "start_time": "2021-11-25T07:00:04.730707+00:00", "last_update": "2021-11-25T07:00:04.959567+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -17590,7 +18380,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -17598,7 +18394,8 @@ "start_time": "2021-11-25T06:50:04.389233+00:00", "last_update": "2021-11-25T06:50:04.570853+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -17643,7 +18440,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -17651,7 +18454,8 @@ "start_time": "2021-11-25T06:40:04.779848+00:00", "last_update": "2021-11-25T06:40:04.993553+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -17696,7 +18500,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -17704,7 +18514,8 @@ "start_time": "2021-11-25T06:30:04.427263+00:00", "last_update": "2021-11-25T06:30:04.614687+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -17749,7 +18560,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -17757,7 +18574,8 @@ "start_time": "2021-11-25T06:20:04.434939+00:00", "last_update": "2021-11-25T06:20:04.618174+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -17802,7 +18620,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -17810,7 +18634,8 @@ "start_time": "2021-11-25T06:10:04.633692+00:00", "last_update": "2021-11-25T06:10:04.845108+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -17855,7 +18680,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -17863,7 +18694,8 @@ "start_time": "2021-11-25T06:00:04.609640+00:00", "last_update": "2021-11-25T06:00:04.912946+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -17908,7 +18740,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -17916,7 +18754,8 @@ "start_time": "2021-11-25T05:50:04.449949+00:00", "last_update": "2021-11-25T05:50:04.635722+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -17961,7 +18800,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -17969,7 +18814,8 @@ "start_time": "2021-11-25T05:40:04.515533+00:00", "last_update": "2021-11-25T05:40:04.736425+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -18014,7 +18860,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -18022,7 +18874,8 @@ "start_time": "2021-11-25T05:30:04.577631+00:00", "last_update": "2021-11-25T05:30:04.863501+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -18067,7 +18920,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -18075,7 +18934,8 @@ "start_time": "2021-11-25T05:20:04.455804+00:00", "last_update": "2021-11-25T05:20:04.634993+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -18120,7 +18980,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -18128,7 +18994,8 @@ "start_time": "2021-11-25T05:10:04.414843+00:00", "last_update": "2021-11-25T05:10:04.629374+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -18173,7 +19040,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -18181,7 +19054,8 @@ "start_time": "2021-11-25T05:00:04.813068+00:00", "last_update": "2021-11-25T05:00:05.113562+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -18226,7 +19100,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -18234,7 +19114,8 @@ "start_time": "2021-11-25T04:50:04.587135+00:00", "last_update": "2021-11-25T04:50:04.779001+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -18279,7 +19160,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -18287,7 +19174,8 @@ "start_time": "2021-11-25T04:40:04.432340+00:00", "last_update": "2021-11-25T04:40:04.693033+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -18332,7 +19220,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -18340,7 +19234,8 @@ "start_time": "2021-11-25T04:30:04.785460+00:00", "last_update": "2021-11-25T04:30:04.974252+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -18385,7 +19280,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -18393,7 +19294,8 @@ "start_time": "2021-11-25T04:20:04.487176+00:00", "last_update": "2021-11-25T04:20:04.689088+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -18438,7 +19340,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -18446,7 +19354,8 @@ "start_time": "2021-11-25T04:10:04.525230+00:00", "last_update": "2021-11-25T04:10:04.804950+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -18491,7 +19400,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -18499,7 +19414,8 @@ "start_time": "2021-11-25T04:00:04.434934+00:00", "last_update": "2021-11-25T04:00:04.684001+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -18544,7 +19460,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -18552,7 +19474,8 @@ "start_time": "2021-11-25T03:50:04.404080+00:00", "last_update": "2021-11-25T03:50:04.721225+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -18597,7 +19520,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -18605,7 +19534,8 @@ "start_time": "2021-11-25T03:40:04.494475+00:00", "last_update": "2021-11-25T03:40:04.780123+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -18650,7 +19580,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -18658,7 +19594,8 @@ "start_time": "2021-11-25T03:30:04.696343+00:00", "last_update": "2021-11-25T03:30:04.898417+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -18703,7 +19640,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -18711,7 +19654,8 @@ "start_time": "2021-11-25T03:20:04.805759+00:00", "last_update": "2021-11-25T03:20:04.984463+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -18756,7 +19700,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -18764,7 +19714,8 @@ "start_time": "2021-11-25T03:10:04.538969+00:00", "last_update": "2021-11-25T03:10:04.807798+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -18809,7 +19760,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -18817,7 +19774,8 @@ "start_time": "2021-11-25T03:00:04.573902+00:00", "last_update": "2021-11-25T03:00:04.835497+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -18862,7 +19820,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -18870,7 +19834,8 @@ "start_time": "2021-11-25T02:50:04.776007+00:00", "last_update": "2021-11-25T02:50:04.956215+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -18915,7 +19880,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -18923,7 +19894,8 @@ "start_time": "2021-11-25T02:40:04.477586+00:00", "last_update": "2021-11-25T02:40:04.665052+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -18968,7 +19940,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -18976,7 +19954,8 @@ "start_time": "2021-11-25T02:30:04.474322+00:00", "last_update": "2021-11-25T02:30:04.663125+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -19021,7 +20000,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -19029,7 +20014,8 @@ "start_time": "2021-11-25T02:20:04.518030+00:00", "last_update": "2021-11-25T02:20:04.854487+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -19074,7 +20060,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -19082,7 +20074,8 @@ "start_time": "2021-11-25T02:10:04.644281+00:00", "last_update": "2021-11-25T02:10:04.827435+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -19127,7 +20120,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -19135,7 +20134,8 @@ "start_time": "2021-11-25T02:00:04.631916+00:00", "last_update": "2021-11-25T02:00:04.879130+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -19180,7 +20180,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -19188,7 +20194,8 @@ "start_time": "2021-11-25T01:50:04.616606+00:00", "last_update": "2021-11-25T01:50:04.799437+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -19233,7 +20240,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -19241,7 +20254,8 @@ "start_time": "2021-11-25T01:40:04.559437+00:00", "last_update": "2021-11-25T01:40:04.750553+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -19286,7 +20300,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -19294,7 +20314,8 @@ "start_time": "2021-11-25T01:30:04.941823+00:00", "last_update": "2021-11-25T01:30:05.134506+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -19339,7 +20360,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -19347,7 +20374,8 @@ "start_time": "2021-11-25T01:20:04.596188+00:00", "last_update": "2021-11-25T01:20:04.782960+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -19392,7 +20420,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -19400,7 +20434,8 @@ "start_time": "2021-11-25T01:10:04.491352+00:00", "last_update": "2021-11-25T01:10:04.667277+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -19445,7 +20480,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -19453,7 +20494,8 @@ "start_time": "2021-11-25T01:00:04.644596+00:00", "last_update": "2021-11-25T01:00:04.873300+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -19498,7 +20540,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -19506,7 +20554,8 @@ "start_time": "2021-11-25T00:50:04.982616+00:00", "last_update": "2021-11-25T00:50:05.168071+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -19551,7 +20600,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -19559,7 +20614,8 @@ "start_time": "2021-11-25T00:40:04.603050+00:00", "last_update": "2021-11-25T00:40:04.891375+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -19604,7 +20660,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -19612,7 +20674,8 @@ "start_time": "2021-11-25T00:30:04.551138+00:00", "last_update": "2021-11-25T00:30:04.740014+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -19657,7 +20720,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -19665,7 +20734,8 @@ "start_time": "2021-11-25T00:20:04.463810+00:00", "last_update": "2021-11-25T00:20:04.814736+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -19710,7 +20780,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -19718,7 +20794,8 @@ "start_time": "2021-11-25T00:10:04.738628+00:00", "last_update": "2021-11-25T00:10:05.017899+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -19763,7 +20840,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -19771,7 +20854,8 @@ "start_time": "2021-11-25T00:00:04.544586+00:00", "last_update": "2021-11-25T00:00:05.005375+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -19816,7 +20900,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -19824,7 +20914,8 @@ "start_time": "2021-11-24T23:50:04.516034+00:00", "last_update": "2021-11-24T23:50:04.708996+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -19869,7 +20960,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -19877,7 +20974,8 @@ "start_time": "2021-11-24T23:40:04.527184+00:00", "last_update": "2021-11-24T23:40:04.794158+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -19922,7 +21020,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -19930,7 +21034,8 @@ "start_time": "2021-11-24T23:30:04.532170+00:00", "last_update": "2021-11-24T23:30:04.726453+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -19975,7 +21080,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -19983,7 +21094,8 @@ "start_time": "2021-11-24T23:20:04.469606+00:00", "last_update": "2021-11-24T23:20:04.756696+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -20028,7 +21140,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -20036,7 +21154,8 @@ "start_time": "2021-11-24T23:10:04.438960+00:00", "last_update": "2021-11-24T23:10:04.654338+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -20081,7 +21200,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -20089,7 +21214,8 @@ "start_time": "2021-11-24T23:00:04.699017+00:00", "last_update": "2021-11-24T23:00:05.044694+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -20134,7 +21260,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -20142,7 +21274,8 @@ "start_time": "2021-11-24T22:50:04.479638+00:00", "last_update": "2021-11-24T22:50:04.668838+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -20187,7 +21320,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -20195,7 +21334,8 @@ "start_time": "2021-11-24T22:40:04.504226+00:00", "last_update": "2021-11-24T22:40:04.695845+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -20240,7 +21380,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -20248,7 +21394,8 @@ "start_time": "2021-11-24T22:30:04.458818+00:00", "last_update": "2021-11-24T22:30:04.711903+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -20293,7 +21440,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -20301,7 +21454,8 @@ "start_time": "2021-11-24T22:20:04.418897+00:00", "last_update": "2021-11-24T22:20:04.607711+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -20346,7 +21500,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -20354,7 +21514,8 @@ "start_time": "2021-11-24T22:10:04.538668+00:00", "last_update": "2021-11-24T22:10:04.734232+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -20399,7 +21560,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -20407,7 +21574,8 @@ "start_time": "2021-11-24T22:00:04.539921+00:00", "last_update": "2021-11-24T22:00:04.781730+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -20452,7 +21620,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -20460,7 +21634,8 @@ "start_time": "2021-11-24T21:50:04.510394+00:00", "last_update": "2021-11-24T21:50:04.691104+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -20505,7 +21680,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -20513,7 +21694,8 @@ "start_time": "2021-11-24T21:40:04.550718+00:00", "last_update": "2021-11-24T21:40:04.749227+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -20558,7 +21740,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -20566,7 +21754,8 @@ "start_time": "2021-11-24T21:30:04.409693+00:00", "last_update": "2021-11-24T21:30:04.598307+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -20611,7 +21800,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -20619,7 +21814,8 @@ "start_time": "2021-11-24T21:20:04.621030+00:00", "last_update": "2021-11-24T21:20:04.810078+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -20664,7 +21860,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -20672,7 +21874,8 @@ "start_time": "2021-11-24T21:10:04.375332+00:00", "last_update": "2021-11-24T21:10:04.626326+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -20717,7 +21920,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -20725,7 +21934,8 @@ "start_time": "2021-11-24T21:00:04.870989+00:00", "last_update": "2021-11-24T21:00:05.112089+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -20770,7 +21980,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -20778,7 +21994,8 @@ "start_time": "2021-11-24T20:50:04.507278+00:00", "last_update": "2021-11-24T20:50:04.686896+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -20823,7 +22040,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -20831,7 +22054,8 @@ "start_time": "2021-11-24T20:40:04.546515+00:00", "last_update": "2021-11-24T20:40:04.731933+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -20876,7 +22100,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -20884,7 +22114,8 @@ "start_time": "2021-11-24T20:30:04.298374+00:00", "last_update": "2021-11-24T20:30:04.511135+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -20929,7 +22160,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -20937,7 +22174,8 @@ "start_time": "2021-11-24T20:20:04.870619+00:00", "last_update": "2021-11-24T20:20:05.159143+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -20982,7 +22220,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -20990,7 +22234,8 @@ "start_time": "2021-11-24T20:10:04.611475+00:00", "last_update": "2021-11-24T20:10:04.839482+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -21035,7 +22280,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -21043,7 +22294,8 @@ "start_time": "2021-11-24T20:00:04.475649+00:00", "last_update": "2021-11-24T20:00:04.795051+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -21088,7 +22340,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -21096,7 +22354,8 @@ "start_time": "2021-11-24T19:50:04.568253+00:00", "last_update": "2021-11-24T19:50:04.759309+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -21141,7 +22400,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -21149,7 +22414,8 @@ "start_time": "2021-11-24T19:40:04.520061+00:00", "last_update": "2021-11-24T19:40:04.722499+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -21194,7 +22460,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -21202,7 +22474,8 @@ "start_time": "2021-11-24T19:30:04.429974+00:00", "last_update": "2021-11-24T19:30:04.643339+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -21247,7 +22520,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -21255,7 +22534,8 @@ "start_time": "2021-11-24T19:20:04.682369+00:00", "last_update": "2021-11-24T19:20:04.987412+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -21300,7 +22580,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -21308,7 +22594,8 @@ "start_time": "2021-11-24T19:10:04.798406+00:00", "last_update": "2021-11-24T19:10:04.987420+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -21353,7 +22640,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -21361,7 +22654,8 @@ "start_time": "2021-11-24T19:00:04.611443+00:00", "last_update": "2021-11-24T19:00:04.904232+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -21406,7 +22700,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -21414,7 +22714,8 @@ "start_time": "2021-11-24T18:50:04.615771+00:00", "last_update": "2021-11-24T18:50:04.798803+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -21459,7 +22760,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -21467,7 +22774,8 @@ "start_time": "2021-11-24T18:40:04.599586+00:00", "last_update": "2021-11-24T18:40:04.795373+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -21512,7 +22820,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -21520,7 +22834,8 @@ "start_time": "2021-11-24T18:30:04.433271+00:00", "last_update": "2021-11-24T18:30:04.641423+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -21565,7 +22880,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -21573,7 +22894,8 @@ "start_time": "2021-11-24T18:20:04.349454+00:00", "last_update": "2021-11-24T18:20:04.527202+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -21618,7 +22940,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -21626,7 +22954,8 @@ "start_time": "2021-11-24T18:10:04.801067+00:00", "last_update": "2021-11-24T18:10:05.109504+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -21671,7 +23000,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -21679,7 +23014,8 @@ "start_time": "2021-11-24T18:00:04.470012+00:00", "last_update": "2021-11-24T18:00:04.699333+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -21724,7 +23060,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -21732,7 +23074,8 @@ "start_time": "2021-11-24T17:50:04.767415+00:00", "last_update": "2021-11-24T17:50:04.958676+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -21777,7 +23120,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -21785,7 +23134,8 @@ "start_time": "2021-11-24T17:40:04.565225+00:00", "last_update": "2021-11-24T17:40:04.758722+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -21830,7 +23180,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -21838,7 +23194,8 @@ "start_time": "2021-11-24T17:30:04.542465+00:00", "last_update": "2021-11-24T17:30:04.726922+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -21883,7 +23240,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -21891,7 +23254,8 @@ "start_time": "2021-11-24T17:20:04.558157+00:00", "last_update": "2021-11-24T17:20:04.747969+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -21936,7 +23300,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -21944,7 +23314,8 @@ "start_time": "2021-11-24T17:10:04.510999+00:00", "last_update": "2021-11-24T17:10:04.741880+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -21989,7 +23360,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -21997,7 +23374,8 @@ "start_time": "2021-11-24T17:00:04.637790+00:00", "last_update": "2021-11-24T17:00:04.914986+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -22042,7 +23420,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -22050,7 +23434,8 @@ "start_time": "2021-11-24T16:50:04.532151+00:00", "last_update": "2021-11-24T16:50:04.707283+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -22095,7 +23480,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -22103,7 +23494,8 @@ "start_time": "2021-11-24T16:40:04.654448+00:00", "last_update": "2021-11-24T16:40:04.857622+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -22148,7 +23540,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -22156,7 +23554,8 @@ "start_time": "2021-11-24T16:30:04.726833+00:00", "last_update": "2021-11-24T16:30:04.915715+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -22201,7 +23600,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -22209,7 +23614,8 @@ "start_time": "2021-11-24T16:20:04.765431+00:00", "last_update": "2021-11-24T16:20:04.995627+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -22254,7 +23660,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -22262,7 +23674,8 @@ "start_time": "2021-11-24T16:10:04.475159+00:00", "last_update": "2021-11-24T16:10:04.707052+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -22307,7 +23720,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -22315,7 +23734,8 @@ "start_time": "2021-11-24T16:00:04.513842+00:00", "last_update": "2021-11-24T16:00:04.798010+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -22360,7 +23780,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -22368,7 +23794,8 @@ "start_time": "2021-11-24T15:50:04.436252+00:00", "last_update": "2021-11-24T15:50:04.625205+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -22413,7 +23840,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -22421,7 +23854,8 @@ "start_time": "2021-11-24T15:40:04.481903+00:00", "last_update": "2021-11-24T15:40:04.663438+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -22466,7 +23900,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -22474,7 +23914,8 @@ "start_time": "2021-11-24T15:30:04.446758+00:00", "last_update": "2021-11-24T15:30:04.620499+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -22519,7 +23960,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -22527,7 +23974,8 @@ "start_time": "2021-11-24T15:20:04.612123+00:00", "last_update": "2021-11-24T15:20:04.796937+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -22572,7 +24020,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -22580,7 +24034,8 @@ "start_time": "2021-11-24T15:10:04.476532+00:00", "last_update": "2021-11-24T15:10:04.690365+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -22625,7 +24080,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -22633,7 +24094,8 @@ "start_time": "2021-11-24T15:00:04.661578+00:00", "last_update": "2021-11-24T15:00:04.888075+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -22678,7 +24140,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -22686,7 +24154,8 @@ "start_time": "2021-11-24T14:50:04.475653+00:00", "last_update": "2021-11-24T14:50:04.661629+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -22731,7 +24200,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -22739,7 +24214,8 @@ "start_time": "2021-11-24T14:40:04.698078+00:00", "last_update": "2021-11-24T14:40:04.874743+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -22784,7 +24260,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -22792,7 +24274,8 @@ "start_time": "2021-11-24T14:30:04.539611+00:00", "last_update": "2021-11-24T14:30:04.795622+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -22837,7 +24320,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -22845,7 +24334,8 @@ "start_time": "2021-11-24T14:20:04.446140+00:00", "last_update": "2021-11-24T14:20:04.626509+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -22890,7 +24380,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -22898,7 +24394,8 @@ "start_time": "2021-11-24T14:10:04.852408+00:00", "last_update": "2021-11-24T14:10:05.035730+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -22943,7 +24440,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -22951,7 +24454,8 @@ "start_time": "2021-11-24T14:00:04.645034+00:00", "last_update": "2021-11-24T14:00:04.878150+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -22996,7 +24500,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -23004,7 +24514,8 @@ "start_time": "2021-11-24T13:50:04.477657+00:00", "last_update": "2021-11-24T13:50:04.662831+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -23049,7 +24560,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -23057,7 +24574,8 @@ "start_time": "2021-11-24T13:40:04.670473+00:00", "last_update": "2021-11-24T13:40:04.861574+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -23102,7 +24620,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -23110,7 +24634,8 @@ "start_time": "2021-11-24T13:30:04.495716+00:00", "last_update": "2021-11-24T13:30:04.694276+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -23155,7 +24680,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -23163,7 +24694,8 @@ "start_time": "2021-11-24T13:20:04.449564+00:00", "last_update": "2021-11-24T13:20:04.665086+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -23208,7 +24740,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -23216,7 +24754,8 @@ "start_time": "2021-11-24T13:10:04.511729+00:00", "last_update": "2021-11-24T13:10:04.694280+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -23261,7 +24800,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -23269,7 +24814,8 @@ "start_time": "2021-11-24T13:00:04.465753+00:00", "last_update": "2021-11-24T13:00:04.702928+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -23314,7 +24860,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -23322,7 +24874,8 @@ "start_time": "2021-11-24T12:50:04.505712+00:00", "last_update": "2021-11-24T12:50:04.716717+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -23367,7 +24920,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -23375,7 +24934,8 @@ "start_time": "2021-11-24T12:40:04.529680+00:00", "last_update": "2021-11-24T12:40:04.723592+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -23420,7 +24980,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -23428,7 +24994,8 @@ "start_time": "2021-11-24T12:30:04.591878+00:00", "last_update": "2021-11-24T12:30:04.767677+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -23473,7 +25040,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -23481,7 +25054,8 @@ "start_time": "2021-11-24T12:20:04.506881+00:00", "last_update": "2021-11-24T12:20:04.707187+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -23526,7 +25100,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -23534,7 +25114,8 @@ "start_time": "2021-11-24T12:10:04.455195+00:00", "last_update": "2021-11-24T12:10:04.662142+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -23579,7 +25160,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -23587,7 +25174,8 @@ "start_time": "2021-11-24T12:00:04.474861+00:00", "last_update": "2021-11-24T12:00:04.712058+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -23632,7 +25220,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -23640,7 +25234,8 @@ "start_time": "2021-11-24T11:50:04.465545+00:00", "last_update": "2021-11-24T11:50:04.643853+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -23685,7 +25280,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -23693,7 +25294,8 @@ "start_time": "2021-11-24T11:40:04.518707+00:00", "last_update": "2021-11-24T11:40:04.714892+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -23738,7 +25340,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -23746,7 +25354,8 @@ "start_time": "2021-11-24T11:30:04.439386+00:00", "last_update": "2021-11-24T11:30:04.606311+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -23791,7 +25400,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -23799,7 +25414,8 @@ "start_time": "2021-11-24T11:20:04.553954+00:00", "last_update": "2021-11-24T11:20:04.741887+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -23844,7 +25460,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -23852,7 +25474,8 @@ "start_time": "2021-11-24T11:10:04.512320+00:00", "last_update": "2021-11-24T11:10:04.692293+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -23897,7 +25520,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -23905,7 +25534,8 @@ "start_time": "2021-11-24T11:00:04.783589+00:00", "last_update": "2021-11-24T11:00:05.027705+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -23950,7 +25580,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -23958,7 +25594,8 @@ "start_time": "2021-11-24T10:50:04.460250+00:00", "last_update": "2021-11-24T10:50:04.637607+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -24003,7 +25640,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -24011,7 +25654,8 @@ "start_time": "2021-11-24T10:40:04.872549+00:00", "last_update": "2021-11-24T10:40:05.055488+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -24056,7 +25700,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -24064,7 +25714,8 @@ "start_time": "2021-11-24T10:30:04.447723+00:00", "last_update": "2021-11-24T10:30:04.657345+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -24109,7 +25760,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -24117,7 +25774,8 @@ "start_time": "2021-11-24T10:20:04.460217+00:00", "last_update": "2021-11-24T10:20:04.672371+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -24162,7 +25820,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -24170,7 +25834,8 @@ "start_time": "2021-11-24T10:10:04.461257+00:00", "last_update": "2021-11-24T10:10:04.644618+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -24215,7 +25880,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -24223,7 +25894,8 @@ "start_time": "2021-11-24T10:00:04.573863+00:00", "last_update": "2021-11-24T10:00:04.798016+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -24268,7 +25940,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -24276,7 +25954,8 @@ "start_time": "2021-11-24T09:50:04.512501+00:00", "last_update": "2021-11-24T09:50:04.695227+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -24321,7 +26000,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -24329,7 +26014,8 @@ "start_time": "2021-11-24T09:40:04.629863+00:00", "last_update": "2021-11-24T09:40:04.834239+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -24374,7 +26060,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -24382,7 +26074,8 @@ "start_time": "2021-11-24T09:30:04.415640+00:00", "last_update": "2021-11-24T09:30:04.602695+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -24427,7 +26120,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -24435,7 +26134,8 @@ "start_time": "2021-11-24T09:20:04.389076+00:00", "last_update": "2021-11-24T09:20:04.627217+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -24480,7 +26180,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -24488,7 +26194,8 @@ "start_time": "2021-11-24T09:10:04.487116+00:00", "last_update": "2021-11-24T09:10:04.670124+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -24533,7 +26240,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -24541,7 +26254,8 @@ "start_time": "2021-11-24T09:00:04.719912+00:00", "last_update": "2021-11-24T09:00:04.905482+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -24586,7 +26300,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -24594,7 +26314,8 @@ "start_time": "2021-11-24T08:50:04.761983+00:00", "last_update": "2021-11-24T08:50:04.929543+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -24639,7 +26360,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -24647,7 +26374,8 @@ "start_time": "2021-11-24T08:40:04.705636+00:00", "last_update": "2021-11-24T08:40:04.897900+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -24692,7 +26420,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -24700,7 +26434,8 @@ "start_time": "2021-11-24T08:30:04.927018+00:00", "last_update": "2021-11-24T08:30:05.101610+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -24745,7 +26480,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -24753,7 +26494,8 @@ "start_time": "2021-11-24T08:20:04.573076+00:00", "last_update": "2021-11-24T08:20:04.769617+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -24798,7 +26540,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -24806,7 +26554,8 @@ "start_time": "2021-11-24T08:10:04.640802+00:00", "last_update": "2021-11-24T08:10:04.829147+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -24851,7 +26600,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -24859,7 +26614,8 @@ "start_time": "2021-11-24T08:00:04.604561+00:00", "last_update": "2021-11-24T08:00:04.847589+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -24904,7 +26660,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -24912,7 +26674,8 @@ "start_time": "2021-11-24T07:50:04.475602+00:00", "last_update": "2021-11-24T07:50:04.652628+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -24957,7 +26720,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -24965,7 +26734,8 @@ "start_time": "2021-11-24T07:40:04.577226+00:00", "last_update": "2021-11-24T07:40:04.759757+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -25010,7 +26780,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -25018,7 +26794,8 @@ "start_time": "2021-11-24T07:30:04.628014+00:00", "last_update": "2021-11-24T07:30:04.842011+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -25063,7 +26840,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -25071,7 +26854,8 @@ "start_time": "2021-11-24T07:20:04.572949+00:00", "last_update": "2021-11-24T07:20:04.745549+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -25116,7 +26900,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -25124,7 +26914,8 @@ "start_time": "2021-11-24T07:10:04.502879+00:00", "last_update": "2021-11-24T07:10:04.764787+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -25169,7 +26960,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -25177,7 +26974,8 @@ "start_time": "2021-11-24T07:00:04.531331+00:00", "last_update": "2021-11-24T07:00:04.813165+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -25222,7 +27020,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -25230,7 +27034,8 @@ "start_time": "2021-11-24T06:50:04.460491+00:00", "last_update": "2021-11-24T06:50:04.656143+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -25275,7 +27080,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -25283,7 +27094,8 @@ "start_time": "2021-11-24T06:40:04.504154+00:00", "last_update": "2021-11-24T06:40:04.742584+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -25328,7 +27140,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -25336,7 +27154,8 @@ "start_time": "2021-11-24T06:30:04.491594+00:00", "last_update": "2021-11-24T06:30:04.725370+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -25381,7 +27200,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -25389,7 +27214,8 @@ "start_time": "2021-11-24T06:20:04.519788+00:00", "last_update": "2021-11-24T06:20:04.734958+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -25434,7 +27260,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -25442,7 +27274,8 @@ "start_time": "2021-11-24T06:10:04.532763+00:00", "last_update": "2021-11-24T06:10:04.823954+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -25487,7 +27320,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -25495,7 +27334,8 @@ "start_time": "2021-11-24T06:00:04.831518+00:00", "last_update": "2021-11-24T06:00:05.063036+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -25540,7 +27380,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -25548,7 +27394,8 @@ "start_time": "2021-11-24T05:50:04.921557+00:00", "last_update": "2021-11-24T05:50:05.106362+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -25593,7 +27440,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -25601,7 +27454,8 @@ "start_time": "2021-11-24T05:40:04.639983+00:00", "last_update": "2021-11-24T05:40:04.822973+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -25646,7 +27500,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -25654,7 +27514,8 @@ "start_time": "2021-11-24T05:30:04.552970+00:00", "last_update": "2021-11-24T05:30:04.758206+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -25699,7 +27560,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -25707,7 +27574,8 @@ "start_time": "2021-11-24T05:20:04.568293+00:00", "last_update": "2021-11-24T05:20:04.766989+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -25752,7 +27620,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -25760,7 +27634,8 @@ "start_time": "2021-11-24T05:10:04.425638+00:00", "last_update": "2021-11-24T05:10:04.610183+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -25805,7 +27680,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -25813,7 +27694,8 @@ "start_time": "2021-11-24T05:00:04.659651+00:00", "last_update": "2021-11-24T05:00:04.878540+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -25858,7 +27740,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -25866,7 +27754,8 @@ "start_time": "2021-11-24T04:50:04.525809+00:00", "last_update": "2021-11-24T04:50:04.698016+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -25911,7 +27800,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -25919,7 +27814,8 @@ "start_time": "2021-11-24T04:40:04.553894+00:00", "last_update": "2021-11-24T04:40:04.748205+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -25964,7 +27860,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -25972,7 +27874,8 @@ "start_time": "2021-11-24T04:30:04.505059+00:00", "last_update": "2021-11-24T04:30:04.694984+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -26017,7 +27920,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -26025,7 +27934,8 @@ "start_time": "2021-11-24T04:20:04.444087+00:00", "last_update": "2021-11-24T04:20:04.674675+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -26070,7 +27980,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -26078,7 +27994,8 @@ "start_time": "2021-11-24T04:10:04.502094+00:00", "last_update": "2021-11-24T04:10:04.693319+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -26123,7 +28040,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -26131,7 +28054,8 @@ "start_time": "2021-11-24T04:00:04.463193+00:00", "last_update": "2021-11-24T04:00:04.701626+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -26176,7 +28100,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -26184,7 +28114,8 @@ "start_time": "2021-11-24T03:50:04.567814+00:00", "last_update": "2021-11-24T03:50:04.753820+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -26229,7 +28160,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -26237,7 +28174,8 @@ "start_time": "2021-11-24T03:40:04.602754+00:00", "last_update": "2021-11-24T03:40:04.796732+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -26282,7 +28220,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -26290,7 +28234,8 @@ "start_time": "2021-11-24T03:30:04.418104+00:00", "last_update": "2021-11-24T03:30:04.601174+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -26335,7 +28280,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -26343,7 +28294,8 @@ "start_time": "2021-11-24T03:20:04.461566+00:00", "last_update": "2021-11-24T03:20:04.660232+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -26388,7 +28340,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -26396,7 +28354,8 @@ "start_time": "2021-11-24T03:10:04.632882+00:00", "last_update": "2021-11-24T03:10:04.841486+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -26441,7 +28400,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -26449,7 +28414,8 @@ "start_time": "2021-11-24T03:00:04.532402+00:00", "last_update": "2021-11-24T03:00:04.777504+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -26494,7 +28460,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -26502,7 +28474,8 @@ "start_time": "2021-11-24T02:50:04.500997+00:00", "last_update": "2021-11-24T02:50:04.679010+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -26547,7 +28520,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -26555,7 +28534,8 @@ "start_time": "2021-11-24T02:40:04.528901+00:00", "last_update": "2021-11-24T02:40:04.721345+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -26600,7 +28580,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -26608,7 +28594,8 @@ "start_time": "2021-11-24T02:30:04.720846+00:00", "last_update": "2021-11-24T02:30:05.074548+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -26653,7 +28640,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -26661,7 +28654,8 @@ "start_time": "2021-11-24T02:20:04.612354+00:00", "last_update": "2021-11-24T02:20:04.794415+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -26706,7 +28700,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -26714,7 +28714,8 @@ "start_time": "2021-11-24T02:10:04.489593+00:00", "last_update": "2021-11-24T02:10:04.713319+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -26759,7 +28760,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -26767,7 +28774,8 @@ "start_time": "2021-11-24T02:00:04.538137+00:00", "last_update": "2021-11-24T02:00:04.755615+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -26812,7 +28820,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -26820,7 +28834,8 @@ "start_time": "2021-11-24T01:50:04.546914+00:00", "last_update": "2021-11-24T01:50:04.747734+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -26865,7 +28880,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -26873,7 +28894,8 @@ "start_time": "2021-11-24T01:40:04.433153+00:00", "last_update": "2021-11-24T01:40:04.626096+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -26918,7 +28940,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -26926,7 +28954,8 @@ "start_time": "2021-11-24T01:30:04.510443+00:00", "last_update": "2021-11-24T01:30:04.692919+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -26971,7 +29000,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -26979,7 +29014,8 @@ "start_time": "2021-11-24T01:20:05.295062+00:00", "last_update": "2021-11-24T01:20:05.497610+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -27024,7 +29060,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -27032,7 +29074,8 @@ "start_time": "2021-11-24T01:10:04.688801+00:00", "last_update": "2021-11-24T01:10:04.883373+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -27077,7 +29120,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -27085,7 +29134,8 @@ "start_time": "2021-11-24T01:00:04.939719+00:00", "last_update": "2021-11-24T01:00:05.178464+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -27130,7 +29180,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -27138,7 +29194,8 @@ "start_time": "2021-11-24T00:50:04.468549+00:00", "last_update": "2021-11-24T00:50:04.701356+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -27183,7 +29240,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -27191,7 +29254,8 @@ "start_time": "2021-11-24T00:40:04.815652+00:00", "last_update": "2021-11-24T00:40:05.000489+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -27236,7 +29300,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -27244,7 +29314,8 @@ "start_time": "2021-11-24T00:30:04.598658+00:00", "last_update": "2021-11-24T00:30:04.774050+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -27289,7 +29360,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -27297,7 +29374,8 @@ "start_time": "2021-11-24T00:20:04.517762+00:00", "last_update": "2021-11-24T00:20:04.706307+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -27342,7 +29420,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -27350,7 +29434,8 @@ "start_time": "2021-11-24T00:10:04.545462+00:00", "last_update": "2021-11-24T00:10:04.727941+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -27395,7 +29480,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -27403,7 +29494,8 @@ "start_time": "2021-11-24T00:00:04.535371+00:00", "last_update": "2021-11-24T00:00:04.746612+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -27448,7 +29540,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -27456,7 +29554,8 @@ "start_time": "2021-11-23T23:50:04.643566+00:00", "last_update": "2021-11-23T23:50:04.826637+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -27501,7 +29600,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -27509,7 +29614,8 @@ "start_time": "2021-11-23T23:40:04.589647+00:00", "last_update": "2021-11-23T23:40:04.791146+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -27554,7 +29660,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -27562,7 +29674,8 @@ "start_time": "2021-11-23T23:30:04.528050+00:00", "last_update": "2021-11-23T23:30:04.734943+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -27607,7 +29720,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -27615,7 +29734,8 @@ "start_time": "2021-11-23T23:20:04.551632+00:00", "last_update": "2021-11-23T23:20:04.738770+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -27660,7 +29780,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -27668,7 +29794,8 @@ "start_time": "2021-11-23T23:10:04.450823+00:00", "last_update": "2021-11-23T23:10:04.652075+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -27713,7 +29840,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -27721,7 +29854,8 @@ "start_time": "2021-11-23T23:00:04.869365+00:00", "last_update": "2021-11-23T23:00:05.128497+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -27766,7 +29900,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -27774,7 +29914,8 @@ "start_time": "2021-11-23T22:50:04.634188+00:00", "last_update": "2021-11-23T22:50:04.810555+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -27819,7 +29960,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -27827,7 +29974,8 @@ "start_time": "2021-11-23T22:40:04.569522+00:00", "last_update": "2021-11-23T22:40:04.769561+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -27872,7 +30020,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -27880,7 +30034,8 @@ "start_time": "2021-11-23T22:30:04.434236+00:00", "last_update": "2021-11-23T22:30:04.623421+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -27925,7 +30080,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -27933,7 +30094,8 @@ "start_time": "2021-11-23T22:20:04.379221+00:00", "last_update": "2021-11-23T22:20:04.571849+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -27978,7 +30140,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -27986,7 +30154,8 @@ "start_time": "2021-11-23T22:10:04.424226+00:00", "last_update": "2021-11-23T22:10:04.606574+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -28031,7 +30200,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -28039,7 +30214,8 @@ "start_time": "2021-11-23T22:00:04.584191+00:00", "last_update": "2021-11-23T22:00:04.802213+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -28084,7 +30260,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -28092,7 +30274,8 @@ "start_time": "2021-11-23T21:50:04.332475+00:00", "last_update": "2021-11-23T21:50:04.660638+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -28137,7 +30320,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -28145,7 +30334,8 @@ "start_time": "2021-11-23T21:40:04.437659+00:00", "last_update": "2021-11-23T21:40:04.653196+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -28190,7 +30380,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -28198,7 +30394,8 @@ "start_time": "2021-11-23T21:30:04.453384+00:00", "last_update": "2021-11-23T21:30:04.654010+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -28243,7 +30440,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -28251,7 +30454,8 @@ "start_time": "2021-11-23T21:20:04.442566+00:00", "last_update": "2021-11-23T21:20:04.625930+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -28296,7 +30500,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -28304,7 +30514,8 @@ "start_time": "2021-11-23T21:10:04.532801+00:00", "last_update": "2021-11-23T21:10:04.771198+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -28349,7 +30560,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -28357,7 +30574,8 @@ "start_time": "2021-11-23T21:00:04.543551+00:00", "last_update": "2021-11-23T21:00:04.762114+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -28402,7 +30620,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -28410,7 +30634,8 @@ "start_time": "2021-11-23T20:50:04.599458+00:00", "last_update": "2021-11-23T20:50:04.810958+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -28455,7 +30680,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -28463,7 +30694,8 @@ "start_time": "2021-11-23T20:40:04.375137+00:00", "last_update": "2021-11-23T20:40:04.549978+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -28508,7 +30740,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -28516,7 +30754,8 @@ "start_time": "2021-11-23T20:30:04.725045+00:00", "last_update": "2021-11-23T20:30:04.910512+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -28561,7 +30800,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -28569,7 +30814,8 @@ "start_time": "2021-11-23T20:20:04.650462+00:00", "last_update": "2021-11-23T20:20:04.826445+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -28614,7 +30860,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -28622,7 +30874,8 @@ "start_time": "2021-11-23T20:10:04.516348+00:00", "last_update": "2021-11-23T20:10:04.854112+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -28667,7 +30920,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -28675,7 +30934,8 @@ "start_time": "2021-11-23T20:00:04.707833+00:00", "last_update": "2021-11-23T20:00:04.908904+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -28720,7 +30980,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -28728,7 +30994,8 @@ "start_time": "2021-11-23T19:50:04.421833+00:00", "last_update": "2021-11-23T19:50:04.632400+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -28773,7 +31040,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -28781,7 +31054,8 @@ "start_time": "2021-11-23T19:40:04.418991+00:00", "last_update": "2021-11-23T19:40:04.591359+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -28826,7 +31100,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -28834,7 +31114,8 @@ "start_time": "2021-11-23T19:30:04.517543+00:00", "last_update": "2021-11-23T19:30:04.705190+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -28879,7 +31160,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -28887,7 +31174,8 @@ "start_time": "2021-11-23T19:20:04.559188+00:00", "last_update": "2021-11-23T19:20:04.744737+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -28932,7 +31220,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -28940,7 +31234,8 @@ "start_time": "2021-11-23T19:10:04.590607+00:00", "last_update": "2021-11-23T19:10:04.789711+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -28985,7 +31280,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -28993,7 +31294,8 @@ "start_time": "2021-11-23T19:00:04.581072+00:00", "last_update": "2021-11-23T19:00:04.821969+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -29038,7 +31340,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -29046,7 +31354,8 @@ "start_time": "2021-11-23T18:50:04.699860+00:00", "last_update": "2021-11-23T18:50:04.931051+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -29091,7 +31400,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -29099,7 +31414,8 @@ "start_time": "2021-11-23T18:40:05.087681+00:00", "last_update": "2021-11-23T18:40:05.261694+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -29144,7 +31460,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -29152,7 +31474,8 @@ "start_time": "2021-11-23T18:30:04.418439+00:00", "last_update": "2021-11-23T18:30:04.598008+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -29197,7 +31520,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -29205,7 +31534,8 @@ "start_time": "2021-11-23T18:20:04.498606+00:00", "last_update": "2021-11-23T18:20:04.694717+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -29250,7 +31580,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -29258,7 +31594,8 @@ "start_time": "2021-11-23T18:10:04.694077+00:00", "last_update": "2021-11-23T18:10:04.877956+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -29303,7 +31640,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -29311,7 +31654,8 @@ "start_time": "2021-11-23T18:00:04.451190+00:00", "last_update": "2021-11-23T18:00:04.685289+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -29356,7 +31700,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -29364,7 +31714,8 @@ "start_time": "2021-11-23T17:50:04.409692+00:00", "last_update": "2021-11-23T17:50:04.574748+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -29409,7 +31760,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -29417,7 +31774,8 @@ "start_time": "2021-11-23T17:40:04.803186+00:00", "last_update": "2021-11-23T17:40:05.024504+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -29462,7 +31820,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -29470,7 +31834,8 @@ "start_time": "2021-11-23T17:30:04.458452+00:00", "last_update": "2021-11-23T17:30:04.643441+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -29515,7 +31880,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -29523,7 +31894,8 @@ "start_time": "2021-11-23T17:20:04.389008+00:00", "last_update": "2021-11-23T17:20:04.559117+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -29568,7 +31940,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -29576,7 +31954,8 @@ "start_time": "2021-11-23T17:10:04.429827+00:00", "last_update": "2021-11-23T17:10:04.697423+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -29621,7 +32000,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -29629,7 +32014,8 @@ "start_time": "2021-11-23T17:00:04.636519+00:00", "last_update": "2021-11-23T17:00:04.852019+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -29674,7 +32060,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -29682,7 +32074,8 @@ "start_time": "2021-11-23T16:50:04.469691+00:00", "last_update": "2021-11-23T16:50:04.638176+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -29727,7 +32120,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -29735,7 +32134,8 @@ "start_time": "2021-11-23T16:40:04.793124+00:00", "last_update": "2021-11-23T16:40:04.979396+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -29780,7 +32180,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -29788,7 +32194,8 @@ "start_time": "2021-11-23T16:30:04.511592+00:00", "last_update": "2021-11-23T16:30:04.701880+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -29833,7 +32240,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -29841,7 +32254,8 @@ "start_time": "2021-11-23T16:20:04.441622+00:00", "last_update": "2021-11-23T16:20:04.616568+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -29886,7 +32300,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -29894,7 +32314,8 @@ "start_time": "2021-11-23T16:10:04.297534+00:00", "last_update": "2021-11-23T16:10:04.488367+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -29921,14 +32342,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-11-23T16:01:58.107788+00:00", "last_update": "2021-11-23T16:01:58.227436+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -29973,7 +32401,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -29981,7 +32415,8 @@ "start_time": "2021-11-23T16:00:04.725458+00:00", "last_update": "2021-11-23T16:00:04.968356+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -30026,7 +32461,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -30034,7 +32475,8 @@ "start_time": "2021-11-23T15:50:04.422576+00:00", "last_update": "2021-11-23T15:50:04.635788+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -30079,7 +32521,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -30087,7 +32535,8 @@ "start_time": "2021-11-23T15:40:04.641266+00:00", "last_update": "2021-11-23T15:40:04.882666+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -30132,7 +32581,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -30140,7 +32595,8 @@ "start_time": "2021-11-23T15:30:04.378826+00:00", "last_update": "2021-11-23T15:30:04.565072+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -30185,7 +32641,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -30193,7 +32655,8 @@ "start_time": "2021-11-23T15:20:04.559525+00:00", "last_update": "2021-11-23T15:20:04.758667+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -30238,7 +32701,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -30246,7 +32715,8 @@ "start_time": "2021-11-23T15:10:04.536833+00:00", "last_update": "2021-11-23T15:10:04.726331+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -30291,7 +32761,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -30299,7 +32775,8 @@ "start_time": "2021-11-23T15:00:04.563670+00:00", "last_update": "2021-11-23T15:00:04.784840+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -30344,7 +32821,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -30352,7 +32835,8 @@ "start_time": "2021-11-23T14:50:04.460492+00:00", "last_update": "2021-11-23T14:50:04.649701+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -30397,7 +32881,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -30405,7 +32895,8 @@ "start_time": "2021-11-23T14:40:04.553734+00:00", "last_update": "2021-11-23T14:40:04.854853+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -30450,7 +32941,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -30458,7 +32955,8 @@ "start_time": "2021-11-23T14:30:04.626953+00:00", "last_update": "2021-11-23T14:30:04.806765+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -30503,7 +33001,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -30511,7 +33015,8 @@ "start_time": "2021-11-23T14:20:04.478122+00:00", "last_update": "2021-11-23T14:20:04.710932+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -30556,7 +33061,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -30564,7 +33075,8 @@ "start_time": "2021-11-23T14:10:04.510030+00:00", "last_update": "2021-11-23T14:10:04.734683+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -30609,7 +33121,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -30617,7 +33135,8 @@ "start_time": "2021-11-23T14:00:04.692590+00:00", "last_update": "2021-11-23T14:00:04.913319+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -30662,7 +33181,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -30670,7 +33195,8 @@ "start_time": "2021-11-23T13:50:04.486524+00:00", "last_update": "2021-11-23T13:50:04.707908+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -30715,7 +33241,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -30723,7 +33255,8 @@ "start_time": "2021-11-23T13:40:04.695802+00:00", "last_update": "2021-11-23T13:40:04.864555+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -30768,7 +33301,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -30776,7 +33315,8 @@ "start_time": "2021-11-23T13:30:04.466982+00:00", "last_update": "2021-11-23T13:30:04.645016+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -30821,7 +33361,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -30829,7 +33375,8 @@ "start_time": "2021-11-23T13:20:04.432215+00:00", "last_update": "2021-11-23T13:20:04.593066+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -30874,7 +33421,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -30882,7 +33435,8 @@ "start_time": "2021-11-23T13:10:04.377343+00:00", "last_update": "2021-11-23T13:10:04.562248+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -30927,7 +33481,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -30935,7 +33495,8 @@ "start_time": "2021-11-23T13:00:04.757717+00:00", "last_update": "2021-11-23T13:00:04.976383+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -30980,7 +33541,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -30988,7 +33555,8 @@ "start_time": "2021-11-23T12:50:04.510481+00:00", "last_update": "2021-11-23T12:50:04.694038+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -31033,7 +33601,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -31041,7 +33615,8 @@ "start_time": "2021-11-23T12:40:04.381615+00:00", "last_update": "2021-11-23T12:40:04.572676+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -31086,7 +33661,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -31094,7 +33675,8 @@ "start_time": "2021-11-23T12:30:04.503862+00:00", "last_update": "2021-11-23T12:30:04.678147+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -31139,7 +33721,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -31147,7 +33735,8 @@ "start_time": "2021-11-23T12:20:04.559097+00:00", "last_update": "2021-11-23T12:20:04.737203+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -31192,7 +33781,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -31200,7 +33795,8 @@ "start_time": "2021-11-23T12:10:04.449115+00:00", "last_update": "2021-11-23T12:10:04.625507+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -31245,7 +33841,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -31253,7 +33855,8 @@ "start_time": "2021-11-23T12:00:04.486243+00:00", "last_update": "2021-11-23T12:00:04.698411+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -31298,7 +33901,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -31306,7 +33915,8 @@ "start_time": "2021-11-23T11:50:04.723311+00:00", "last_update": "2021-11-23T11:50:04.932266+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -31351,7 +33961,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -31359,7 +33975,8 @@ "start_time": "2021-11-23T11:40:04.649386+00:00", "last_update": "2021-11-23T11:40:04.869518+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -31404,7 +34021,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -31412,7 +34035,8 @@ "start_time": "2021-11-23T11:30:04.532380+00:00", "last_update": "2021-11-23T11:30:04.711271+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -31457,7 +34081,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -31465,7 +34095,8 @@ "start_time": "2021-11-23T11:20:04.501966+00:00", "last_update": "2021-11-23T11:20:04.698149+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -31510,7 +34141,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -31518,7 +34155,8 @@ "start_time": "2021-11-23T11:10:04.480587+00:00", "last_update": "2021-11-23T11:10:04.666382+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -31563,7 +34201,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -31571,7 +34215,8 @@ "start_time": "2021-11-23T11:00:04.482799+00:00", "last_update": "2021-11-23T11:00:04.712377+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -31616,7 +34261,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -31624,7 +34275,8 @@ "start_time": "2021-11-23T10:50:04.458809+00:00", "last_update": "2021-11-23T10:50:04.633174+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -31669,7 +34321,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -31677,7 +34335,8 @@ "start_time": "2021-11-23T10:40:04.415844+00:00", "last_update": "2021-11-23T10:40:04.582542+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -31722,7 +34381,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -31730,7 +34395,8 @@ "start_time": "2021-11-23T10:30:04.376510+00:00", "last_update": "2021-11-23T10:30:04.568037+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -31775,7 +34441,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -31783,7 +34455,8 @@ "start_time": "2021-11-23T10:20:04.393940+00:00", "last_update": "2021-11-23T10:20:04.599562+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -31828,7 +34501,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -31836,7 +34515,8 @@ "start_time": "2021-11-23T10:10:04.602995+00:00", "last_update": "2021-11-23T10:10:04.792896+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -31884,7 +34564,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -31892,7 +34578,8 @@ "start_time": "2021-11-23T10:04:11.101928+00:00", "last_update": "2021-11-23T10:04:11.277613+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -31919,14 +34606,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-11-23T10:03:38.156539+00:00", "last_update": "2021-11-23T10:03:52.050684+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -31954,14 +34648,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-11-23T10:03:35.393063+00:00", "last_update": "2021-11-23T10:03:35.483063+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -31988,14 +34689,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-11-08T11:46:51.227805+00:00", "last_update": "2021-11-08T11:46:51.296237+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -32022,14 +34730,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-11-08T11:45:22.064287+00:00", "last_update": "2021-11-08T11:45:22.145479+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -32064,7 +34779,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -32072,7 +34793,8 @@ "start_time": "2021-11-08T11:43:51.387325+00:00", "last_update": "2021-11-08T11:43:51.660572+00:00", "error": "Columns must be same length as key", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -32115,14 +34837,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "aborted", "results": {}, "start_time": "2021-11-08T11:42:59.089848+00:00", "last_update": "2021-11-08T11:43:07.483195+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -32169,14 +34898,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-11-08T11:40:08.223207+00:00", "last_update": "2021-11-08T11:40:36.453731+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -32219,14 +34955,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-11-08T11:39:43.558424+00:00", "last_update": "2021-11-08T11:40:06.182841+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -32273,14 +35016,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-11-08T11:39:35.083703+00:00", "last_update": "2021-11-08T11:39:35.895469+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -32308,14 +35058,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-11-08T11:36:03.228032+00:00", "last_update": "2021-11-08T11:36:03.301501+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -32343,14 +35100,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-11-02T08:47:57.208326+00:00", "last_update": "2021-11-02T08:47:57.328639+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -32378,14 +35142,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-11-01T00:00:08.999400+00:00", "last_update": "2021-11-01T00:00:09.211607+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -32411,14 +35182,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-10-28T18:12:56.106520+00:00", "last_update": "2021-10-28T18:13:17.198567+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -32444,14 +35222,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-10-28T14:18:37.228925+00:00", "last_update": "2021-10-28T14:19:06.426608+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -32479,14 +35264,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-10-28T13:46:21.225458+00:00", "last_update": "2021-10-28T13:46:21.294035+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -32537,7 +35329,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -32545,7 +35343,8 @@ "start_time": "2021-10-28T13:43:30.968141+00:00", "last_update": "2021-10-28T13:43:31.647120+00:00", "error": "file type unhandled v3io:///test/test", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -32587,14 +35386,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-10-28T08:40:35.739139+00:00", "last_update": "2021-10-28T08:41:05.600456+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -32640,14 +35446,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "aborted", "results": {}, "start_time": "2021-10-21T18:14:19.099271+00:00", "last_update": "2021-10-21T18:14:46.228065+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -32673,14 +35486,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "aborted", "results": {}, "start_time": "2021-10-19T07:46:06.654759+00:00", "last_update": "2021-10-19T07:46:36.553501+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -32706,14 +35526,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-10-19T07:32:37.765470+00:00", "last_update": "2021-10-19T07:32:56.606738+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -32739,14 +35566,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "aborted", "results": {}, "start_time": "2021-10-15T14:54:55.118884+00:00", "last_update": "2021-10-15T14:55:06.696436+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -32773,14 +35607,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-10-13T19:58:01.299873+00:00", "last_update": "2021-10-13T19:58:01.374021+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -32807,14 +35648,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-10-13T19:41:12.462796+00:00", "last_update": "2021-10-13T19:41:12.541077+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -32840,14 +35688,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-10-13T19:23:24.084989+00:00", "last_update": "2021-10-13T19:23:24.472745+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -32873,14 +35728,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-10-13T19:22:17.420518+00:00", "last_update": "2021-10-13T19:22:24.018887+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -32906,14 +35768,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-10-13T15:55:43.092290+00:00", "last_update": "2021-10-13T15:56:04.828883+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -32940,14 +35809,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-10-13T15:14:29.209667+00:00", "last_update": "2021-10-13T15:14:29.271307+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -32974,14 +35850,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-10-13T14:12:55.122657+00:00", "last_update": "2021-10-13T14:12:55.188855+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -33008,14 +35891,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-10-13T14:02:19.750855+00:00", "last_update": "2021-10-13T14:02:19.839795+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -33041,14 +35931,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "aborted", "results": {}, "start_time": "2021-10-10T10:27:23.881911+00:00", "last_update": "2021-10-10T10:27:24.616015+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -33074,14 +35971,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "aborted", "results": {}, "start_time": "2021-10-10T10:22:23.551995+00:00", "last_update": "2021-10-10T10:22:29.710206+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -33107,14 +36011,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "aborted", "results": {}, "start_time": "2021-10-10T10:22:01.460726+00:00", "last_update": "2021-10-10T10:22:06.341668+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -33140,14 +36051,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "aborted", "results": {}, "start_time": "2021-10-10T10:21:34.872124+00:00", "last_update": "2021-10-10T10:21:44.400075+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -33183,14 +36101,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-10-06T14:10:00.438518+00:00", "last_update": "2021-10-06T14:10:16.259616+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -33217,14 +36142,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-10-01T00:00:00.235989+00:00", "last_update": "2021-10-01T00:00:12.308235+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -33250,14 +36182,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-09-30T12:03:14.421289+00:00", "last_update": "2021-09-30T12:03:33.039369+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -33283,14 +36222,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-09-30T12:00:57.901153+00:00", "last_update": "2021-09-30T12:01:01.851605+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -33316,14 +36262,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "aborted", "results": {}, "start_time": "2021-09-17T15:08:47.936899+00:00", "last_update": "2021-09-17T15:09:07.462131+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -33380,7 +36333,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -33388,7 +36347,8 @@ "start_time": "2021-09-17T15:08:29.202452+00:00", "last_update": "2021-09-17T15:08:30.072691+00:00", "error": "unable to connect to account for Must provide either a connection_string or account_name with credentials!!", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -33445,7 +36405,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -33453,7 +36419,8 @@ "start_time": "2021-09-17T12:53:31.183995+00:00", "last_update": "2021-09-17T12:53:31.818200+00:00", "error": "file type unhandled v3io://hhhhjjjjkkkk", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -33510,7 +36477,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -33518,7 +36491,8 @@ "start_time": "2021-09-17T12:50:53.673923+00:00", "last_update": "2021-09-17T12:50:54.305932+00:00", "error": "file type unhandled v3io://hhhhhhh", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -33575,7 +36549,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -33583,7 +36563,8 @@ "start_time": "2021-09-17T12:44:47.158478+00:00", "last_update": "2021-09-17T12:44:47.738459+00:00", "error": "file type unhandled v3io://test", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -33640,7 +36621,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -33648,7 +36635,8 @@ "start_time": "2021-09-17T12:15:35.974230+00:00", "last_update": "2021-09-17T12:15:36.567922+00:00", "error": "file type unhandled v3io://sdadsada", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -33705,7 +36693,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -33713,7 +36707,8 @@ "start_time": "2021-09-17T12:14:22.653559+00:00", "last_update": "2021-09-17T12:14:23.294026+00:00", "error": "file type unhandled v3io://ss", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -33770,7 +36765,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -33778,7 +36779,8 @@ "start_time": "2021-09-17T12:13:17.761118+00:00", "last_update": "2021-09-17T12:13:18.502005+00:00", "error": "file type unhandled v3io://yy", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -33835,7 +36837,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -33843,7 +36851,8 @@ "start_time": "2021-09-17T12:12:48.401039+00:00", "last_update": "2021-09-17T12:12:49.044854+00:00", "error": "file type unhandled v3io://tt", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -33900,7 +36909,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -33908,7 +36923,8 @@ "start_time": "2021-09-17T12:09:10.806047+00:00", "last_update": "2021-09-17T12:09:11.364692+00:00", "error": "file type unhandled v3io://ewqewq", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -33965,7 +36981,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -33973,7 +36995,8 @@ "start_time": "2021-09-17T11:59:50.920646+00:00", "last_update": "2021-09-17T11:59:51.576888+00:00", "error": "file type unhandled v3io://asd", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -34030,7 +37053,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -34038,7 +37067,8 @@ "start_time": "2021-09-17T11:59:01.285243+00:00", "last_update": "2021-09-17T11:59:04.051728+00:00", "error": "file type unhandled s3://asd", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -34095,7 +37125,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -34103,7 +37139,8 @@ "start_time": "2021-09-17T11:57:57.036076+00:00", "last_update": "2021-09-17T11:57:57.905590+00:00", "error": "file type unhandled v3io://qweewqqwwwwwwww", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -34129,14 +37166,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-09-17T11:34:04.948045+00:00", "last_update": "2021-09-17T11:34:11.649796+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -34193,7 +37237,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -34201,7 +37251,8 @@ "start_time": "2021-09-17T08:01:55.544559+00:00", "last_update": "2021-09-17T08:01:56.622206+00:00", "error": "unable to connect to account for Must provide either a connection_string or account_name with credentials!!", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -34258,7 +37309,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -34266,7 +37323,8 @@ "start_time": "2021-09-16T15:34:11.324884+00:00", "last_update": "2021-09-16T15:34:11.938806+00:00", "error": "file type unhandled v3io://asd", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -34323,7 +37381,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -34331,7 +37395,8 @@ "start_time": "2021-09-15T11:11:23.310455+00:00", "last_update": "2021-09-15T11:11:23.886661+00:00", "error": "file type unhandled v3io://aa", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -34357,7 +37422,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -34365,7 +37436,8 @@ "start_time": "2021-09-10T08:07:55.696888+00:00", "last_update": "2021-09-10T08:07:55.747261+00:00", "artifacts": [], - "error": "(422)\nReason: Unprocessable Entity\nHTTP response headers: HTTPHeaderDict({'Cache-Control': 'no-cache, private', 'Content-Type': 'application/json', 'Date': 'Fri, 10 Sep 2021 08:07:55 GMT', 'Content-Length': '1026'})\nHTTP response body: {\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"Pod \\\"test-i-vmghw\\\" is invalid: [spec.volumes[0].name: Invalid value: \\\"volume_test__name\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?'), spec.containers[0].volumeMounts[0].name: Not found: \\\"volume_test__name\\\"]\",\"reason\":\"Invalid\",\"details\":{\"name\":\"test-i-vmghw\",\"kind\":\"Pod\",\"causes\":[{\"reason\":\"FieldValueInvalid\",\"message\":\"Invalid value: \\\"volume_test__name\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')\",\"field\":\"spec.volumes[0].name\"},{\"reason\":\"FieldValueNotFound\",\"message\":\"Not found: \\\"volume_test__name\\\"\",\"field\":\"spec.containers[0].volumeMounts[0].name\"}]},\"code\":422}\n\n" + "error": "(422)\nReason: Unprocessable Entity\nHTTP response headers: HTTPHeaderDict({'Cache-Control': 'no-cache, private', 'Content-Type': 'application/json', 'Date': 'Fri, 10 Sep 2021 08:07:55 GMT', 'Content-Length': '1026'})\nHTTP response body: {\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"Pod \\\"test-i-vmghw\\\" is invalid: [spec.volumes[0].name: Invalid value: \\\"volume_test__name\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?'), spec.containers[0].volumeMounts[0].name: Not found: \\\"volume_test__name\\\"]\",\"reason\":\"Invalid\",\"details\":{\"name\":\"test-i-vmghw\",\"kind\":\"Pod\",\"causes\":[{\"reason\":\"FieldValueInvalid\",\"message\":\"Invalid value: \\\"volume_test__name\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')\",\"field\":\"spec.volumes[0].name\"},{\"reason\":\"FieldValueNotFound\",\"message\":\"Not found: \\\"volume_test__name\\\"\",\"field\":\"spec.containers[0].volumeMounts[0].name\"}]},\"code\":422}\n\n", + "retry_count": 0 } }, { @@ -34391,7 +37463,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -34399,7 +37477,8 @@ "start_time": "2021-09-10T08:07:27.992706+00:00", "last_update": "2021-09-10T08:07:28.071778+00:00", "artifacts": [], - "error": "(422)\nReason: Unprocessable Entity\nHTTP response headers: HTTPHeaderDict({'Cache-Control': 'no-cache, private', 'Content-Type': 'application/json', 'Date': 'Fri, 10 Sep 2021 08:07:28 GMT', 'Content-Length': '1026'})\nHTTP response body: {\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"Pod \\\"test-i-d2x69\\\" is invalid: [spec.volumes[0].name: Invalid value: \\\"volume_test__name\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?'), spec.containers[0].volumeMounts[0].name: Not found: \\\"volume_test__name\\\"]\",\"reason\":\"Invalid\",\"details\":{\"name\":\"test-i-d2x69\",\"kind\":\"Pod\",\"causes\":[{\"reason\":\"FieldValueInvalid\",\"message\":\"Invalid value: \\\"volume_test__name\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')\",\"field\":\"spec.volumes[0].name\"},{\"reason\":\"FieldValueNotFound\",\"message\":\"Not found: \\\"volume_test__name\\\"\",\"field\":\"spec.containers[0].volumeMounts[0].name\"}]},\"code\":422}\n\n" + "error": "(422)\nReason: Unprocessable Entity\nHTTP response headers: HTTPHeaderDict({'Cache-Control': 'no-cache, private', 'Content-Type': 'application/json', 'Date': 'Fri, 10 Sep 2021 08:07:28 GMT', 'Content-Length': '1026'})\nHTTP response body: {\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"Pod \\\"test-i-d2x69\\\" is invalid: [spec.volumes[0].name: Invalid value: \\\"volume_test__name\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?'), spec.containers[0].volumeMounts[0].name: Not found: \\\"volume_test__name\\\"]\",\"reason\":\"Invalid\",\"details\":{\"name\":\"test-i-d2x69\",\"kind\":\"Pod\",\"causes\":[{\"reason\":\"FieldValueInvalid\",\"message\":\"Invalid value: \\\"volume_test__name\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')\",\"field\":\"spec.volumes[0].name\"},{\"reason\":\"FieldValueNotFound\",\"message\":\"Not found: \\\"volume_test__name\\\"\",\"field\":\"spec.containers[0].volumeMounts[0].name\"}]},\"code\":422}\n\n", + "retry_count": 0 } }, { @@ -34425,14 +37504,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-09-08T16:01:00.020724+00:00", "last_update": "2021-09-08T16:01:28.024926+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -34458,14 +37544,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-09-08T15:51:02.734809+00:00", "last_update": "2021-09-08T15:51:23.296887+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -34491,14 +37584,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-09-08T15:37:29.504427+00:00", "last_update": "2021-09-08T15:37:47.727633+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -34544,14 +37644,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-09-07T11:42:54.171035+00:00", "last_update": "2021-09-07T11:42:56.512443+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -34577,14 +37684,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-09-07T11:20:14.154220+00:00", "last_update": "2021-09-07T11:20:16.663883+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -34610,14 +37724,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-09-07T09:03:37.071417+00:00", "last_update": "2021-09-07T09:04:05.569790+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -34668,7 +37789,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -34677,7 +37804,8 @@ }, "start_time": "2021-09-04T08:13:13.409154+00:00", "last_update": "2021-09-04T08:13:14.808015+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -34711,7 +37839,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -34719,7 +37853,8 @@ "start_time": "2021-09-03T13:53:56.088502+00:00", "last_update": "2021-09-03T13:53:56.318914+00:00", "error": "Columns must be same length as key", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -34746,14 +37881,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-09-03T13:53:50.030505+00:00", "last_update": "2021-09-03T13:53:50.099756+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -34800,7 +37942,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -34808,7 +37956,8 @@ "start_time": "2021-09-03T13:53:35.470383+00:00", "last_update": "2021-09-03T13:53:35.716754+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -34835,14 +37984,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-09-03T13:52:40.749944+00:00", "last_update": "2021-09-03T13:52:40.810108+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -34869,14 +38025,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-09-03T12:02:52.273993+00:00", "last_update": "2021-09-03T12:02:52.335681+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -34911,7 +38074,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -34919,7 +38088,8 @@ "start_time": "2021-09-03T12:02:03.774104+00:00", "last_update": "2021-09-03T12:02:03.936616+00:00", "error": "[Errno 2] No such file or directory: 'message_file'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -34966,7 +38136,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -34974,7 +38150,8 @@ "start_time": "2021-09-01T13:32:53.361949+00:00", "last_update": "2021-09-01T13:32:53.519516+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -35000,7 +38177,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -35008,7 +38191,8 @@ "start_time": "2021-08-31T19:07:10.627886+00:00", "last_update": "2021-08-31T19:07:10.683889+00:00", "artifacts": [], - "error": "cannot import from ''" + "error": "cannot import from ''", + "retry_count": 2 } }, { @@ -35034,14 +38218,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "aborted", "results": {}, "start_time": "2021-10-04T06:43:00.974008+00:00", "last_update": "2021-10-04T06:43:07.566741+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -35079,7 +38270,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -35088,7 +38285,8 @@ }, "start_time": "2021-08-29T19:45:14.995282+00:00", "last_update": "2021-08-29T19:45:18.516911+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -35119,14 +38317,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-11-23T10:00:00.059030+00:00", "last_update": "2021-11-23T10:00:20.339115+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -35156,14 +38361,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-11-23T09:58:33.718204+00:00", "last_update": "2021-11-23T09:58:49.667649+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -35195,7 +38407,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -35203,7 +38421,8 @@ "start_time": "2021-11-08T16:26:31.029770+00:00", "last_update": "2021-11-08T16:27:42.496061+00:00", "error": "401 received while accessing 'getting-started-tutorial-admin/artifacts/data/test_set.csv'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -35238,7 +38457,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -35246,7 +38471,8 @@ "start_time": "2021-11-08T16:26:21.976983+00:00", "last_update": "2021-11-08T16:28:41.537143+00:00", "error": "401 received while accessing 'getting-started-tutorial-admin/artifacts/pipeline/dd5972cb-cbc2-4998-ab0e-705dba1b307d/data/test_set.csv'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -35279,7 +38505,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -35287,7 +38519,8 @@ "start_time": "2021-11-08T16:24:23.377270+00:00", "last_update": "2021-11-08T16:24:23.642837+00:00", "error": "file type unhandled dataset", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -35320,7 +38553,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -35328,7 +38567,8 @@ "start_time": "2021-11-08T16:24:03.601835+00:00", "last_update": "2021-11-08T16:24:03.787381+00:00", "error": "file type unhandled source_url", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -35370,7 +38610,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -35378,7 +38624,8 @@ "start_time": "2021-11-08T16:21:59.747369+00:00", "last_update": "2021-11-08T16:21:59.925727+00:00", "error": "file type unhandled test_set", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -35416,7 +38663,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -35424,7 +38677,8 @@ "start_time": "2021-11-08T16:21:43.033778+00:00", "last_update": "2021-11-08T16:21:43.242064+00:00", "error": "file type unhandled table", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -35451,7 +38705,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -35459,7 +38719,8 @@ "start_time": "2021-11-08T16:21:00.729828+00:00", "last_update": "2021-11-08T16:21:00.772223+00:00", "artifacts": [], - "error": ".run() can only be execute on \"mlrun\" kind, recreate with function kind \"mlrun\"" + "error": ".run() can only be execute on \"mlrun\" kind, recreate with function kind \"mlrun\"", + "retry_count": 1 } }, { @@ -35495,7 +38756,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -36144,7 +39411,8 @@ "uid": "460-3", "tag": "latest" } - ] + ], + "retry_count": 1 } }, { @@ -36181,7 +39449,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -37283,7 +40557,8 @@ "uid": "461-5", "tag": "latest" } - ] + ], + "retry_count": 0 } }, { @@ -37319,7 +40594,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -37835,7 +41116,8 @@ "uid": "462-0", "tag": "latest" } - ] + ], + "retry_count": 0 } }, { @@ -37868,7 +41150,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -38517,7 +41805,8 @@ "uid": "463-3", "tag": "latest" } - ] + ], + "retry_count": 1 } }, { @@ -38548,7 +41837,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -38658,7 +41953,8 @@ "uid": "464-5", "tag": "latest" } - ] + ], + "retry_count": 0 } }, { @@ -38689,7 +41985,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -39791,7 +43093,8 @@ "uid": "465-5", "tag": "latest" } - ] + ], + "retry_count": 0 } }, { @@ -39820,7 +43123,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -40336,7 +43645,8 @@ "uid": "466-0", "tag": "latest" } - ] + ], + "retry_count": 0 } }, { @@ -40365,7 +43675,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -40881,7 +44197,8 @@ "uid": "467-0", "tag": "latest" } - ] + ], + "retry_count": 0 } }, { @@ -40910,7 +44227,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -41426,7 +44749,8 @@ "uid": "468-0", "tag": "latest" } - ] + ], + "retry_count": 2 } }, { @@ -41455,14 +44779,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-08-31T19:47:38.497611+00:00", "last_update": "2021-08-31T19:47:53.564737+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -41493,14 +44824,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-08-29T20:05:25.859281+00:00", "last_update": "2021-08-29T20:07:09.961262+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -41526,14 +44864,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-09-10T11:40:10.676831+00:00", "last_update": "2021-09-10T11:40:27.194590+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -41559,14 +44904,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-09-08T12:58:23.170389+00:00", "last_update": "2021-09-08T12:58:43.526754+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -41601,7 +44953,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -41609,7 +44967,8 @@ "start_time": "2021-09-06T15:18:24.118044+00:00", "last_update": "2021-09-06T15:18:24.379177+00:00", "error": "unsupported archive type in archive_url", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -41655,7 +45014,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -41663,7 +45028,8 @@ "start_time": "2021-09-06T13:47:42.720200+00:00", "last_update": "2021-09-06T13:47:42.859183+00:00", "error": "file type unhandled dataset", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -41709,7 +45075,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -41717,7 +45089,8 @@ "start_time": "2021-09-06T13:45:12.800502+00:00", "last_update": "2021-09-06T13:45:12.929041+00:00", "error": "file type unhandled dataset", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -41763,14 +45136,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "aborted", "results": {}, "start_time": "2021-09-03T11:09:10.722682+00:00", "last_update": "2021-09-03T11:09:31.085216+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -41794,14 +45174,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "running", "results": {}, "start_time": "2021-11-16T07:37:26.003124+00:00", "last_update": "2021-11-16T07:37:26.003133+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -41825,14 +45212,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "running", "results": {}, "start_time": "2021-11-16T07:37:26.001892+00:00", "last_update": "2021-11-16T07:37:26.001899+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -41856,14 +45250,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "running", "results": {}, "start_time": "2021-11-16T07:37:25.723971+00:00", "last_update": "2021-11-16T07:37:25.723978+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -41887,14 +45288,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "running", "results": {}, "start_time": "2021-11-16T07:37:25.667003+00:00", "last_update": "2021-11-16T07:37:25.667009+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -41938,7 +45346,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -41991,7 +45405,8 @@ "uid": "481-2", "tag": "latest" } - ] + ], + "retry_count": 0 } }, { @@ -42015,14 +45430,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "running", "results": {}, "start_time": "2021-08-29T20:28:59.571945+00:00", "last_update": "2021-08-29T20:28:59.571951+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -42046,14 +45468,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "running", "results": {}, "start_time": "2021-08-29T20:28:59.571725+00:00", "last_update": "2021-08-29T20:28:59.571731+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -42091,7 +45520,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -42120,7 +45555,8 @@ "uid": "484-0", "tag": "latest" } - ] + ], + "retry_count": 0 } }, { @@ -42144,14 +45580,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "running", "results": {}, "start_time": "2021-08-29T20:28:11.410654+00:00", "last_update": "2021-08-29T20:28:11.410660+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -42175,14 +45618,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "running", "results": {}, "start_time": "2021-08-29T20:28:11.397877+00:00", "last_update": "2021-08-29T20:28:11.397882+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -42220,7 +45670,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -42891,7 +46347,8 @@ "uid": "487-5", "tag": "latest" } - ] + ], + "retry_count": 1 } }, { @@ -42939,7 +46396,13 @@ "hyper_param_options": { "selector": "max.accuracy" }, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -44032,7 +47495,8 @@ "uid": "488-7", "tag": "latest" } - ] + ], + "retry_count": 1 } }, { @@ -44080,7 +47544,13 @@ "hyper_param_options": { "selector": "max.accuracy" }, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -45173,7 +48643,8 @@ "uid": "489-7", "tag": "latest" } - ] + ], + "retry_count": 1 } }, { @@ -45221,7 +48692,13 @@ "hyper_param_options": { "selector": "max.accuracy" }, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -46314,7 +49791,8 @@ "uid": "490-7", "tag": "latest" } - ] + ], + "retry_count": 0 } }, { @@ -46362,7 +49840,13 @@ "hyper_param_options": { "selector": "max.accuracy" }, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -47455,7 +50939,8 @@ "uid": "491-7", "tag": "latest" } - ] + ], + "retry_count": 1 } }, { @@ -47499,7 +50984,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -47609,7 +51100,8 @@ "uid": "492-5", "tag": "latest" } - ] + ], + "retry_count": 0 } }, { @@ -47649,7 +51141,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -50174,7 +53672,8 @@ "uid": "493-9", "tag": "latest" } - ] + ], + "retry_count": 2 } }, { @@ -50219,7 +53718,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -50357,7 +53862,8 @@ "uid": "494-5", "tag": "latest" } - ] + ], + "retry_count": 2 } }, { @@ -50409,7 +53915,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -53291,7 +56803,8 @@ "uid": "495-0", "tag": "latest" } - ] + ], + "retry_count": 0 } }, { @@ -53330,7 +56843,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -53468,7 +56987,8 @@ "uid": "496-5", "tag": "latest" } - ] + ], + "retry_count": 0 } }, { @@ -53519,7 +57039,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -56401,7 +59927,8 @@ "uid": "497-0", "tag": "latest" } - ] + ], + "retry_count": 1 } }, { @@ -56439,7 +59966,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -56549,7 +60082,8 @@ "uid": "498-5", "tag": "latest" } - ] + ], + "retry_count": 0 } }, { @@ -56573,7 +60107,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "running", @@ -57158,7 +60698,8 @@ "uid": "499-0", "tag": "latest" } - ] + ], + "retry_count": 2 } }, { @@ -57203,14 +60744,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-10-01T00:00:00.277689+00:00", "last_update": "2021-10-01T00:00:12.345881+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -57258,7 +60806,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -57266,7 +60820,8 @@ "start_time": "2021-09-01T00:00:07.362502+00:00", "last_update": "2021-09-01T00:00:07.556686+00:00", "error": "file type unhandled dataset", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -57303,7 +60858,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -57311,7 +60872,8 @@ "start_time": "2021-08-31T12:28:09.838061+00:00", "last_update": "2021-08-31T12:28:10.003381+00:00", "error": "file type unhandled table", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -57347,7 +60909,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -57376,7 +60944,8 @@ "uid": "503-0", "tag": "latest" } - ] + ], + "retry_count": 2 } }, { @@ -57412,7 +60981,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -58031,7 +61606,8 @@ "uid": "504-4", "tag": "latest" } - ] + ], + "retry_count": 0 } }, { @@ -58078,7 +61654,13 @@ "hyper_param_options": { "selector": "max.accuracy" }, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -59048,7 +62630,8 @@ "uid": "505-6", "tag": "latest" } - ] + ], + "retry_count": 0 } }, { @@ -59095,7 +62678,13 @@ "hyper_param_options": { "selector": "max.accuracy" }, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -60065,7 +63654,8 @@ "uid": "506-6", "tag": "latest" } - ] + ], + "retry_count": 2 } }, { @@ -60112,7 +63702,13 @@ "hyper_param_options": { "selector": "max.accuracy" }, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -61082,7 +64678,8 @@ "uid": "507-6", "tag": "latest" } - ] + ], + "retry_count": 1 } }, { @@ -61117,7 +64714,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -61227,7 +64830,8 @@ "uid": "508-5", "tag": "latest" } - ] + ], + "retry_count": 1 } }, { @@ -61274,7 +64878,13 @@ "hyper_param_options": { "selector": "max.accuracy" }, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -62244,7 +65854,8 @@ "uid": "509-6", "tag": "latest" } - ] + ], + "retry_count": 1 } }, { @@ -62278,7 +65889,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -62792,7 +66409,8 @@ "uid": "510-0", "tag": "latest" } - ] + ], + "retry_count": 1 } }, { @@ -62823,7 +66441,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -62933,7 +66557,8 @@ "uid": "511-5", "tag": "latest" } - ] + ], + "retry_count": 0 } }, { @@ -62960,14 +66585,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-08-30T05:19:49.379677+00:00", "last_update": "2021-08-30T05:19:49.578198+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -62999,14 +66631,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", "results": {}, "start_time": "2021-10-28T13:52:42.987115+00:00", "last_update": "2021-10-28T13:52:55.115320+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -63052,7 +66691,13 @@ "hyper_param_options": { "selector": "max.accuracy" }, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -67847,7 +71492,8 @@ "uid": "514-7", "tag": "latest" } - ] + ], + "retry_count": 2 } }, { @@ -67884,7 +71530,13 @@ "node_selector": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "results": {}, @@ -67892,8 +71544,61 @@ "last_update": "2024-10-08T14:34:12.621378+00:00", "state": "aborted", "abort_task_id": "74be3e06-56fb-4bc9-9ece-b77f7f818373", - "status_text": "aborted" + "status_text": "aborted", + "retry_count": 0 + } + }, + { + "kind": "run", + "metadata": { + "name": "test-func-oyn-handler", + "uid": "98418b756c4b4307be9a3e7c39e66f21", + "iteration": 0, + "project": "default", + "labels": { + "v3io_user": "normal-user", + "kind": "job", + "owner": "normal-user", + "mlrun/client_version": "1.10.0-rc23", + "mlrun/client_python_version": "3.9.18", + "host": "test-func-oyn-handler-h9xjm" + }, + "annotations": {} + }, + "spec": { + "function": "default/test-func-oyn@93124a9c66fcefbe27b24109a729691f8dbea5c0", + "log_level": "info", + "parameters": {}, + "handler": "handler", + "outputs": [], + "output_path": "v3io:///projects/mm-alerts-proj/artifacts", + "inputs": {}, + "notifications": [], + "state_thresholds": { + "pending_scheduled": "1h", + "pending_not_scheduled": "-1", + "image_pull_backoff": "1h", + "executing": "24h" + }, + "node_selector": {}, + "tolerations": {}, + "affinity": {}, + "retry": {}, + "hyperparams": {}, + "hyper_param_options": {}, + "data_stores": [] + }, + "status": { + "results": {}, + "start_time": "2025-09-04T12:45:48.586000+00:00", + "last_update": "2025-09-04T12:45:48.925000+00:00", + "retry_count": null, + "retries": [], + "state": "error", + "artifact_uris": {}, + "error": "This function intentionally fails", + "end_time": "2025-09-04T12:45:48.870872+00:00" } } ] -} \ No newline at end of file +} diff --git a/tests/mockServer/data/runs.json b/tests/mockServer/data/runs.json index 678aa482b9..c88fcb93b7 100644 --- a/tests/mockServer/data/runs.json +++ b/tests/mockServer/data/runs.json @@ -24,7 +24,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -32,7 +38,8 @@ "start_time": "2021-11-08T16:24:30.312181+00:00", "last_update": "2021-11-08T16:24:30.472758+00:00", "artifacts": [], - "error": "handler dg not found in main.py" + "error": "handler dg not found in main.py", + "retry_count": 0 } }, { @@ -59,7 +66,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -67,7 +80,8 @@ "start_time": "2021-11-08T16:24:30.312181+00:00", "last_update": "2021-11-08T16:24:30.472758+00:00", "artifacts": [], - "error": "handler dg not found in main.py" + "error": "handler dg not found in main.py", + "retry_count": 2 } }, { @@ -94,7 +108,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -102,7 +122,8 @@ "start_time": "2021-11-08T16:24:30.310633+00:00", "last_update": "2021-11-08T16:24:30.473678+00:00", "artifacts": [], - "error": "handler seg not found in main.py" + "error": "handler seg not found in main.py", + "retry_count": 2 } }, { @@ -129,14 +150,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-11-08T16:22:18.425595+00:00", "last_update": "2021-11-08T16:23:45.047882+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -162,7 +190,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -170,7 +204,8 @@ "start_time": "2021-10-26T10:23:46.201308+00:00", "last_update": "2021-10-26T10:23:46.326428+00:00", "artifacts": [], - "error": "handler seg not found in main.py" + "error": "handler seg not found in main.py", + "retry_count": 0 } }, { @@ -196,14 +231,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "aborted", "results": {}, "start_time": "2021-10-12T08:24:05.965500+00:00", "last_update": "2021-10-12T08:24:10.599070+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -229,14 +271,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "aborted", "results": {}, "start_time": "2021-09-14T09:30:33.692216+00:00", "last_update": "2021-09-14T09:30:45.398626+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -265,14 +314,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { - "state": "pending", + "state": "pendingRetry", "results": {}, "start_time": "2021-09-13T12:37:39.890790+00:00", "last_update": "2021-09-13T12:37:47.341825+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -298,7 +354,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -306,7 +368,8 @@ "start_time": "2021-09-10T11:49:26.170358+00:00", "last_update": "2021-09-10T11:49:26.249424+00:00", "artifacts": [], - "error": "(422)\nReason: Unprocessable Entity\nHTTP response headers: HTTPHeaderDict({'Cache-Control': 'no-cache, private', 'Content-Type': 'application/json', 'Date': 'Fri, 10 Sep 2021 11:49:26 GMT', 'Content-Length': '974'})\nHTTP response body: {\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"Pod \\\"test-i-sz7vd\\\" is invalid: [spec.volumes[0].name: Invalid value: \\\"NAME\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?'), spec.containers[0].volumeMounts[0].name: Not found: \\\"NAME\\\"]\",\"reason\":\"Invalid\",\"details\":{\"name\":\"test-i-sz7vd\",\"kind\":\"Pod\",\"causes\":[{\"reason\":\"FieldValueInvalid\",\"message\":\"Invalid value: \\\"NAME\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')\",\"field\":\"spec.volumes[0].name\"},{\"reason\":\"FieldValueNotFound\",\"message\":\"Not found: \\\"NAME\\\"\",\"field\":\"spec.containers[0].volumeMounts[0].name\"}]},\"code\":422}\n\n" + "error": "(422)\nReason: Unprocessable Entity\nHTTP response headers: HTTPHeaderDict({'Cache-Control': 'no-cache, private', 'Content-Type': 'application/json', 'Date': 'Fri, 10 Sep 2021 11:49:26 GMT', 'Content-Length': '974'})\nHTTP response body: {\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"Pod \\\"test-i-sz7vd\\\" is invalid: [spec.volumes[0].name: Invalid value: \\\"NAME\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?'), spec.containers[0].volumeMounts[0].name: Not found: \\\"NAME\\\"]\",\"reason\":\"Invalid\",\"details\":{\"name\":\"test-i-sz7vd\",\"kind\":\"Pod\",\"causes\":[{\"reason\":\"FieldValueInvalid\",\"message\":\"Invalid value: \\\"NAME\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')\",\"field\":\"spec.volumes[0].name\"},{\"reason\":\"FieldValueNotFound\",\"message\":\"Not found: \\\"NAME\\\"\",\"field\":\"spec.containers[0].volumeMounts[0].name\"}]},\"code\":422}\n\n", + "retry_count": 1 } }, { @@ -332,7 +395,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -340,7 +409,8 @@ "start_time": "2021-09-10T11:46:36.715480+00:00", "last_update": "2021-09-10T11:46:36.768280+00:00", "artifacts": [], - "error": "(422)\nReason: Unprocessable Entity\nHTTP response headers: HTTPHeaderDict({'Cache-Control': 'no-cache, private', 'Content-Type': 'application/json', 'Date': 'Fri, 10 Sep 2021 11:46:36 GMT', 'Content-Length': '970'})\nHTTP response body: {\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"Pod \\\"fesf-frtb9\\\" is invalid: [spec.volumes[0].name: Invalid value: \\\"NAME\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?'), spec.containers[0].volumeMounts[0].name: Not found: \\\"NAME\\\"]\",\"reason\":\"Invalid\",\"details\":{\"name\":\"fesf-frtb9\",\"kind\":\"Pod\",\"causes\":[{\"reason\":\"FieldValueInvalid\",\"message\":\"Invalid value: \\\"NAME\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')\",\"field\":\"spec.volumes[0].name\"},{\"reason\":\"FieldValueNotFound\",\"message\":\"Not found: \\\"NAME\\\"\",\"field\":\"spec.containers[0].volumeMounts[0].name\"}]},\"code\":422}\n\n" + "error": "(422)\nReason: Unprocessable Entity\nHTTP response headers: HTTPHeaderDict({'Cache-Control': 'no-cache, private', 'Content-Type': 'application/json', 'Date': 'Fri, 10 Sep 2021 11:46:36 GMT', 'Content-Length': '970'})\nHTTP response body: {\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"Pod \\\"fesf-frtb9\\\" is invalid: [spec.volumes[0].name: Invalid value: \\\"NAME\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?'), spec.containers[0].volumeMounts[0].name: Not found: \\\"NAME\\\"]\",\"reason\":\"Invalid\",\"details\":{\"name\":\"fesf-frtb9\",\"kind\":\"Pod\",\"causes\":[{\"reason\":\"FieldValueInvalid\",\"message\":\"Invalid value: \\\"NAME\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')\",\"field\":\"spec.volumes[0].name\"},{\"reason\":\"FieldValueNotFound\",\"message\":\"Not found: \\\"NAME\\\"\",\"field\":\"spec.containers[0].volumeMounts[0].name\"}]},\"code\":422}\n\n", + "retry_count": 2 } }, { @@ -366,7 +436,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -374,7 +450,8 @@ "start_time": "2021-09-10T11:45:54.004341+00:00", "last_update": "2021-09-10T11:45:54.059573+00:00", "artifacts": [], - "error": "(422)\nReason: Unprocessable Entity\nHTTP response headers: HTTPHeaderDict({'Cache-Control': 'no-cache, private', 'Content-Type': 'application/json', 'Date': 'Fri, 10 Sep 2021 11:45:54 GMT', 'Content-Length': '970'})\nHTTP response body: {\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"Pod \\\"fesf-bk7xh\\\" is invalid: [spec.volumes[0].name: Invalid value: \\\"NAME\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?'), spec.containers[0].volumeMounts[0].name: Not found: \\\"NAME\\\"]\",\"reason\":\"Invalid\",\"details\":{\"name\":\"fesf-bk7xh\",\"kind\":\"Pod\",\"causes\":[{\"reason\":\"FieldValueInvalid\",\"message\":\"Invalid value: \\\"NAME\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')\",\"field\":\"spec.volumes[0].name\"},{\"reason\":\"FieldValueNotFound\",\"message\":\"Not found: \\\"NAME\\\"\",\"field\":\"spec.containers[0].volumeMounts[0].name\"}]},\"code\":422}\n\n" + "error": "(422)\nReason: Unprocessable Entity\nHTTP response headers: HTTPHeaderDict({'Cache-Control': 'no-cache, private', 'Content-Type': 'application/json', 'Date': 'Fri, 10 Sep 2021 11:45:54 GMT', 'Content-Length': '970'})\nHTTP response body: {\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"Pod \\\"fesf-bk7xh\\\" is invalid: [spec.volumes[0].name: Invalid value: \\\"NAME\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?'), spec.containers[0].volumeMounts[0].name: Not found: \\\"NAME\\\"]\",\"reason\":\"Invalid\",\"details\":{\"name\":\"fesf-bk7xh\",\"kind\":\"Pod\",\"causes\":[{\"reason\":\"FieldValueInvalid\",\"message\":\"Invalid value: \\\"NAME\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')\",\"field\":\"spec.volumes[0].name\"},{\"reason\":\"FieldValueNotFound\",\"message\":\"Not found: \\\"NAME\\\"\",\"field\":\"spec.containers[0].volumeMounts[0].name\"}]},\"code\":422}\n\n", + "retry_count": 2 } }, { @@ -400,7 +477,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -408,7 +491,49 @@ "start_time": "2021-09-10T11:45:44.673524+00:00", "last_update": "2021-09-10T11:45:44.804681+00:00", "artifacts": [], - "error": "handler sef not found in main.py" + "error": "handler sef not found in main.py", + "retry_count": 1 + } + }, + { + "kind": "run", + "metadata": { + "name": "fesf", + "uid": "c1a32f275eb743f781fd13d7a316a657", + "iteration": 0, + "project": "fsdemo-admin", + "labels": { + "v3io_user": "admin", + "owner": "admin", + "kind": "job" + }, + "annotations": {} + }, + "spec": { + "function": "fsdemo-admin/fesf@cfa663e14f1c7b71c7072afbc91827a23a86e964", + "log_level": "info", + "parameters": {}, + "outputs": [], + "output_path": "v3io:///projects/fsdemo-admin/artifacts/c1a32f275eb743f781fd13d7a316a657", + "inputs": {}, + "hyperparams": {}, + "hyper_param_options": {}, + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } + }, + "status": { + "state": "error", + "results": {}, + "start_time": "2021-09-10T11:46:36.715480+00:00", + "last_update": "2021-09-10T11:46:36.768280+00:00", + "artifacts": [], + "error": "(422)\nReason: Unprocessable Entity\nHTTP response headers: HTTPHeaderDict({'Cache-Control': 'no-cache, private', 'Content-Type': 'application/json', 'Date': 'Fri, 10 Sep 2021 11:46:36 GMT', 'Content-Length': '970'})\nHTTP response body: {\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"Pod \\\"fesf-frtb9\\\" is invalid: [spec.volumes[0].name: Invalid value: \\\"NAME\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?'), spec.containers[0].volumeMounts[0].name: Not found: \\\"NAME\\\"]\",\"reason\":\"Invalid\",\"details\":{\"name\":\"fesf-frtb9\",\"kind\":\"Pod\",\"causes\":[{\"reason\":\"FieldValueInvalid\",\"message\":\"Invalid value: \\\"NAME\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')\",\"field\":\"spec.volumes[0].name\"},{\"reason\":\"FieldValueNotFound\",\"message\":\"Not found: \\\"NAME\\\"\",\"field\":\"spec.containers[0].volumeMounts[0].name\"}]},\"code\":422}\n\n", + "retry_count": 0 } }, { @@ -434,7 +559,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -442,7 +573,8 @@ "start_time": "2021-09-10T11:44:47.606870+00:00", "last_update": "2021-09-10T11:44:47.678370+00:00", "artifacts": [], - "error": "(422)\nReason: Unprocessable Entity\nHTTP response headers: HTTPHeaderDict({'Cache-Control': 'no-cache, private', 'Content-Type': 'application/json', 'Date': 'Fri, 10 Sep 2021 11:44:47 GMT', 'Content-Length': '970'})\nHTTP response body: {\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"Pod \\\"test-6wpgq\\\" is invalid: [spec.volumes[0].name: Invalid value: \\\"NAME\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?'), spec.containers[0].volumeMounts[0].name: Not found: \\\"NAME\\\"]\",\"reason\":\"Invalid\",\"details\":{\"name\":\"test-6wpgq\",\"kind\":\"Pod\",\"causes\":[{\"reason\":\"FieldValueInvalid\",\"message\":\"Invalid value: \\\"NAME\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')\",\"field\":\"spec.volumes[0].name\"},{\"reason\":\"FieldValueNotFound\",\"message\":\"Not found: \\\"NAME\\\"\",\"field\":\"spec.containers[0].volumeMounts[0].name\"}]},\"code\":422}\n\n" + "error": "(422)\nReason: Unprocessable Entity\nHTTP response headers: HTTPHeaderDict({'Cache-Control': 'no-cache, private', 'Content-Type': 'application/json', 'Date': 'Fri, 10 Sep 2021 11:44:47 GMT', 'Content-Length': '970'})\nHTTP response body: {\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"Pod \\\"test-6wpgq\\\" is invalid: [spec.volumes[0].name: Invalid value: \\\"NAME\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?'), spec.containers[0].volumeMounts[0].name: Not found: \\\"NAME\\\"]\",\"reason\":\"Invalid\",\"details\":{\"name\":\"test-6wpgq\",\"kind\":\"Pod\",\"causes\":[{\"reason\":\"FieldValueInvalid\",\"message\":\"Invalid value: \\\"NAME\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')\",\"field\":\"spec.volumes[0].name\"},{\"reason\":\"FieldValueNotFound\",\"message\":\"Not found: \\\"NAME\\\"\",\"field\":\"spec.containers[0].volumeMounts[0].name\"}]},\"code\":422}\n\n", + "retry_count": 0 } }, { @@ -469,14 +601,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "running", "results": {}, "start_time": "2021-09-03T13:58:12.581215+00:00", "last_update": "2021-09-03T13:58:12.581220+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -503,14 +642,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "running", "results": {}, "start_time": "2021-09-03T13:58:01.150086+00:00", "last_update": "2021-09-03T13:58:01.150091+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -537,14 +683,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "running", "results": {}, "start_time": "2021-09-03T13:57:20.120500+00:00", "last_update": "2021-09-03T13:57:20.120505+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -571,14 +724,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "running", "results": {}, "start_time": "2021-09-03T13:51:21.205831+00:00", "last_update": "2021-09-03T13:51:21.205834+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -606,14 +766,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "running", "results": {}, "start_time": "2021-09-03T13:51:05.027342+00:00", "last_update": "2021-09-03T13:51:05.027349+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -647,7 +814,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -655,7 +828,8 @@ "start_time": "2021-09-03T13:50:59.748610+00:00", "last_update": "2021-09-03T13:50:59.909427+00:00", "error": "[Errno 2] No such file or directory: ''", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -683,14 +857,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "running", "results": {}, "start_time": "2021-09-03T13:50:01.211460+00:00", "last_update": "2021-09-03T13:50:01.211465+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -737,7 +918,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -745,7 +932,8 @@ "start_time": "2021-08-29T20:01:45.738537+00:00", "last_update": "2021-08-29T20:02:01.827946+00:00", "artifacts": [], - "error": "2021-08-29 20:01:36.582972: W tensorflow/stream_executor/platform/default/dso_loader.cc:60] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /usr/local/lib:/usr/local/lib:\n2021-08-29 20:01:36.583019: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.\n2021-08-29 20:01:46.470042: I tensorflow/compiler/jit/xla_cpu_device.cc:41] Not creating XLA devices, tf_xla_enable_xla_devices not set\n2021-08-29 20:01:46.470263: W tensorflow/stream_executor/platform/default/dso_loader.cc:60] Could not load dynamic library 'libcuda.so.1'; dlerror: libcuda.so.1: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /usr/local/lib:/usr/local/lib:\n2021-08-29 20:01:46.470283: W tensorflow/stream_executor/cuda/cuda_driver.cc:326] failed call to cuInit: UNKNOWN ERROR (303)\n2021-08-29 20:01:46.470306: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:156] kernel driver does not appear to be running on this host (train-1193bacd-worker-0): /proc/driver/nvidia/version does not exist\n2021-08-29 20:01:46.518782: I tensorflow/core/platform/cpu_feature_guard.cc:142] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX2 FMA\nTo enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.\n2021-08-29 20:01:46.518927: I tensorflow/compiler/jit/xla_gpu_device.cc:99] Not creating XLA devices, tf_xla_enable_xla_devices not set\nSome callbacks may not have access to the averaged metrics, see https://github.com/horovod/horovod/issues/2440\nTraceback (most recent call last):\n File \"/User/demos/image-classification-with-distributed-training/src-tfv2/horovod-training.py\", line 116, in \n hvd.callbacks.LearningRateWarmupCallback(warmup_epochs=5, verbose=1),\nTypeError: __init__() missing 1 required positional argument: 'initial_lr'\n" + "error": "2021-08-29 20:01:36.582972: W tensorflow/stream_executor/platform/default/dso_loader.cc:60] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /usr/local/lib:/usr/local/lib:\n2021-08-29 20:01:36.583019: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.\n2021-08-29 20:01:46.470042: I tensorflow/compiler/jit/xla_cpu_device.cc:41] Not creating XLA devices, tf_xla_enable_xla_devices not set\n2021-08-29 20:01:46.470263: W tensorflow/stream_executor/platform/default/dso_loader.cc:60] Could not load dynamic library 'libcuda.so.1'; dlerror: libcuda.so.1: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /usr/local/lib:/usr/local/lib:\n2021-08-29 20:01:46.470283: W tensorflow/stream_executor/cuda/cuda_driver.cc:326] failed call to cuInit: UNKNOWN ERROR (303)\n2021-08-29 20:01:46.470306: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:156] kernel driver does not appear to be running on this host (train-1193bacd-worker-0): /proc/driver/nvidia/version does not exist\n2021-08-29 20:01:46.518782: I tensorflow/core/platform/cpu_feature_guard.cc:142] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX2 FMA\nTo enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.\n2021-08-29 20:01:46.518927: I tensorflow/compiler/jit/xla_gpu_device.cc:99] Not creating XLA devices, tf_xla_enable_xla_devices not set\nSome callbacks may not have access to the averaged metrics, see https://github.com/horovod/horovod/issues/2440\nTraceback (most recent call last):\n File \"/User/demos/image-classification-with-distributed-training/src-tfv2/horovod-training.py\", line 116, in \n hvd.callbacks.LearningRateWarmupCallback(warmup_epochs=5, verbose=1),\nTypeError: __init__() missing 1 required positional argument: 'initial_lr'\n", + "retry_count": 1 } }, { @@ -781,7 +969,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -799,7 +993,8 @@ "uid": "20-0", "tag": "latest" } - ] + ], + "retry_count": 0 } }, { @@ -830,7 +1025,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -848,7 +1049,8 @@ "uid": "21-0", "tag": "latest" } - ] + ], + "retry_count": 2 } }, { @@ -900,7 +1102,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -1415,7 +1623,8 @@ "uid": "22-0", "tag": "latest" } - ] + ], + "retry_count": 2 } }, { @@ -1451,7 +1660,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -1459,7 +1674,8 @@ "start_time": "2021-11-09T15:39:58.595075+00:00", "last_update": "2021-11-09T15:39:58.910192+00:00", "error": "[Errno 2] No such file or directory: '/User/demos/customer-churn-prediction/data/pipeline/eaae138e-439a-47fa-93c6-ba0fe1dc3b79/tenured-test-set.csv'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -1487,14 +1703,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-11-09T15:39:25.398562+00:00", "last_update": "2021-11-09T15:39:25.473487+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -1530,7 +1753,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -1538,7 +1767,8 @@ "start_time": "2021-11-08T16:26:06.311262+00:00", "last_update": "2021-11-08T16:26:06.600147+00:00", "error": "[Errno 2] No such file or directory: '/User/demos/customer-churn-prediction/data/pipeline/eaae138e-439a-47fa-93c6-ba0fe1dc3b79/tenured-test-set.csv'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -1566,14 +1796,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-11-08T16:25:34.779339+00:00", "last_update": "2021-11-08T16:25:34.842229+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -1620,7 +1857,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -1628,7 +1871,8 @@ "start_time": "2021-11-08T16:25:23.418269+00:00", "last_update": "2021-11-08T16:25:23.647817+00:00", "error": "file type unhandled dataset", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -1676,7 +1920,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -1684,7 +1934,8 @@ "start_time": "2021-11-08T16:25:23.359533+00:00", "last_update": "2021-11-08T16:25:23.583287+00:00", "error": "'str' object has no attribute 'as_df'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -1722,7 +1973,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -1730,7 +1987,8 @@ "start_time": "2021-11-08T16:25:23.359185+00:00", "last_update": "2021-11-08T16:25:23.809551+00:00", "error": "file type unhandled test_set", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -1768,7 +2026,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -1776,7 +2040,8 @@ "start_time": "2021-11-08T16:25:23.359144+00:00", "last_update": "2021-11-08T16:25:23.584861+00:00", "error": "file type unhandled test_set", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -1814,7 +2079,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -1822,7 +2093,8 @@ "start_time": "2021-11-08T16:25:22.232499+00:00", "last_update": "2021-11-08T16:25:22.405691+00:00", "error": "file type unhandled src", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -1860,7 +2132,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -1868,7 +2146,8 @@ "start_time": "2021-11-08T16:25:20.324321+00:00", "last_update": "2021-11-08T16:25:20.517116+00:00", "error": "file type unhandled table", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -1896,14 +2175,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-11-08T16:25:16.966884+00:00", "last_update": "2021-11-08T16:25:17.038745+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -1932,7 +2218,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -1940,7 +2232,8 @@ "start_time": "2021-11-08T16:23:11.710713+00:00", "last_update": "2021-11-08T16:23:12.129908+00:00", "artifacts": [], - "error": ".run() can only be execute on \"mlrun\" kind, recreate with function kind \"mlrun\"" + "error": ".run() can only be execute on \"mlrun\" kind, recreate with function kind \"mlrun\"", + "retry_count": 0 } }, { @@ -1975,7 +2268,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -1983,7 +2282,8 @@ "start_time": "2021-09-16T08:00:05.727520+00:00", "last_update": "2021-09-16T08:00:06.112908+00:00", "error": "[Errno 2] No such file or directory: '/User/demos/customer-churn-prediction/data/pipeline/eaae138e-439a-47fa-93c6-ba0fe1dc3b79/test_set.csv'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -2040,7 +2340,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -2048,7 +2354,8 @@ "start_time": "2021-09-15T13:44:33.718770+00:00", "last_update": "2021-09-15T13:44:34.287133+00:00", "error": "file type unhandled v3io://test/test", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -2085,7 +2392,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -2093,7 +2406,8 @@ "start_time": "2021-09-03T14:02:21.992537+00:00", "last_update": "2021-09-03T14:02:22.143202+00:00", "error": "file type unhandled test_set", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -2130,7 +2444,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -2138,7 +2458,8 @@ "start_time": "2021-09-03T14:02:14.813451+00:00", "last_update": "2021-09-03T14:02:14.961434+00:00", "error": "file type unhandled test_set", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -2185,7 +2506,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -2193,7 +2520,8 @@ "start_time": "2021-09-03T14:02:06.911466+00:00", "last_update": "2021-09-03T14:02:07.047657+00:00", "error": "'str' object has no attribute 'as_df'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -2230,7 +2558,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -2238,7 +2572,8 @@ "start_time": "2021-09-03T14:01:57.400446+00:00", "last_update": "2021-09-03T14:01:57.593225+00:00", "error": "file type unhandled table", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -2284,7 +2619,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -2292,7 +2633,8 @@ "start_time": "2021-09-03T14:01:41.039404+00:00", "last_update": "2021-09-03T14:01:41.302859+00:00", "error": "file type unhandled dataset", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -2329,7 +2671,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -2337,7 +2685,8 @@ "start_time": "2021-09-03T14:01:25.207451+00:00", "last_update": "2021-09-03T14:01:25.372461+00:00", "error": "file type unhandled src", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -2384,7 +2733,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -2392,7 +2747,8 @@ "start_time": "2021-09-03T13:56:21.373049+00:00", "last_update": "2021-09-03T13:56:21.517709+00:00", "error": "'str' object has no attribute 'as_df'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -2429,7 +2785,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -2437,7 +2799,8 @@ "start_time": "2021-09-03T13:56:21.206337+00:00", "last_update": "2021-09-03T13:56:21.342459+00:00", "error": "file type unhandled test_set", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -2474,7 +2837,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -2482,7 +2851,8 @@ "start_time": "2021-09-03T13:56:19.700627+00:00", "last_update": "2021-09-03T13:56:19.856594+00:00", "error": "file type unhandled test_set", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -2528,7 +2898,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -2536,7 +2912,8 @@ "start_time": "2021-09-03T13:56:19.515710+00:00", "last_update": "2021-09-03T13:56:19.665883+00:00", "error": "file type unhandled dataset", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -2573,7 +2950,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -2581,7 +2964,8 @@ "start_time": "2021-09-03T13:56:16.478536+00:00", "last_update": "2021-09-03T13:56:16.600809+00:00", "error": "file type unhandled src", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -2618,7 +3002,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -2626,7 +3016,8 @@ "start_time": "2021-09-03T13:55:42.511622+00:00", "last_update": "2021-09-03T13:55:42.712944+00:00", "error": "file type unhandled table", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -2663,7 +3054,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -2754,7 +3151,8 @@ "uid": "49-4", "tag": "latest" } - ] + ], + "retry_count": 2 } }, { @@ -2791,7 +3189,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -3615,7 +4019,8 @@ "uid": "50-0", "tag": "latest" } - ] + ], + "retry_count": 1 } }, { @@ -3678,7 +4083,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -5847,7 +6258,8 @@ "uid": "51-6", "tag": "latest" } - ] + ], + "retry_count": 2 } }, { @@ -5882,7 +6294,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -6007,7 +6425,8 @@ "uid": "52-5", "tag": "latest" } - ] + ], + "retry_count": 2 } }, { @@ -6058,7 +6477,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -9587,7 +10012,8 @@ "uid": "53-5", "tag": "latest" } - ] + ], + "retry_count": 0 } }, { @@ -9625,7 +10051,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -12235,7 +12667,8 @@ "uid": "54-4", "tag": "latest" } - ] + ], + "retry_count": 2 } }, { @@ -12267,7 +12700,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -14877,7 +15316,8 @@ "uid": "55-4", "tag": "latest" } - ] + ], + "retry_count": 0 } }, { @@ -14922,7 +15362,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -14930,7 +15376,8 @@ "start_time": "2021-11-25T15:20:04.626994+00:00", "last_update": "2021-11-25T15:20:04.869705+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -14975,7 +15422,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -14983,7 +15436,8 @@ "start_time": "2021-11-25T15:10:04.547356+00:00", "last_update": "2021-11-25T15:10:04.740772+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -15028,7 +15482,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -15036,7 +15496,8 @@ "start_time": "2021-11-25T15:00:04.530198+00:00", "last_update": "2021-11-25T15:00:04.778945+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -15081,7 +15542,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -15089,7 +15556,8 @@ "start_time": "2021-11-25T14:50:04.689049+00:00", "last_update": "2021-11-25T14:50:04.876507+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -15134,7 +15602,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -15142,7 +15616,8 @@ "start_time": "2021-11-25T14:40:04.591290+00:00", "last_update": "2021-11-25T14:40:04.779383+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -15187,7 +15662,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -15195,7 +15676,8 @@ "start_time": "2021-11-25T14:30:04.478111+00:00", "last_update": "2021-11-25T14:30:04.671986+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -15240,7 +15722,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -15248,7 +15736,8 @@ "start_time": "2021-11-25T14:20:04.413115+00:00", "last_update": "2021-11-25T14:20:04.602205+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -15293,7 +15782,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -15301,7 +15796,8 @@ "start_time": "2021-11-25T14:10:04.748113+00:00", "last_update": "2021-11-25T14:10:04.936987+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -15346,7 +15842,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -15354,7 +15856,8 @@ "start_time": "2021-11-25T14:00:04.499287+00:00", "last_update": "2021-11-25T14:00:04.748608+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -15399,7 +15902,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -15407,7 +15916,8 @@ "start_time": "2021-11-25T13:50:04.460226+00:00", "last_update": "2021-11-25T13:50:04.663531+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -15452,7 +15962,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -15460,7 +15976,8 @@ "start_time": "2021-11-25T13:40:04.616903+00:00", "last_update": "2021-11-25T13:40:05.070431+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -15505,7 +16022,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -15513,7 +16036,8 @@ "start_time": "2021-11-25T13:30:04.482084+00:00", "last_update": "2021-11-25T13:30:04.682436+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -15558,7 +16082,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -15566,7 +16096,8 @@ "start_time": "2021-11-25T13:20:04.619182+00:00", "last_update": "2021-11-25T13:20:04.821367+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -15611,7 +16142,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -15619,7 +16156,8 @@ "start_time": "2021-11-25T13:10:04.530025+00:00", "last_update": "2021-11-25T13:10:04.725068+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -15664,7 +16202,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -15672,7 +16216,8 @@ "start_time": "2021-11-25T13:00:04.554031+00:00", "last_update": "2021-11-25T13:00:04.800899+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -15717,7 +16262,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -15725,7 +16276,8 @@ "start_time": "2021-11-25T12:50:04.498226+00:00", "last_update": "2021-11-25T12:50:04.692993+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -15770,7 +16322,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -15778,7 +16336,8 @@ "start_time": "2021-11-25T12:40:04.664771+00:00", "last_update": "2021-11-25T12:40:04.859887+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -15823,7 +16382,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -15831,7 +16396,8 @@ "start_time": "2021-11-25T12:30:04.506004+00:00", "last_update": "2021-11-25T12:30:04.697277+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -15876,7 +16442,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -15884,7 +16456,8 @@ "start_time": "2021-11-25T12:20:04.678686+00:00", "last_update": "2021-11-25T12:20:04.872209+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -15929,7 +16502,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -15937,7 +16516,8 @@ "start_time": "2021-11-25T12:10:04.672087+00:00", "last_update": "2021-11-25T12:10:04.889989+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -15982,7 +16562,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -15990,7 +16576,8 @@ "start_time": "2021-11-25T12:00:04.755738+00:00", "last_update": "2021-11-25T12:00:05.093911+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -16035,7 +16622,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -16043,7 +16636,8 @@ "start_time": "2021-11-25T11:50:04.480850+00:00", "last_update": "2021-11-25T11:50:04.677429+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -16088,7 +16682,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -16096,7 +16696,8 @@ "start_time": "2021-11-25T11:40:04.602256+00:00", "last_update": "2021-11-25T11:40:04.850283+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -16141,7 +16742,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -16149,7 +16756,8 @@ "start_time": "2021-11-25T11:30:04.426377+00:00", "last_update": "2021-11-25T11:30:04.636503+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -16194,7 +16802,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -16202,7 +16816,8 @@ "start_time": "2021-11-25T11:20:04.516140+00:00", "last_update": "2021-11-25T11:20:04.735509+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -16247,7 +16862,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -16255,7 +16876,8 @@ "start_time": "2021-11-25T11:10:04.472037+00:00", "last_update": "2021-11-25T11:10:04.664942+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -16300,7 +16922,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -16308,7 +16936,8 @@ "start_time": "2021-11-25T11:00:04.657896+00:00", "last_update": "2021-11-25T11:00:04.883672+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -16353,7 +16982,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -16361,7 +16996,8 @@ "start_time": "2021-11-25T10:50:04.647522+00:00", "last_update": "2021-11-25T10:50:04.836197+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -16406,7 +17042,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -16414,7 +17056,8 @@ "start_time": "2021-11-25T10:40:04.569781+00:00", "last_update": "2021-11-25T10:40:04.770749+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -16459,7 +17102,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -16467,7 +17116,8 @@ "start_time": "2021-11-25T10:30:04.676500+00:00", "last_update": "2021-11-25T10:30:04.860678+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -16512,7 +17162,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -16520,7 +17176,8 @@ "start_time": "2021-11-25T10:20:04.709992+00:00", "last_update": "2021-11-25T10:20:04.906660+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -16565,7 +17222,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -16573,7 +17236,8 @@ "start_time": "2021-11-25T10:10:04.654881+00:00", "last_update": "2021-11-25T10:10:04.877279+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -16618,7 +17282,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -16626,7 +17296,8 @@ "start_time": "2021-11-25T10:00:04.655647+00:00", "last_update": "2021-11-25T10:00:04.922516+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -16671,7 +17342,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -16679,7 +17356,8 @@ "start_time": "2021-11-25T09:50:05.301473+00:00", "last_update": "2021-11-25T09:50:05.506318+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -16724,7 +17402,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -16732,7 +17416,8 @@ "start_time": "2021-11-25T09:40:04.688485+00:00", "last_update": "2021-11-25T09:40:04.885575+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -16777,7 +17462,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -16785,7 +17476,8 @@ "start_time": "2021-11-25T09:30:04.526432+00:00", "last_update": "2021-11-25T09:30:04.714181+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -16830,7 +17522,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -16838,7 +17536,8 @@ "start_time": "2021-11-25T09:20:04.628475+00:00", "last_update": "2021-11-25T09:20:04.872881+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -16883,7 +17582,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -16891,7 +17596,8 @@ "start_time": "2021-11-25T09:10:04.450469+00:00", "last_update": "2021-11-25T09:10:04.777839+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -16936,7 +17642,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -16944,7 +17656,8 @@ "start_time": "2021-11-25T09:00:04.766381+00:00", "last_update": "2021-11-25T09:00:05.025565+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -16989,7 +17702,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -16997,7 +17716,8 @@ "start_time": "2021-11-25T08:50:04.418181+00:00", "last_update": "2021-11-25T08:50:04.595812+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -17042,7 +17762,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -17050,7 +17776,8 @@ "start_time": "2021-11-25T08:40:04.569381+00:00", "last_update": "2021-11-25T08:40:04.759896+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -17095,7 +17822,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -17103,7 +17836,8 @@ "start_time": "2021-11-25T08:30:04.600599+00:00", "last_update": "2021-11-25T08:30:04.848873+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -17148,7 +17882,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -17156,7 +17896,8 @@ "start_time": "2021-11-25T08:20:04.519720+00:00", "last_update": "2021-11-25T08:20:04.819565+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -17201,7 +17942,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -17209,7 +17956,8 @@ "start_time": "2021-11-25T08:10:04.578285+00:00", "last_update": "2021-11-25T08:10:04.758011+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -17254,7 +18002,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -17262,7 +18016,8 @@ "start_time": "2021-11-25T08:00:04.433436+00:00", "last_update": "2021-11-25T08:00:04.694042+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -17307,7 +18062,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -17315,7 +18076,8 @@ "start_time": "2021-11-25T07:50:04.643860+00:00", "last_update": "2021-11-25T07:50:04.894175+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -17360,7 +18122,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -17368,7 +18136,8 @@ "start_time": "2021-11-25T07:40:04.621111+00:00", "last_update": "2021-11-25T07:40:04.847086+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -17413,7 +18182,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -17421,7 +18196,8 @@ "start_time": "2021-11-25T07:30:04.433519+00:00", "last_update": "2021-11-25T07:30:04.623295+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -17466,7 +18242,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -17474,7 +18256,8 @@ "start_time": "2021-11-25T07:20:04.851092+00:00", "last_update": "2021-11-25T07:20:05.072058+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -17519,7 +18302,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -17527,7 +18316,8 @@ "start_time": "2021-11-25T07:10:04.701725+00:00", "last_update": "2021-11-25T07:10:04.891876+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -17572,7 +18362,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -17580,7 +18376,8 @@ "start_time": "2021-11-25T07:00:04.730707+00:00", "last_update": "2021-11-25T07:00:04.959567+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -17625,7 +18422,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -17633,7 +18436,8 @@ "start_time": "2021-11-25T06:50:04.389233+00:00", "last_update": "2021-11-25T06:50:04.570853+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -17678,7 +18482,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -17686,7 +18496,8 @@ "start_time": "2021-11-25T06:40:04.779848+00:00", "last_update": "2021-11-25T06:40:04.993553+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -17731,7 +18542,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -17739,7 +18556,8 @@ "start_time": "2021-11-25T06:30:04.427263+00:00", "last_update": "2021-11-25T06:30:04.614687+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -17784,7 +18602,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -17792,7 +18616,8 @@ "start_time": "2021-11-25T06:20:04.434939+00:00", "last_update": "2021-11-25T06:20:04.618174+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -17837,7 +18662,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -17845,7 +18676,8 @@ "start_time": "2021-11-25T06:10:04.633692+00:00", "last_update": "2021-11-25T06:10:04.845108+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -17890,7 +18722,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -17898,7 +18736,8 @@ "start_time": "2021-11-25T06:00:04.609640+00:00", "last_update": "2021-11-25T06:00:04.912946+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -17943,7 +18782,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -17951,7 +18796,8 @@ "start_time": "2021-11-25T05:50:04.449949+00:00", "last_update": "2021-11-25T05:50:04.635722+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -17996,7 +18842,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -18004,7 +18856,8 @@ "start_time": "2021-11-25T05:40:04.515533+00:00", "last_update": "2021-11-25T05:40:04.736425+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -18049,7 +18902,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -18057,7 +18916,8 @@ "start_time": "2021-11-25T05:30:04.577631+00:00", "last_update": "2021-11-25T05:30:04.863501+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -18102,7 +18962,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -18110,7 +18976,8 @@ "start_time": "2021-11-25T05:20:04.455804+00:00", "last_update": "2021-11-25T05:20:04.634993+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -18155,7 +19022,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -18163,7 +19036,8 @@ "start_time": "2021-11-25T05:10:04.414843+00:00", "last_update": "2021-11-25T05:10:04.629374+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -18208,7 +19082,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -18216,7 +19096,8 @@ "start_time": "2021-11-25T05:00:04.813068+00:00", "last_update": "2021-11-25T05:00:05.113562+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -18261,7 +19142,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -18269,7 +19156,8 @@ "start_time": "2021-11-25T04:50:04.587135+00:00", "last_update": "2021-11-25T04:50:04.779001+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -18314,7 +19202,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -18322,7 +19216,8 @@ "start_time": "2021-11-25T04:40:04.432340+00:00", "last_update": "2021-11-25T04:40:04.693033+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -18367,7 +19262,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -18375,7 +19276,8 @@ "start_time": "2021-11-25T04:30:04.785460+00:00", "last_update": "2021-11-25T04:30:04.974252+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -18420,7 +19322,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -18428,7 +19336,8 @@ "start_time": "2021-11-25T04:20:04.487176+00:00", "last_update": "2021-11-25T04:20:04.689088+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -18473,7 +19382,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -18481,7 +19396,8 @@ "start_time": "2021-11-25T04:10:04.525230+00:00", "last_update": "2021-11-25T04:10:04.804950+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -18526,7 +19442,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -18534,7 +19456,8 @@ "start_time": "2021-11-25T04:00:04.434934+00:00", "last_update": "2021-11-25T04:00:04.684001+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -18579,7 +19502,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -18587,7 +19516,8 @@ "start_time": "2021-11-25T03:50:04.404080+00:00", "last_update": "2021-11-25T03:50:04.721225+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -18632,7 +19562,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -18640,7 +19576,8 @@ "start_time": "2021-11-25T03:40:04.494475+00:00", "last_update": "2021-11-25T03:40:04.780123+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -18685,7 +19622,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -18693,7 +19636,8 @@ "start_time": "2021-11-25T03:30:04.696343+00:00", "last_update": "2021-11-25T03:30:04.898417+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -18738,7 +19682,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -18746,7 +19696,8 @@ "start_time": "2021-11-25T03:20:04.805759+00:00", "last_update": "2021-11-25T03:20:04.984463+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -18791,7 +19742,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -18799,7 +19756,8 @@ "start_time": "2021-11-25T03:10:04.538969+00:00", "last_update": "2021-11-25T03:10:04.807798+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -18844,7 +19802,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -18852,7 +19816,8 @@ "start_time": "2021-11-25T03:00:04.573902+00:00", "last_update": "2021-11-25T03:00:04.835497+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -18897,7 +19862,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -18905,7 +19876,8 @@ "start_time": "2021-11-25T02:50:04.776007+00:00", "last_update": "2021-11-25T02:50:04.956215+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -18950,7 +19922,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -18958,7 +19936,8 @@ "start_time": "2021-11-25T02:40:04.477586+00:00", "last_update": "2021-11-25T02:40:04.665052+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -19003,7 +19982,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -19011,7 +19996,8 @@ "start_time": "2021-11-25T02:30:04.474322+00:00", "last_update": "2021-11-25T02:30:04.663125+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -19056,7 +20042,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -19064,7 +20056,8 @@ "start_time": "2021-11-25T02:20:04.518030+00:00", "last_update": "2021-11-25T02:20:04.854487+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -19109,7 +20102,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -19117,7 +20116,8 @@ "start_time": "2021-11-25T02:10:04.644281+00:00", "last_update": "2021-11-25T02:10:04.827435+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -19162,7 +20162,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -19170,7 +20176,8 @@ "start_time": "2021-11-25T02:00:04.631916+00:00", "last_update": "2021-11-25T02:00:04.879130+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -19215,7 +20222,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -19223,7 +20236,8 @@ "start_time": "2021-11-25T01:50:04.616606+00:00", "last_update": "2021-11-25T01:50:04.799437+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -19268,7 +20282,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -19276,7 +20296,8 @@ "start_time": "2021-11-25T01:40:04.559437+00:00", "last_update": "2021-11-25T01:40:04.750553+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -19321,7 +20342,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -19329,7 +20356,8 @@ "start_time": "2021-11-25T01:30:04.941823+00:00", "last_update": "2021-11-25T01:30:05.134506+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -19374,7 +20402,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -19382,7 +20416,8 @@ "start_time": "2021-11-25T01:20:04.596188+00:00", "last_update": "2021-11-25T01:20:04.782960+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -19427,7 +20462,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -19435,7 +20476,8 @@ "start_time": "2021-11-25T01:10:04.491352+00:00", "last_update": "2021-11-25T01:10:04.667277+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -19480,7 +20522,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -19488,7 +20536,8 @@ "start_time": "2021-11-25T01:00:04.644596+00:00", "last_update": "2021-11-25T01:00:04.873300+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -19533,7 +20582,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -19541,7 +20596,8 @@ "start_time": "2021-11-25T00:50:04.982616+00:00", "last_update": "2021-11-25T00:50:05.168071+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -19586,7 +20642,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -19594,7 +20656,8 @@ "start_time": "2021-11-25T00:40:04.603050+00:00", "last_update": "2021-11-25T00:40:04.891375+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -19639,7 +20702,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -19647,7 +20716,8 @@ "start_time": "2021-11-25T00:30:04.551138+00:00", "last_update": "2021-11-25T00:30:04.740014+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -19692,7 +20762,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -19700,7 +20776,8 @@ "start_time": "2021-11-25T00:20:04.463810+00:00", "last_update": "2021-11-25T00:20:04.814736+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -19745,7 +20822,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -19753,7 +20836,8 @@ "start_time": "2021-11-25T00:10:04.738628+00:00", "last_update": "2021-11-25T00:10:05.017899+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -19798,7 +20882,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -19806,7 +20896,8 @@ "start_time": "2021-11-25T00:00:04.544586+00:00", "last_update": "2021-11-25T00:00:05.005375+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -19851,7 +20942,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -19859,7 +20956,8 @@ "start_time": "2021-11-24T23:50:04.516034+00:00", "last_update": "2021-11-24T23:50:04.708996+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -19904,7 +21002,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -19912,7 +21016,8 @@ "start_time": "2021-11-24T23:40:04.527184+00:00", "last_update": "2021-11-24T23:40:04.794158+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -19957,7 +21062,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -19965,7 +21076,8 @@ "start_time": "2021-11-24T23:30:04.532170+00:00", "last_update": "2021-11-24T23:30:04.726453+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -20010,7 +21122,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -20018,7 +21136,8 @@ "start_time": "2021-11-24T23:20:04.469606+00:00", "last_update": "2021-11-24T23:20:04.756696+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -20063,7 +21182,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -20071,7 +21196,8 @@ "start_time": "2021-11-24T23:10:04.438960+00:00", "last_update": "2021-11-24T23:10:04.654338+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -20116,7 +21242,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -20124,7 +21256,8 @@ "start_time": "2021-11-24T23:00:04.699017+00:00", "last_update": "2021-11-24T23:00:05.044694+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -20169,7 +21302,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -20177,7 +21316,8 @@ "start_time": "2021-11-24T22:50:04.479638+00:00", "last_update": "2021-11-24T22:50:04.668838+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -20222,7 +21362,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -20230,7 +21376,8 @@ "start_time": "2021-11-24T22:40:04.504226+00:00", "last_update": "2021-11-24T22:40:04.695845+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -20275,7 +21422,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -20283,7 +21436,8 @@ "start_time": "2021-11-24T22:30:04.458818+00:00", "last_update": "2021-11-24T22:30:04.711903+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -20328,7 +21482,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -20336,7 +21496,8 @@ "start_time": "2021-11-24T22:20:04.418897+00:00", "last_update": "2021-11-24T22:20:04.607711+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -20381,7 +21542,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -20389,7 +21556,8 @@ "start_time": "2021-11-24T22:10:04.538668+00:00", "last_update": "2021-11-24T22:10:04.734232+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -20434,7 +21602,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -20442,7 +21616,8 @@ "start_time": "2021-11-24T22:00:04.539921+00:00", "last_update": "2021-11-24T22:00:04.781730+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -20487,7 +21662,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -20495,7 +21676,8 @@ "start_time": "2021-11-24T21:50:04.510394+00:00", "last_update": "2021-11-24T21:50:04.691104+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -20540,7 +21722,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -20548,7 +21736,8 @@ "start_time": "2021-11-24T21:40:04.550718+00:00", "last_update": "2021-11-24T21:40:04.749227+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -20593,7 +21782,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -20601,7 +21796,8 @@ "start_time": "2021-11-24T21:30:04.409693+00:00", "last_update": "2021-11-24T21:30:04.598307+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -20646,7 +21842,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -20654,7 +21856,8 @@ "start_time": "2021-11-24T21:20:04.621030+00:00", "last_update": "2021-11-24T21:20:04.810078+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -20699,7 +21902,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -20707,7 +21916,8 @@ "start_time": "2021-11-24T21:10:04.375332+00:00", "last_update": "2021-11-24T21:10:04.626326+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -20752,7 +21962,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -20760,7 +21976,8 @@ "start_time": "2021-11-24T21:00:04.870989+00:00", "last_update": "2021-11-24T21:00:05.112089+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -20805,7 +22022,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -20813,7 +22036,8 @@ "start_time": "2021-11-24T20:50:04.507278+00:00", "last_update": "2021-11-24T20:50:04.686896+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -20858,7 +22082,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -20866,7 +22096,8 @@ "start_time": "2021-11-24T20:40:04.546515+00:00", "last_update": "2021-11-24T20:40:04.731933+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -20911,7 +22142,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -20919,7 +22156,8 @@ "start_time": "2021-11-24T20:30:04.298374+00:00", "last_update": "2021-11-24T20:30:04.511135+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -20964,7 +22202,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -20972,7 +22216,8 @@ "start_time": "2021-11-24T20:20:04.870619+00:00", "last_update": "2021-11-24T20:20:05.159143+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -21017,7 +22262,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -21025,7 +22276,8 @@ "start_time": "2021-11-24T20:10:04.611475+00:00", "last_update": "2021-11-24T20:10:04.839482+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -21070,7 +22322,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -21078,7 +22336,8 @@ "start_time": "2021-11-24T20:00:04.475649+00:00", "last_update": "2021-11-24T20:00:04.795051+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -21123,7 +22382,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -21131,7 +22396,8 @@ "start_time": "2021-11-24T19:50:04.568253+00:00", "last_update": "2021-11-24T19:50:04.759309+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -21176,7 +22442,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -21184,7 +22456,8 @@ "start_time": "2021-11-24T19:40:04.520061+00:00", "last_update": "2021-11-24T19:40:04.722499+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -21229,7 +22502,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -21237,7 +22516,8 @@ "start_time": "2021-11-24T19:30:04.429974+00:00", "last_update": "2021-11-24T19:30:04.643339+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -21282,7 +22562,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -21290,7 +22576,8 @@ "start_time": "2021-11-24T19:20:04.682369+00:00", "last_update": "2021-11-24T19:20:04.987412+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -21335,7 +22622,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -21343,7 +22636,8 @@ "start_time": "2021-11-24T19:10:04.798406+00:00", "last_update": "2021-11-24T19:10:04.987420+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -21388,7 +22682,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -21396,7 +22696,8 @@ "start_time": "2021-11-24T19:00:04.611443+00:00", "last_update": "2021-11-24T19:00:04.904232+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -21441,7 +22742,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -21449,7 +22756,8 @@ "start_time": "2021-11-24T18:50:04.615771+00:00", "last_update": "2021-11-24T18:50:04.798803+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -21494,7 +22802,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -21502,7 +22816,8 @@ "start_time": "2021-11-24T18:40:04.599586+00:00", "last_update": "2021-11-24T18:40:04.795373+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -21547,7 +22862,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -21555,7 +22876,8 @@ "start_time": "2021-11-24T18:30:04.433271+00:00", "last_update": "2021-11-24T18:30:04.641423+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -21600,7 +22922,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -21608,7 +22936,8 @@ "start_time": "2021-11-24T18:20:04.349454+00:00", "last_update": "2021-11-24T18:20:04.527202+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -21653,7 +22982,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -21661,7 +22996,8 @@ "start_time": "2021-11-24T18:10:04.801067+00:00", "last_update": "2021-11-24T18:10:05.109504+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -21706,7 +23042,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -21714,7 +23056,8 @@ "start_time": "2021-11-24T18:00:04.470012+00:00", "last_update": "2021-11-24T18:00:04.699333+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -21759,7 +23102,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -21767,7 +23116,8 @@ "start_time": "2021-11-24T17:50:04.767415+00:00", "last_update": "2021-11-24T17:50:04.958676+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -21812,7 +23162,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -21820,7 +23176,8 @@ "start_time": "2021-11-24T17:40:04.565225+00:00", "last_update": "2021-11-24T17:40:04.758722+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -21865,7 +23222,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -21873,7 +23236,8 @@ "start_time": "2021-11-24T17:30:04.542465+00:00", "last_update": "2021-11-24T17:30:04.726922+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -21918,7 +23282,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -21926,7 +23296,8 @@ "start_time": "2021-11-24T17:20:04.558157+00:00", "last_update": "2021-11-24T17:20:04.747969+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -21971,7 +23342,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -21979,7 +23356,8 @@ "start_time": "2021-11-24T17:10:04.510999+00:00", "last_update": "2021-11-24T17:10:04.741880+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -22024,7 +23402,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -22032,7 +23416,8 @@ "start_time": "2021-11-24T17:00:04.637790+00:00", "last_update": "2021-11-24T17:00:04.914986+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -22077,7 +23462,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -22085,7 +23476,8 @@ "start_time": "2021-11-24T16:50:04.532151+00:00", "last_update": "2021-11-24T16:50:04.707283+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -22130,7 +23522,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -22138,7 +23536,8 @@ "start_time": "2021-11-24T16:40:04.654448+00:00", "last_update": "2021-11-24T16:40:04.857622+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -22183,7 +23582,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -22191,7 +23596,8 @@ "start_time": "2021-11-24T16:30:04.726833+00:00", "last_update": "2021-11-24T16:30:04.915715+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -22236,7 +23642,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -22244,7 +23656,8 @@ "start_time": "2021-11-24T16:20:04.765431+00:00", "last_update": "2021-11-24T16:20:04.995627+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -22289,7 +23702,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -22297,7 +23716,8 @@ "start_time": "2021-11-24T16:10:04.475159+00:00", "last_update": "2021-11-24T16:10:04.707052+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -22342,7 +23762,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -22350,7 +23776,8 @@ "start_time": "2021-11-24T16:00:04.513842+00:00", "last_update": "2021-11-24T16:00:04.798010+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -22395,7 +23822,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -22403,7 +23836,8 @@ "start_time": "2021-11-24T15:50:04.436252+00:00", "last_update": "2021-11-24T15:50:04.625205+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -22448,7 +23882,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -22456,7 +23896,8 @@ "start_time": "2021-11-24T15:40:04.481903+00:00", "last_update": "2021-11-24T15:40:04.663438+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -22501,7 +23942,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -22509,7 +23956,8 @@ "start_time": "2021-11-24T15:30:04.446758+00:00", "last_update": "2021-11-24T15:30:04.620499+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -22554,7 +24002,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -22562,7 +24016,8 @@ "start_time": "2021-11-24T15:20:04.612123+00:00", "last_update": "2021-11-24T15:20:04.796937+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -22607,7 +24062,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -22615,7 +24076,8 @@ "start_time": "2021-11-24T15:10:04.476532+00:00", "last_update": "2021-11-24T15:10:04.690365+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -22660,7 +24122,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -22668,7 +24136,8 @@ "start_time": "2021-11-24T15:00:04.661578+00:00", "last_update": "2021-11-24T15:00:04.888075+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -22713,7 +24182,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -22721,7 +24196,8 @@ "start_time": "2021-11-24T14:50:04.475653+00:00", "last_update": "2021-11-24T14:50:04.661629+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -22766,7 +24242,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -22774,7 +24256,8 @@ "start_time": "2021-11-24T14:40:04.698078+00:00", "last_update": "2021-11-24T14:40:04.874743+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -22819,7 +24302,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -22827,7 +24316,8 @@ "start_time": "2021-11-24T14:30:04.539611+00:00", "last_update": "2021-11-24T14:30:04.795622+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -22872,7 +24362,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -22880,7 +24376,8 @@ "start_time": "2021-11-24T14:20:04.446140+00:00", "last_update": "2021-11-24T14:20:04.626509+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -22925,7 +24422,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -22933,7 +24436,8 @@ "start_time": "2021-11-24T14:10:04.852408+00:00", "last_update": "2021-11-24T14:10:05.035730+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -22978,7 +24482,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -22986,7 +24496,8 @@ "start_time": "2021-11-24T14:00:04.645034+00:00", "last_update": "2021-11-24T14:00:04.878150+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -23031,7 +24542,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -23039,7 +24556,8 @@ "start_time": "2021-11-24T13:50:04.477657+00:00", "last_update": "2021-11-24T13:50:04.662831+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -23084,7 +24602,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -23092,7 +24616,8 @@ "start_time": "2021-11-24T13:40:04.670473+00:00", "last_update": "2021-11-24T13:40:04.861574+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -23137,7 +24662,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -23145,7 +24676,8 @@ "start_time": "2021-11-24T13:30:04.495716+00:00", "last_update": "2021-11-24T13:30:04.694276+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -23190,7 +24722,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -23198,7 +24736,8 @@ "start_time": "2021-11-24T13:20:04.449564+00:00", "last_update": "2021-11-24T13:20:04.665086+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -23243,7 +24782,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -23251,7 +24796,8 @@ "start_time": "2021-11-24T13:10:04.511729+00:00", "last_update": "2021-11-24T13:10:04.694280+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -23296,7 +24842,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -23304,7 +24856,8 @@ "start_time": "2021-11-24T13:00:04.465753+00:00", "last_update": "2021-11-24T13:00:04.702928+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -23349,7 +24902,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -23357,7 +24916,8 @@ "start_time": "2021-11-24T12:50:04.505712+00:00", "last_update": "2021-11-24T12:50:04.716717+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -23402,7 +24962,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -23410,7 +24976,8 @@ "start_time": "2021-11-24T12:40:04.529680+00:00", "last_update": "2021-11-24T12:40:04.723592+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -23455,7 +25022,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -23463,7 +25036,8 @@ "start_time": "2021-11-24T12:30:04.591878+00:00", "last_update": "2021-11-24T12:30:04.767677+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -23508,7 +25082,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -23516,7 +25096,8 @@ "start_time": "2021-11-24T12:20:04.506881+00:00", "last_update": "2021-11-24T12:20:04.707187+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -23561,7 +25142,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -23569,7 +25156,8 @@ "start_time": "2021-11-24T12:10:04.455195+00:00", "last_update": "2021-11-24T12:10:04.662142+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -23614,7 +25202,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -23622,7 +25216,8 @@ "start_time": "2021-11-24T12:00:04.474861+00:00", "last_update": "2021-11-24T12:00:04.712058+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -23667,7 +25262,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -23675,7 +25276,8 @@ "start_time": "2021-11-24T11:50:04.465545+00:00", "last_update": "2021-11-24T11:50:04.643853+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -23720,7 +25322,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -23728,7 +25336,8 @@ "start_time": "2021-11-24T11:40:04.518707+00:00", "last_update": "2021-11-24T11:40:04.714892+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -23773,7 +25382,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -23781,7 +25396,8 @@ "start_time": "2021-11-24T11:30:04.439386+00:00", "last_update": "2021-11-24T11:30:04.606311+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -23826,7 +25442,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -23834,7 +25456,8 @@ "start_time": "2021-11-24T11:20:04.553954+00:00", "last_update": "2021-11-24T11:20:04.741887+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -23879,7 +25502,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -23887,7 +25516,8 @@ "start_time": "2021-11-24T11:10:04.512320+00:00", "last_update": "2021-11-24T11:10:04.692293+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -23932,7 +25562,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -23940,7 +25576,8 @@ "start_time": "2021-11-24T11:00:04.783589+00:00", "last_update": "2021-11-24T11:00:05.027705+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -23985,7 +25622,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -23993,7 +25636,8 @@ "start_time": "2021-11-24T10:50:04.460250+00:00", "last_update": "2021-11-24T10:50:04.637607+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -24038,7 +25682,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -24046,7 +25696,8 @@ "start_time": "2021-11-24T10:40:04.872549+00:00", "last_update": "2021-11-24T10:40:05.055488+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -24091,7 +25742,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -24099,7 +25756,8 @@ "start_time": "2021-11-24T10:30:04.447723+00:00", "last_update": "2021-11-24T10:30:04.657345+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -24144,7 +25802,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -24152,7 +25816,8 @@ "start_time": "2021-11-24T10:20:04.460217+00:00", "last_update": "2021-11-24T10:20:04.672371+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -24197,7 +25862,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -24205,7 +25876,8 @@ "start_time": "2021-11-24T10:10:04.461257+00:00", "last_update": "2021-11-24T10:10:04.644618+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -24250,7 +25922,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -24258,7 +25936,8 @@ "start_time": "2021-11-24T10:00:04.573863+00:00", "last_update": "2021-11-24T10:00:04.798016+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -24303,7 +25982,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -24311,7 +25996,8 @@ "start_time": "2021-11-24T09:50:04.512501+00:00", "last_update": "2021-11-24T09:50:04.695227+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -24356,7 +26042,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -24364,7 +26056,8 @@ "start_time": "2021-11-24T09:40:04.629863+00:00", "last_update": "2021-11-24T09:40:04.834239+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -24409,7 +26102,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -24417,7 +26116,8 @@ "start_time": "2021-11-24T09:30:04.415640+00:00", "last_update": "2021-11-24T09:30:04.602695+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -24462,7 +26162,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -24470,7 +26176,8 @@ "start_time": "2021-11-24T09:20:04.389076+00:00", "last_update": "2021-11-24T09:20:04.627217+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -24515,7 +26222,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -24523,7 +26236,8 @@ "start_time": "2021-11-24T09:10:04.487116+00:00", "last_update": "2021-11-24T09:10:04.670124+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -24568,7 +26282,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -24576,7 +26296,8 @@ "start_time": "2021-11-24T09:00:04.719912+00:00", "last_update": "2021-11-24T09:00:04.905482+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -24621,7 +26342,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -24629,7 +26356,8 @@ "start_time": "2021-11-24T08:50:04.761983+00:00", "last_update": "2021-11-24T08:50:04.929543+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -24674,7 +26402,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -24682,7 +26416,8 @@ "start_time": "2021-11-24T08:40:04.705636+00:00", "last_update": "2021-11-24T08:40:04.897900+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -24727,7 +26462,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -24735,7 +26476,8 @@ "start_time": "2021-11-24T08:30:04.927018+00:00", "last_update": "2021-11-24T08:30:05.101610+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -24780,7 +26522,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -24788,7 +26536,8 @@ "start_time": "2021-11-24T08:20:04.573076+00:00", "last_update": "2021-11-24T08:20:04.769617+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -24833,7 +26582,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -24841,7 +26596,8 @@ "start_time": "2021-11-24T08:10:04.640802+00:00", "last_update": "2021-11-24T08:10:04.829147+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -24886,7 +26642,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -24894,7 +26656,8 @@ "start_time": "2021-11-24T08:00:04.604561+00:00", "last_update": "2021-11-24T08:00:04.847589+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -24939,7 +26702,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -24947,7 +26716,8 @@ "start_time": "2021-11-24T07:50:04.475602+00:00", "last_update": "2021-11-24T07:50:04.652628+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -24992,7 +26762,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -25000,7 +26776,8 @@ "start_time": "2021-11-24T07:40:04.577226+00:00", "last_update": "2021-11-24T07:40:04.759757+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -25045,7 +26822,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -25053,7 +26836,8 @@ "start_time": "2021-11-24T07:30:04.628014+00:00", "last_update": "2021-11-24T07:30:04.842011+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -25098,7 +26882,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -25106,7 +26896,8 @@ "start_time": "2021-11-24T07:20:04.572949+00:00", "last_update": "2021-11-24T07:20:04.745549+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -25151,7 +26942,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -25159,7 +26956,8 @@ "start_time": "2021-11-24T07:10:04.502879+00:00", "last_update": "2021-11-24T07:10:04.764787+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -25204,7 +27002,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -25212,7 +27016,8 @@ "start_time": "2021-11-24T07:00:04.531331+00:00", "last_update": "2021-11-24T07:00:04.813165+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -25257,7 +27062,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -25265,7 +27076,8 @@ "start_time": "2021-11-24T06:50:04.460491+00:00", "last_update": "2021-11-24T06:50:04.656143+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -25310,7 +27122,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -25318,7 +27136,8 @@ "start_time": "2021-11-24T06:40:04.504154+00:00", "last_update": "2021-11-24T06:40:04.742584+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -25363,7 +27182,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -25371,7 +27196,8 @@ "start_time": "2021-11-24T06:30:04.491594+00:00", "last_update": "2021-11-24T06:30:04.725370+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -25416,7 +27242,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -25424,7 +27256,8 @@ "start_time": "2021-11-24T06:20:04.519788+00:00", "last_update": "2021-11-24T06:20:04.734958+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -25469,7 +27302,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -25477,7 +27316,8 @@ "start_time": "2021-11-24T06:10:04.532763+00:00", "last_update": "2021-11-24T06:10:04.823954+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -25522,7 +27362,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -25530,7 +27376,8 @@ "start_time": "2021-11-24T06:00:04.831518+00:00", "last_update": "2021-11-24T06:00:05.063036+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -25575,7 +27422,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -25583,7 +27436,8 @@ "start_time": "2021-11-24T05:50:04.921557+00:00", "last_update": "2021-11-24T05:50:05.106362+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -25628,7 +27482,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -25636,7 +27496,8 @@ "start_time": "2021-11-24T05:40:04.639983+00:00", "last_update": "2021-11-24T05:40:04.822973+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -25681,7 +27542,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -25689,7 +27556,8 @@ "start_time": "2021-11-24T05:30:04.552970+00:00", "last_update": "2021-11-24T05:30:04.758206+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -25734,7 +27602,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -25742,7 +27616,8 @@ "start_time": "2021-11-24T05:20:04.568293+00:00", "last_update": "2021-11-24T05:20:04.766989+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -25787,7 +27662,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -25795,7 +27676,8 @@ "start_time": "2021-11-24T05:10:04.425638+00:00", "last_update": "2021-11-24T05:10:04.610183+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -25840,7 +27722,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -25848,7 +27736,8 @@ "start_time": "2021-11-24T05:00:04.659651+00:00", "last_update": "2021-11-24T05:00:04.878540+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -25893,7 +27782,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -25901,7 +27796,8 @@ "start_time": "2021-11-24T04:50:04.525809+00:00", "last_update": "2021-11-24T04:50:04.698016+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -25946,7 +27842,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -25954,7 +27856,8 @@ "start_time": "2021-11-24T04:40:04.553894+00:00", "last_update": "2021-11-24T04:40:04.748205+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -25999,7 +27902,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -26007,7 +27916,8 @@ "start_time": "2021-11-24T04:30:04.505059+00:00", "last_update": "2021-11-24T04:30:04.694984+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -26052,7 +27962,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -26060,7 +27976,8 @@ "start_time": "2021-11-24T04:20:04.444087+00:00", "last_update": "2021-11-24T04:20:04.674675+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -26105,7 +28022,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -26113,7 +28036,8 @@ "start_time": "2021-11-24T04:10:04.502094+00:00", "last_update": "2021-11-24T04:10:04.693319+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -26158,7 +28082,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -26166,7 +28096,8 @@ "start_time": "2021-11-24T04:00:04.463193+00:00", "last_update": "2021-11-24T04:00:04.701626+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -26211,7 +28142,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -26219,7 +28156,8 @@ "start_time": "2021-11-24T03:50:04.567814+00:00", "last_update": "2021-11-24T03:50:04.753820+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -26264,7 +28202,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -26272,7 +28216,8 @@ "start_time": "2021-11-24T03:40:04.602754+00:00", "last_update": "2021-11-24T03:40:04.796732+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -26317,7 +28262,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -26325,7 +28276,8 @@ "start_time": "2021-11-24T03:30:04.418104+00:00", "last_update": "2021-11-24T03:30:04.601174+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -26370,7 +28322,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -26378,7 +28336,8 @@ "start_time": "2021-11-24T03:20:04.461566+00:00", "last_update": "2021-11-24T03:20:04.660232+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -26423,7 +28382,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -26431,7 +28396,8 @@ "start_time": "2021-11-24T03:10:04.632882+00:00", "last_update": "2021-11-24T03:10:04.841486+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -26476,7 +28442,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -26484,7 +28456,8 @@ "start_time": "2021-11-24T03:00:04.532402+00:00", "last_update": "2021-11-24T03:00:04.777504+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -26529,7 +28502,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -26537,7 +28516,8 @@ "start_time": "2021-11-24T02:50:04.500997+00:00", "last_update": "2021-11-24T02:50:04.679010+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -26582,7 +28562,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -26590,7 +28576,8 @@ "start_time": "2021-11-24T02:40:04.528901+00:00", "last_update": "2021-11-24T02:40:04.721345+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -26635,7 +28622,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -26643,7 +28636,8 @@ "start_time": "2021-11-24T02:30:04.720846+00:00", "last_update": "2021-11-24T02:30:05.074548+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -26688,7 +28682,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -26696,7 +28696,8 @@ "start_time": "2021-11-24T02:20:04.612354+00:00", "last_update": "2021-11-24T02:20:04.794415+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -26741,7 +28742,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -26749,7 +28756,8 @@ "start_time": "2021-11-24T02:10:04.489593+00:00", "last_update": "2021-11-24T02:10:04.713319+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -26794,7 +28802,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -26802,7 +28816,8 @@ "start_time": "2021-11-24T02:00:04.538137+00:00", "last_update": "2021-11-24T02:00:04.755615+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -26847,7 +28862,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -26855,7 +28876,8 @@ "start_time": "2021-11-24T01:50:04.546914+00:00", "last_update": "2021-11-24T01:50:04.747734+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -26900,7 +28922,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -26908,7 +28936,8 @@ "start_time": "2021-11-24T01:40:04.433153+00:00", "last_update": "2021-11-24T01:40:04.626096+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -26953,7 +28982,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -26961,7 +28996,8 @@ "start_time": "2021-11-24T01:30:04.510443+00:00", "last_update": "2021-11-24T01:30:04.692919+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -27006,7 +29042,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -27014,7 +29056,8 @@ "start_time": "2021-11-24T01:20:05.295062+00:00", "last_update": "2021-11-24T01:20:05.497610+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -27059,7 +29102,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -27067,7 +29116,8 @@ "start_time": "2021-11-24T01:10:04.688801+00:00", "last_update": "2021-11-24T01:10:04.883373+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -27112,7 +29162,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -27120,7 +29176,8 @@ "start_time": "2021-11-24T01:00:04.939719+00:00", "last_update": "2021-11-24T01:00:05.178464+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -27165,7 +29222,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -27173,7 +29236,8 @@ "start_time": "2021-11-24T00:50:04.468549+00:00", "last_update": "2021-11-24T00:50:04.701356+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -27218,7 +29282,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -27226,7 +29296,8 @@ "start_time": "2021-11-24T00:40:04.815652+00:00", "last_update": "2021-11-24T00:40:05.000489+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -27271,7 +29342,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -27279,7 +29356,8 @@ "start_time": "2021-11-24T00:30:04.598658+00:00", "last_update": "2021-11-24T00:30:04.774050+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -27324,7 +29402,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -27332,7 +29416,8 @@ "start_time": "2021-11-24T00:20:04.517762+00:00", "last_update": "2021-11-24T00:20:04.706307+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -27377,7 +29462,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -27385,7 +29476,8 @@ "start_time": "2021-11-24T00:10:04.545462+00:00", "last_update": "2021-11-24T00:10:04.727941+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -27430,7 +29522,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -27438,7 +29536,8 @@ "start_time": "2021-11-24T00:00:04.535371+00:00", "last_update": "2021-11-24T00:00:04.746612+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -27483,7 +29582,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -27491,7 +29596,8 @@ "start_time": "2021-11-23T23:50:04.643566+00:00", "last_update": "2021-11-23T23:50:04.826637+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -27536,7 +29642,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -27544,7 +29656,8 @@ "start_time": "2021-11-23T23:40:04.589647+00:00", "last_update": "2021-11-23T23:40:04.791146+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -27589,7 +29702,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -27597,7 +29716,8 @@ "start_time": "2021-11-23T23:30:04.528050+00:00", "last_update": "2021-11-23T23:30:04.734943+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -27642,7 +29762,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -27650,7 +29776,8 @@ "start_time": "2021-11-23T23:20:04.551632+00:00", "last_update": "2021-11-23T23:20:04.738770+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -27695,7 +29822,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -27703,7 +29836,8 @@ "start_time": "2021-11-23T23:10:04.450823+00:00", "last_update": "2021-11-23T23:10:04.652075+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -27748,7 +29882,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -27756,7 +29896,8 @@ "start_time": "2021-11-23T23:00:04.869365+00:00", "last_update": "2021-11-23T23:00:05.128497+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -27801,7 +29942,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -27809,7 +29956,8 @@ "start_time": "2021-11-23T22:50:04.634188+00:00", "last_update": "2021-11-23T22:50:04.810555+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -27854,7 +30002,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -27862,7 +30016,8 @@ "start_time": "2021-11-23T22:40:04.569522+00:00", "last_update": "2021-11-23T22:40:04.769561+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -27907,7 +30062,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -27915,7 +30076,8 @@ "start_time": "2021-11-23T22:30:04.434236+00:00", "last_update": "2021-11-23T22:30:04.623421+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -27960,7 +30122,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -27968,7 +30136,8 @@ "start_time": "2021-11-23T22:20:04.379221+00:00", "last_update": "2021-11-23T22:20:04.571849+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -28013,7 +30182,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -28021,7 +30196,8 @@ "start_time": "2021-11-23T22:10:04.424226+00:00", "last_update": "2021-11-23T22:10:04.606574+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -28066,7 +30242,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -28074,7 +30256,8 @@ "start_time": "2021-11-23T22:00:04.584191+00:00", "last_update": "2021-11-23T22:00:04.802213+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -28119,7 +30302,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -28127,7 +30316,8 @@ "start_time": "2021-11-23T21:50:04.332475+00:00", "last_update": "2021-11-23T21:50:04.660638+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -28172,7 +30362,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -28180,7 +30376,8 @@ "start_time": "2021-11-23T21:40:04.437659+00:00", "last_update": "2021-11-23T21:40:04.653196+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -28225,7 +30422,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -28233,7 +30436,8 @@ "start_time": "2021-11-23T21:30:04.453384+00:00", "last_update": "2021-11-23T21:30:04.654010+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -28278,7 +30482,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -28286,7 +30496,8 @@ "start_time": "2021-11-23T21:20:04.442566+00:00", "last_update": "2021-11-23T21:20:04.625930+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -28331,7 +30542,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -28339,7 +30556,8 @@ "start_time": "2021-11-23T21:10:04.532801+00:00", "last_update": "2021-11-23T21:10:04.771198+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -28384,7 +30602,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -28392,7 +30616,8 @@ "start_time": "2021-11-23T21:00:04.543551+00:00", "last_update": "2021-11-23T21:00:04.762114+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -28437,7 +30662,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -28445,7 +30676,8 @@ "start_time": "2021-11-23T20:50:04.599458+00:00", "last_update": "2021-11-23T20:50:04.810958+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -28490,7 +30722,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -28498,7 +30736,8 @@ "start_time": "2021-11-23T20:40:04.375137+00:00", "last_update": "2021-11-23T20:40:04.549978+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -28543,7 +30782,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -28551,7 +30796,8 @@ "start_time": "2021-11-23T20:30:04.725045+00:00", "last_update": "2021-11-23T20:30:04.910512+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -28596,7 +30842,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -28604,7 +30856,8 @@ "start_time": "2021-11-23T20:20:04.650462+00:00", "last_update": "2021-11-23T20:20:04.826445+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -28649,7 +30902,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -28657,7 +30916,8 @@ "start_time": "2021-11-23T20:10:04.516348+00:00", "last_update": "2021-11-23T20:10:04.854112+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -28702,7 +30962,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -28710,7 +30976,8 @@ "start_time": "2021-11-23T20:00:04.707833+00:00", "last_update": "2021-11-23T20:00:04.908904+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -28755,7 +31022,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -28763,7 +31036,8 @@ "start_time": "2021-11-23T19:50:04.421833+00:00", "last_update": "2021-11-23T19:50:04.632400+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -28808,7 +31082,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -28816,7 +31096,8 @@ "start_time": "2021-11-23T19:40:04.418991+00:00", "last_update": "2021-11-23T19:40:04.591359+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -28861,7 +31142,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -28869,7 +31156,8 @@ "start_time": "2021-11-23T19:30:04.517543+00:00", "last_update": "2021-11-23T19:30:04.705190+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -28914,7 +31202,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -28922,7 +31216,8 @@ "start_time": "2021-11-23T19:20:04.559188+00:00", "last_update": "2021-11-23T19:20:04.744737+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -28967,7 +31262,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -28975,7 +31276,8 @@ "start_time": "2021-11-23T19:10:04.590607+00:00", "last_update": "2021-11-23T19:10:04.789711+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -29020,7 +31322,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -29028,7 +31336,8 @@ "start_time": "2021-11-23T19:00:04.581072+00:00", "last_update": "2021-11-23T19:00:04.821969+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -29073,7 +31382,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -29081,7 +31396,8 @@ "start_time": "2021-11-23T18:50:04.699860+00:00", "last_update": "2021-11-23T18:50:04.931051+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -29126,7 +31442,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -29134,7 +31456,8 @@ "start_time": "2021-11-23T18:40:05.087681+00:00", "last_update": "2021-11-23T18:40:05.261694+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -29179,7 +31502,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -29187,7 +31516,8 @@ "start_time": "2021-11-23T18:30:04.418439+00:00", "last_update": "2021-11-23T18:30:04.598008+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -29232,7 +31562,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -29240,7 +31576,8 @@ "start_time": "2021-11-23T18:20:04.498606+00:00", "last_update": "2021-11-23T18:20:04.694717+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -29285,7 +31622,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -29293,7 +31636,8 @@ "start_time": "2021-11-23T18:10:04.694077+00:00", "last_update": "2021-11-23T18:10:04.877956+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -29338,7 +31682,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -29346,7 +31696,8 @@ "start_time": "2021-11-23T18:00:04.451190+00:00", "last_update": "2021-11-23T18:00:04.685289+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -29391,7 +31742,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -29399,7 +31756,8 @@ "start_time": "2021-11-23T17:50:04.409692+00:00", "last_update": "2021-11-23T17:50:04.574748+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -29444,7 +31802,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -29452,7 +31816,8 @@ "start_time": "2021-11-23T17:40:04.803186+00:00", "last_update": "2021-11-23T17:40:05.024504+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -29497,7 +31862,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -29505,7 +31876,8 @@ "start_time": "2021-11-23T17:30:04.458452+00:00", "last_update": "2021-11-23T17:30:04.643441+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -29550,7 +31922,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -29558,7 +31936,8 @@ "start_time": "2021-11-23T17:20:04.389008+00:00", "last_update": "2021-11-23T17:20:04.559117+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -29603,7 +31982,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -29611,7 +31996,8 @@ "start_time": "2021-11-23T17:10:04.429827+00:00", "last_update": "2021-11-23T17:10:04.697423+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -29656,7 +32042,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -29664,7 +32056,8 @@ "start_time": "2021-11-23T17:00:04.636519+00:00", "last_update": "2021-11-23T17:00:04.852019+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -29709,7 +32102,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -29717,7 +32116,8 @@ "start_time": "2021-11-23T16:50:04.469691+00:00", "last_update": "2021-11-23T16:50:04.638176+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -29762,7 +32162,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -29770,7 +32176,8 @@ "start_time": "2021-11-23T16:40:04.793124+00:00", "last_update": "2021-11-23T16:40:04.979396+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -29815,7 +32222,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -29823,7 +32236,8 @@ "start_time": "2021-11-23T16:30:04.511592+00:00", "last_update": "2021-11-23T16:30:04.701880+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -29868,7 +32282,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -29876,7 +32296,8 @@ "start_time": "2021-11-23T16:20:04.441622+00:00", "last_update": "2021-11-23T16:20:04.616568+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -29921,7 +32342,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -29929,7 +32356,8 @@ "start_time": "2021-11-23T16:10:04.297534+00:00", "last_update": "2021-11-23T16:10:04.488367+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -29956,14 +32384,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-11-23T16:01:58.107788+00:00", "last_update": "2021-11-23T16:01:58.227436+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -30008,7 +32443,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -30016,7 +32457,8 @@ "start_time": "2021-11-23T16:00:04.725458+00:00", "last_update": "2021-11-23T16:00:04.968356+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -30061,7 +32503,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -30069,7 +32517,8 @@ "start_time": "2021-11-23T15:50:04.422576+00:00", "last_update": "2021-11-23T15:50:04.635788+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -30114,7 +32563,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -30122,7 +32577,8 @@ "start_time": "2021-11-23T15:40:04.641266+00:00", "last_update": "2021-11-23T15:40:04.882666+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -30167,7 +32623,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -30175,7 +32637,8 @@ "start_time": "2021-11-23T15:30:04.378826+00:00", "last_update": "2021-11-23T15:30:04.565072+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -30220,7 +32683,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -30228,7 +32697,8 @@ "start_time": "2021-11-23T15:20:04.559525+00:00", "last_update": "2021-11-23T15:20:04.758667+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -30273,7 +32743,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -30281,7 +32757,8 @@ "start_time": "2021-11-23T15:10:04.536833+00:00", "last_update": "2021-11-23T15:10:04.726331+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -30326,7 +32803,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -30334,7 +32817,8 @@ "start_time": "2021-11-23T15:00:04.563670+00:00", "last_update": "2021-11-23T15:00:04.784840+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -30379,7 +32863,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -30387,7 +32877,8 @@ "start_time": "2021-11-23T14:50:04.460492+00:00", "last_update": "2021-11-23T14:50:04.649701+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -30432,7 +32923,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -30440,7 +32937,8 @@ "start_time": "2021-11-23T14:40:04.553734+00:00", "last_update": "2021-11-23T14:40:04.854853+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -30485,7 +32983,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -30493,7 +32997,8 @@ "start_time": "2021-11-23T14:30:04.626953+00:00", "last_update": "2021-11-23T14:30:04.806765+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -30538,7 +33043,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -30546,7 +33057,8 @@ "start_time": "2021-11-23T14:20:04.478122+00:00", "last_update": "2021-11-23T14:20:04.710932+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -30591,7 +33103,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -30599,7 +33117,8 @@ "start_time": "2021-11-23T14:10:04.510030+00:00", "last_update": "2021-11-23T14:10:04.734683+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -30644,7 +33163,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -30652,7 +33177,8 @@ "start_time": "2021-11-23T14:00:04.692590+00:00", "last_update": "2021-11-23T14:00:04.913319+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -30697,7 +33223,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -30705,7 +33237,8 @@ "start_time": "2021-11-23T13:50:04.486524+00:00", "last_update": "2021-11-23T13:50:04.707908+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -30750,7 +33283,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -30758,7 +33297,8 @@ "start_time": "2021-11-23T13:40:04.695802+00:00", "last_update": "2021-11-23T13:40:04.864555+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -30803,7 +33343,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -30811,7 +33357,8 @@ "start_time": "2021-11-23T13:30:04.466982+00:00", "last_update": "2021-11-23T13:30:04.645016+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -30856,7 +33403,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -30864,7 +33417,8 @@ "start_time": "2021-11-23T13:20:04.432215+00:00", "last_update": "2021-11-23T13:20:04.593066+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -30909,7 +33463,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -30917,7 +33477,8 @@ "start_time": "2021-11-23T13:10:04.377343+00:00", "last_update": "2021-11-23T13:10:04.562248+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -30962,7 +33523,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -30970,7 +33537,8 @@ "start_time": "2021-11-23T13:00:04.757717+00:00", "last_update": "2021-11-23T13:00:04.976383+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -31015,7 +33583,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -31023,7 +33597,8 @@ "start_time": "2021-11-23T12:50:04.510481+00:00", "last_update": "2021-11-23T12:50:04.694038+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -31068,7 +33643,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -31076,7 +33657,8 @@ "start_time": "2021-11-23T12:40:04.381615+00:00", "last_update": "2021-11-23T12:40:04.572676+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -31121,7 +33703,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -31129,7 +33717,8 @@ "start_time": "2021-11-23T12:30:04.503862+00:00", "last_update": "2021-11-23T12:30:04.678147+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -31174,7 +33763,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -31182,7 +33777,8 @@ "start_time": "2021-11-23T12:20:04.559097+00:00", "last_update": "2021-11-23T12:20:04.737203+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -31227,7 +33823,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -31235,7 +33837,8 @@ "start_time": "2021-11-23T12:10:04.449115+00:00", "last_update": "2021-11-23T12:10:04.625507+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -31280,7 +33883,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -31288,7 +33897,8 @@ "start_time": "2021-11-23T12:00:04.486243+00:00", "last_update": "2021-11-23T12:00:04.698411+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -31333,7 +33943,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -31341,7 +33957,8 @@ "start_time": "2021-11-23T11:50:04.723311+00:00", "last_update": "2021-11-23T11:50:04.932266+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -31386,7 +34003,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -31394,7 +34017,8 @@ "start_time": "2021-11-23T11:40:04.649386+00:00", "last_update": "2021-11-23T11:40:04.869518+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -31439,7 +34063,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -31447,7 +34077,8 @@ "start_time": "2021-11-23T11:30:04.532380+00:00", "last_update": "2021-11-23T11:30:04.711271+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -31492,7 +34123,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -31500,7 +34137,8 @@ "start_time": "2021-11-23T11:20:04.501966+00:00", "last_update": "2021-11-23T11:20:04.698149+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -31545,7 +34183,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -31553,7 +34197,8 @@ "start_time": "2021-11-23T11:10:04.480587+00:00", "last_update": "2021-11-23T11:10:04.666382+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -31598,7 +34243,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -31606,7 +34257,8 @@ "start_time": "2021-11-23T11:00:04.482799+00:00", "last_update": "2021-11-23T11:00:04.712377+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -31651,7 +34303,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -31659,7 +34317,8 @@ "start_time": "2021-11-23T10:50:04.458809+00:00", "last_update": "2021-11-23T10:50:04.633174+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -31704,7 +34363,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -31712,7 +34377,8 @@ "start_time": "2021-11-23T10:40:04.415844+00:00", "last_update": "2021-11-23T10:40:04.582542+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -31757,7 +34423,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -31765,7 +34437,8 @@ "start_time": "2021-11-23T10:30:04.376510+00:00", "last_update": "2021-11-23T10:30:04.568037+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -31810,7 +34483,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -31818,7 +34497,8 @@ "start_time": "2021-11-23T10:20:04.393940+00:00", "last_update": "2021-11-23T10:20:04.599562+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -31863,7 +34543,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -31871,7 +34557,8 @@ "start_time": "2021-11-23T10:10:04.602995+00:00", "last_update": "2021-11-23T10:10:04.792896+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -31919,7 +34606,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -31927,7 +34620,8 @@ "start_time": "2021-11-23T10:04:11.101928+00:00", "last_update": "2021-11-23T10:04:11.277613+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -31963,14 +34657,21 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-11-23T10:03:38.156539+00:00", "last_update": "2021-11-23T10:03:52.050684+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -31998,14 +34699,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-11-23T10:03:35.393063+00:00", "last_update": "2021-11-23T10:03:35.483063+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -32032,14 +34740,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-11-08T11:46:51.227805+00:00", "last_update": "2021-11-08T11:46:51.296237+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -32066,14 +34781,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-11-08T11:45:22.064287+00:00", "last_update": "2021-11-08T11:45:22.145479+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -32108,7 +34830,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -32116,7 +34844,8 @@ "start_time": "2021-11-08T11:43:51.387325+00:00", "last_update": "2021-11-08T11:43:51.660572+00:00", "error": "Columns must be same length as key", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -32159,14 +34888,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "aborted", "results": {}, "start_time": "2021-11-08T11:42:59.089848+00:00", "last_update": "2021-11-08T11:43:07.483195+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -32213,14 +34949,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-11-08T11:40:08.223207+00:00", "last_update": "2021-11-08T11:40:36.453731+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -32263,14 +35006,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-11-08T11:39:43.558424+00:00", "last_update": "2021-11-08T11:40:06.182841+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -32317,14 +35067,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-11-08T11:39:35.083703+00:00", "last_update": "2021-11-08T11:39:35.895469+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -32352,14 +35109,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-11-08T11:36:03.228032+00:00", "last_update": "2021-11-08T11:36:03.301501+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -32387,14 +35151,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-11-02T08:47:57.208326+00:00", "last_update": "2021-11-02T08:47:57.328639+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -32422,14 +35193,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-11-01T00:00:08.999400+00:00", "last_update": "2021-11-01T00:00:09.211607+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -32455,14 +35233,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-10-28T18:12:56.106520+00:00", "last_update": "2021-10-28T18:13:17.198567+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -32488,14 +35273,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-10-28T14:18:37.228925+00:00", "last_update": "2021-10-28T14:19:06.426608+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -32523,14 +35315,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-10-28T13:46:21.225458+00:00", "last_update": "2021-10-28T13:46:21.294035+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -32581,7 +35380,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -32589,7 +35394,8 @@ "start_time": "2021-10-28T13:43:30.968141+00:00", "last_update": "2021-10-28T13:43:31.647120+00:00", "error": "file type unhandled v3io:///test/test", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -32631,14 +35437,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-10-28T08:40:35.739139+00:00", "last_update": "2021-10-28T08:41:05.600456+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -32684,14 +35497,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "aborted", "results": {}, "start_time": "2021-10-21T18:14:19.099271+00:00", "last_update": "2021-10-21T18:14:46.228065+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -32717,14 +35537,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "aborted", "results": {}, "start_time": "2021-10-19T07:46:06.654759+00:00", "last_update": "2021-10-19T07:46:36.553501+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -32750,14 +35577,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-10-19T07:32:37.765470+00:00", "last_update": "2021-10-19T07:32:56.606738+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -32783,14 +35617,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "aborted", "results": {}, "start_time": "2021-10-15T14:54:55.118884+00:00", "last_update": "2021-10-15T14:55:06.696436+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -32817,14 +35658,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-10-13T19:58:01.299873+00:00", "last_update": "2021-10-13T19:58:01.374021+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -32851,14 +35699,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-10-13T19:41:12.462796+00:00", "last_update": "2021-10-13T19:41:12.541077+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -32884,14 +35739,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-10-13T19:23:24.084989+00:00", "last_update": "2021-10-13T19:23:24.472745+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -32917,14 +35779,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-10-13T19:22:17.420518+00:00", "last_update": "2021-10-13T19:22:24.018887+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -32950,14 +35819,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-10-13T15:55:43.092290+00:00", "last_update": "2021-10-13T15:56:04.828883+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -32984,14 +35860,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-10-13T15:14:29.209667+00:00", "last_update": "2021-10-13T15:14:29.271307+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -33018,14 +35901,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-10-13T14:12:55.122657+00:00", "last_update": "2021-10-13T14:12:55.188855+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -33052,14 +35942,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-10-13T14:02:19.750855+00:00", "last_update": "2021-10-13T14:02:19.839795+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -33085,14 +35982,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "aborted", "results": {}, "start_time": "2021-10-10T10:27:23.881911+00:00", "last_update": "2021-10-10T10:27:24.616015+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -33118,14 +36022,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "aborted", "results": {}, "start_time": "2021-10-10T10:22:23.551995+00:00", "last_update": "2021-10-10T10:22:29.710206+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -33151,14 +36062,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "aborted", "results": {}, "start_time": "2021-10-10T10:22:01.460726+00:00", "last_update": "2021-10-10T10:22:06.341668+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -33184,14 +36102,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "aborted", "results": {}, "start_time": "2021-10-10T10:21:34.872124+00:00", "last_update": "2021-10-10T10:21:44.400075+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -33227,14 +36152,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-10-06T14:10:00.438518+00:00", "last_update": "2021-10-06T14:10:16.259616+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -33261,14 +36193,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-10-01T00:00:00.235989+00:00", "last_update": "2021-10-01T00:00:12.308235+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -33294,14 +36233,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-09-30T12:03:14.421289+00:00", "last_update": "2021-09-30T12:03:33.039369+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -33327,14 +36273,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-09-30T12:00:57.901153+00:00", "last_update": "2021-09-30T12:01:01.851605+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -33360,14 +36313,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "aborted", "results": {}, "start_time": "2021-09-17T15:08:47.936899+00:00", "last_update": "2021-09-17T15:09:07.462131+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -33424,7 +36384,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -33432,7 +36398,8 @@ "start_time": "2021-09-17T15:08:29.202452+00:00", "last_update": "2021-09-17T15:08:30.072691+00:00", "error": "unable to connect to account for Must provide either a connection_string or account_name with credentials!!", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -33489,7 +36456,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -33497,7 +36470,8 @@ "start_time": "2021-09-17T12:53:31.183995+00:00", "last_update": "2021-09-17T12:53:31.818200+00:00", "error": "file type unhandled v3io://hhhhjjjjkkkk", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -33554,7 +36528,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -33562,7 +36542,8 @@ "start_time": "2021-09-17T12:50:53.673923+00:00", "last_update": "2021-09-17T12:50:54.305932+00:00", "error": "file type unhandled v3io://hhhhhhh", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -33619,7 +36600,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -33627,7 +36614,8 @@ "start_time": "2021-09-17T12:44:47.158478+00:00", "last_update": "2021-09-17T12:44:47.738459+00:00", "error": "file type unhandled v3io://test", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -33684,7 +36672,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -33692,7 +36686,8 @@ "start_time": "2021-09-17T12:15:35.974230+00:00", "last_update": "2021-09-17T12:15:36.567922+00:00", "error": "file type unhandled v3io://sdadsada", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -33749,7 +36744,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -33757,7 +36758,8 @@ "start_time": "2021-09-17T12:14:22.653559+00:00", "last_update": "2021-09-17T12:14:23.294026+00:00", "error": "file type unhandled v3io://ss", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -33814,7 +36816,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -33822,7 +36830,8 @@ "start_time": "2021-09-17T12:13:17.761118+00:00", "last_update": "2021-09-17T12:13:18.502005+00:00", "error": "file type unhandled v3io://yy", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -33879,7 +36888,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -33887,7 +36902,8 @@ "start_time": "2021-09-17T12:12:48.401039+00:00", "last_update": "2021-09-17T12:12:49.044854+00:00", "error": "file type unhandled v3io://tt", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -33944,7 +36960,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -33952,7 +36974,8 @@ "start_time": "2021-09-17T12:09:10.806047+00:00", "last_update": "2021-09-17T12:09:11.364692+00:00", "error": "file type unhandled v3io://ewqewq", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -34009,7 +37032,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -34017,7 +37046,8 @@ "start_time": "2021-09-17T11:59:50.920646+00:00", "last_update": "2021-09-17T11:59:51.576888+00:00", "error": "file type unhandled v3io://asd", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -34074,7 +37104,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -34082,7 +37118,8 @@ "start_time": "2021-09-17T11:59:01.285243+00:00", "last_update": "2021-09-17T11:59:04.051728+00:00", "error": "file type unhandled s3://asd", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -34139,7 +37176,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -34147,7 +37190,8 @@ "start_time": "2021-09-17T11:57:57.036076+00:00", "last_update": "2021-09-17T11:57:57.905590+00:00", "error": "file type unhandled v3io://qweewqqwwwwwwww", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -34173,14 +37217,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-09-17T11:34:04.948045+00:00", "last_update": "2021-09-17T11:34:11.649796+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -34237,7 +37288,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -34245,7 +37302,8 @@ "start_time": "2021-09-17T08:01:55.544559+00:00", "last_update": "2021-09-17T08:01:56.622206+00:00", "error": "unable to connect to account for Must provide either a connection_string or account_name with credentials!!", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -34302,7 +37360,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -34310,7 +37374,8 @@ "start_time": "2021-09-16T15:34:11.324884+00:00", "last_update": "2021-09-16T15:34:11.938806+00:00", "error": "file type unhandled v3io://asd", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -34367,7 +37432,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -34375,7 +37446,8 @@ "start_time": "2021-09-15T11:11:23.310455+00:00", "last_update": "2021-09-15T11:11:23.886661+00:00", "error": "file type unhandled v3io://aa", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -34401,7 +37473,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -34409,7 +37487,8 @@ "start_time": "2021-09-10T08:07:55.696888+00:00", "last_update": "2021-09-10T08:07:55.747261+00:00", "artifacts": [], - "error": "(422)\nReason: Unprocessable Entity\nHTTP response headers: HTTPHeaderDict({'Cache-Control': 'no-cache, private', 'Content-Type': 'application/json', 'Date': 'Fri, 10 Sep 2021 08:07:55 GMT', 'Content-Length': '1026'})\nHTTP response body: {\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"Pod \\\"test-i-vmghw\\\" is invalid: [spec.volumes[0].name: Invalid value: \\\"volume_test__name\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?'), spec.containers[0].volumeMounts[0].name: Not found: \\\"volume_test__name\\\"]\",\"reason\":\"Invalid\",\"details\":{\"name\":\"test-i-vmghw\",\"kind\":\"Pod\",\"causes\":[{\"reason\":\"FieldValueInvalid\",\"message\":\"Invalid value: \\\"volume_test__name\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')\",\"field\":\"spec.volumes[0].name\"},{\"reason\":\"FieldValueNotFound\",\"message\":\"Not found: \\\"volume_test__name\\\"\",\"field\":\"spec.containers[0].volumeMounts[0].name\"}]},\"code\":422}\n\n" + "error": "(422)\nReason: Unprocessable Entity\nHTTP response headers: HTTPHeaderDict({'Cache-Control': 'no-cache, private', 'Content-Type': 'application/json', 'Date': 'Fri, 10 Sep 2021 08:07:55 GMT', 'Content-Length': '1026'})\nHTTP response body: {\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"Pod \\\"test-i-vmghw\\\" is invalid: [spec.volumes[0].name: Invalid value: \\\"volume_test__name\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?'), spec.containers[0].volumeMounts[0].name: Not found: \\\"volume_test__name\\\"]\",\"reason\":\"Invalid\",\"details\":{\"name\":\"test-i-vmghw\",\"kind\":\"Pod\",\"causes\":[{\"reason\":\"FieldValueInvalid\",\"message\":\"Invalid value: \\\"volume_test__name\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')\",\"field\":\"spec.volumes[0].name\"},{\"reason\":\"FieldValueNotFound\",\"message\":\"Not found: \\\"volume_test__name\\\"\",\"field\":\"spec.containers[0].volumeMounts[0].name\"}]},\"code\":422}\n\n", + "retry_count": 1 } }, { @@ -34435,7 +37514,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -34443,7 +37528,8 @@ "start_time": "2021-09-10T08:07:27.992706+00:00", "last_update": "2021-09-10T08:07:28.071778+00:00", "artifacts": [], - "error": "(422)\nReason: Unprocessable Entity\nHTTP response headers: HTTPHeaderDict({'Cache-Control': 'no-cache, private', 'Content-Type': 'application/json', 'Date': 'Fri, 10 Sep 2021 08:07:28 GMT', 'Content-Length': '1026'})\nHTTP response body: {\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"Pod \\\"test-i-d2x69\\\" is invalid: [spec.volumes[0].name: Invalid value: \\\"volume_test__name\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?'), spec.containers[0].volumeMounts[0].name: Not found: \\\"volume_test__name\\\"]\",\"reason\":\"Invalid\",\"details\":{\"name\":\"test-i-d2x69\",\"kind\":\"Pod\",\"causes\":[{\"reason\":\"FieldValueInvalid\",\"message\":\"Invalid value: \\\"volume_test__name\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')\",\"field\":\"spec.volumes[0].name\"},{\"reason\":\"FieldValueNotFound\",\"message\":\"Not found: \\\"volume_test__name\\\"\",\"field\":\"spec.containers[0].volumeMounts[0].name\"}]},\"code\":422}\n\n" + "error": "(422)\nReason: Unprocessable Entity\nHTTP response headers: HTTPHeaderDict({'Cache-Control': 'no-cache, private', 'Content-Type': 'application/json', 'Date': 'Fri, 10 Sep 2021 08:07:28 GMT', 'Content-Length': '1026'})\nHTTP response body: {\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"Pod \\\"test-i-d2x69\\\" is invalid: [spec.volumes[0].name: Invalid value: \\\"volume_test__name\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?'), spec.containers[0].volumeMounts[0].name: Not found: \\\"volume_test__name\\\"]\",\"reason\":\"Invalid\",\"details\":{\"name\":\"test-i-d2x69\",\"kind\":\"Pod\",\"causes\":[{\"reason\":\"FieldValueInvalid\",\"message\":\"Invalid value: \\\"volume_test__name\\\": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')\",\"field\":\"spec.volumes[0].name\"},{\"reason\":\"FieldValueNotFound\",\"message\":\"Not found: \\\"volume_test__name\\\"\",\"field\":\"spec.containers[0].volumeMounts[0].name\"}]},\"code\":422}\n\n", + "retry_count": 0 } }, { @@ -34469,14 +37555,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-09-08T16:01:00.020724+00:00", "last_update": "2021-09-08T16:01:28.024926+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -34502,14 +37595,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-09-08T15:51:02.734809+00:00", "last_update": "2021-09-08T15:51:23.296887+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -34535,14 +37635,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-09-08T15:37:29.504427+00:00", "last_update": "2021-09-08T15:37:47.727633+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -34588,14 +37695,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-09-07T11:42:54.171035+00:00", "last_update": "2021-09-07T11:42:56.512443+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -34621,14 +37735,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-09-07T11:20:14.154220+00:00", "last_update": "2021-09-07T11:20:16.663883+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -34654,14 +37775,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-09-07T09:03:37.071417+00:00", "last_update": "2021-09-07T09:04:05.569790+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -34712,7 +37840,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -34721,7 +37855,8 @@ }, "start_time": "2021-09-04T08:13:13.409154+00:00", "last_update": "2021-09-04T08:13:14.808015+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -34755,7 +37890,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -34763,7 +37904,8 @@ "start_time": "2021-09-03T13:53:56.088502+00:00", "last_update": "2021-09-03T13:53:56.318914+00:00", "error": "Columns must be same length as key", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -34790,14 +37932,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-09-03T13:53:50.030505+00:00", "last_update": "2021-09-03T13:53:50.099756+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -34844,7 +37993,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -34852,7 +38007,8 @@ "start_time": "2021-09-03T13:53:35.470383+00:00", "last_update": "2021-09-03T13:53:35.716754+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -34879,14 +38035,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-09-03T13:52:40.749944+00:00", "last_update": "2021-09-03T13:52:40.810108+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -34913,14 +38076,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-09-03T12:02:52.273993+00:00", "last_update": "2021-09-03T12:02:52.335681+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -34955,7 +38125,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -34963,7 +38139,8 @@ "start_time": "2021-09-03T12:02:03.774104+00:00", "last_update": "2021-09-03T12:02:03.936616+00:00", "error": "[Errno 2] No such file or directory: 'message_file'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -35010,7 +38187,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -35018,7 +38201,8 @@ "start_time": "2021-09-01T13:32:53.361949+00:00", "last_update": "2021-09-01T13:32:53.519516+00:00", "error": "'str' object has no attribute 'url'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -35044,7 +38228,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -35052,7 +38242,8 @@ "start_time": "2021-08-31T19:07:10.627886+00:00", "last_update": "2021-08-31T19:07:10.683889+00:00", "artifacts": [], - "error": "cannot import from ''" + "error": "cannot import from ''", + "retry_count": 1 } }, { @@ -35078,14 +38269,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "aborted", "results": {}, "start_time": "2021-10-04T06:43:00.974008+00:00", "last_update": "2021-10-04T06:43:07.566741+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -35123,7 +38321,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -35132,7 +38336,8 @@ }, "start_time": "2021-08-29T19:45:14.995282+00:00", "last_update": "2021-08-29T19:45:18.516911+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -35163,14 +38368,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-11-23T10:00:00.059030+00:00", "last_update": "2021-11-23T10:00:20.339115+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -35200,14 +38412,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-11-23T09:58:33.718204+00:00", "last_update": "2021-11-23T09:58:49.667649+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -35239,7 +38458,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -35247,7 +38472,8 @@ "start_time": "2021-11-08T16:26:31.029770+00:00", "last_update": "2021-11-08T16:27:42.496061+00:00", "error": "401 received while accessing 'getting-started-tutorial-admin/artifacts/data/test_set.csv'", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -35282,7 +38508,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -35290,7 +38522,8 @@ "start_time": "2021-11-08T16:26:21.976983+00:00", "last_update": "2021-11-08T16:28:41.537143+00:00", "error": "401 received while accessing 'getting-started-tutorial-admin/artifacts/pipeline/dd5972cb-cbc2-4998-ab0e-705dba1b307d/data/test_set.csv'", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -35323,7 +38556,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -35331,7 +38570,8 @@ "start_time": "2021-11-08T16:24:23.377270+00:00", "last_update": "2021-11-08T16:24:23.642837+00:00", "error": "file type unhandled dataset", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -35364,7 +38604,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -35372,7 +38618,8 @@ "start_time": "2021-11-08T16:24:03.601835+00:00", "last_update": "2021-11-08T16:24:03.787381+00:00", "error": "file type unhandled source_url", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -35414,7 +38661,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -35422,7 +38675,8 @@ "start_time": "2021-11-08T16:21:59.747369+00:00", "last_update": "2021-11-08T16:21:59.925727+00:00", "error": "file type unhandled test_set", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -35460,7 +38714,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -35468,7 +38728,8 @@ "start_time": "2021-11-08T16:21:43.033778+00:00", "last_update": "2021-11-08T16:21:43.242064+00:00", "error": "file type unhandled table", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -35495,7 +38756,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -35503,7 +38770,8 @@ "start_time": "2021-11-08T16:21:00.729828+00:00", "last_update": "2021-11-08T16:21:00.772223+00:00", "artifacts": [], - "error": ".run() can only be execute on \"mlrun\" kind, recreate with function kind \"mlrun\"" + "error": ".run() can only be execute on \"mlrun\" kind, recreate with function kind \"mlrun\"", + "retry_count": 1 } }, { @@ -35539,7 +38807,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -36188,7 +39462,8 @@ "uid": "460-3", "tag": "latest" } - ] + ], + "retry_count": 0 } }, { @@ -36225,7 +39500,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -37327,7 +40608,8 @@ "uid": "461-5", "tag": "latest" } - ] + ], + "retry_count": 1 } }, { @@ -37363,7 +40645,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -37879,7 +41167,8 @@ "uid": "462-0", "tag": "latest" } - ] + ], + "retry_count": 1 } }, { @@ -37912,7 +41201,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -38561,7 +41856,8 @@ "uid": "463-3", "tag": "latest" } - ] + ], + "retry_count": 2 } }, { @@ -38592,7 +41888,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -38702,7 +42004,8 @@ "uid": "464-5", "tag": "latest" } - ] + ], + "retry_count": 0 } }, { @@ -38733,7 +42036,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -39835,7 +43144,8 @@ "uid": "465-5", "tag": "latest" } - ] + ], + "retry_count": 2 } }, { @@ -39864,7 +43174,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -40380,7 +43696,8 @@ "uid": "466-0", "tag": "latest" } - ] + ], + "retry_count": 0 } }, { @@ -40409,7 +43726,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -40925,7 +44248,8 @@ "uid": "467-0", "tag": "latest" } - ] + ], + "retry_count": 2 } }, { @@ -40954,7 +44278,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -41470,7 +44800,8 @@ "uid": "468-0", "tag": "latest" } - ] + ], + "retry_count": 2 } }, { @@ -41499,14 +44830,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-08-31T19:47:38.497611+00:00", "last_update": "2021-08-31T19:47:53.564737+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -41537,14 +44875,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", "results": {}, "start_time": "2021-08-29T20:05:25.859281+00:00", "last_update": "2021-08-29T20:07:09.961262+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -41570,14 +44915,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-09-10T11:40:10.676831+00:00", "last_update": "2021-09-10T11:40:27.194590+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -41603,14 +44955,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-09-08T12:58:23.170389+00:00", "last_update": "2021-09-08T12:58:43.526754+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -41645,7 +45004,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -41653,7 +45018,8 @@ "start_time": "2021-09-06T15:18:24.118044+00:00", "last_update": "2021-09-06T15:18:24.379177+00:00", "error": "unsupported archive type in archive_url", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -41699,7 +45065,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -41707,7 +45079,8 @@ "start_time": "2021-09-06T13:47:42.720200+00:00", "last_update": "2021-09-06T13:47:42.859183+00:00", "error": "file type unhandled dataset", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -41753,7 +45126,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -41761,7 +45140,8 @@ "start_time": "2021-09-06T13:45:12.800502+00:00", "last_update": "2021-09-06T13:45:12.929041+00:00", "error": "file type unhandled dataset", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -41807,14 +45187,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "aborted", "results": {}, "start_time": "2021-09-03T11:09:10.722682+00:00", "last_update": "2021-09-03T11:09:31.085216+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -41838,14 +45225,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "running", "results": {}, "start_time": "2021-11-16T07:37:26.003124+00:00", "last_update": "2021-11-16T07:37:26.003133+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -41869,14 +45263,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "running", "results": {}, "start_time": "2021-11-16T07:37:26.001892+00:00", "last_update": "2021-11-16T07:37:26.001899+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -41900,14 +45301,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "running", "results": {}, "start_time": "2021-11-16T07:37:25.723971+00:00", "last_update": "2021-11-16T07:37:25.723978+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -41931,14 +45339,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 9, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "running", "results": {}, "start_time": "2021-11-16T07:37:25.667003+00:00", "last_update": "2021-11-16T07:37:25.667009+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -41982,7 +45397,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 10, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -42035,7 +45456,8 @@ "uid": "481-2", "tag": "latest" } - ] + ], + "retry_count": 0 } }, { @@ -42059,14 +45481,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "running", "results": {}, "start_time": "2021-08-29T20:28:59.571945+00:00", "last_update": "2021-08-29T20:28:59.571951+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -42090,14 +45519,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "running", "results": {}, "start_time": "2021-08-29T20:28:59.571725+00:00", "last_update": "2021-08-29T20:28:59.571731+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -42135,7 +45571,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -42164,7 +45606,8 @@ "uid": "484-0", "tag": "latest" } - ] + ], + "retry_count": 1 } }, { @@ -42188,14 +45631,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "running", "results": {}, "start_time": "2021-08-29T20:28:11.410654+00:00", "last_update": "2021-08-29T20:28:11.410660+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -42219,14 +45669,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "running", "results": {}, "start_time": "2021-08-29T20:28:11.397877+00:00", "last_update": "2021-08-29T20:28:11.397882+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -42264,7 +45721,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -42935,7 +46398,8 @@ "uid": "487-5", "tag": "latest" } - ] + ], + "retry_count": 0 } }, { @@ -42976,7 +46440,13 @@ "inputs": { "dataset": "store://datasets/network-operations-admin/feature_selection_selected_features:cd151783-05df-4f9c-a9db-3aa674e4a058" }, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -43972,7 +47442,8 @@ "uid": "488-6", "tag": "latest" } - ] + ], + "retry_count": 1 } }, { @@ -44013,7 +47484,13 @@ "inputs": { "dataset": "store://datasets/network-operations-admin/feature_selection_selected_features:cd151783-05df-4f9c-a9db-3aa674e4a058" }, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -44992,7 +48469,8 @@ "uid": "489-5", "tag": "latest" } - ] + ], + "retry_count": 0 } }, { @@ -45033,7 +48511,13 @@ "inputs": { "dataset": "store://datasets/network-operations-admin/feature_selection_selected_features:cd151783-05df-4f9c-a9db-3aa674e4a058" }, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 8, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -46029,7 +49513,8 @@ "uid": "490-6", "tag": "latest" } - ] + ], + "retry_count": 2 } }, { @@ -46077,7 +49562,13 @@ "hyper_param_options": { "selector": "max.accuracy" }, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -47170,7 +50661,8 @@ "uid": "491-7", "tag": "latest" } - ] + ], + "retry_count": 1 } }, { @@ -47214,7 +50706,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -47324,7 +50822,8 @@ "uid": "492-5", "tag": "latest" } - ] + ], + "retry_count": 2 } }, { @@ -47364,7 +50863,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -49889,7 +53394,8 @@ "uid": "493-9", "tag": "latest" } - ] + ], + "retry_count": 1 } }, { @@ -49934,7 +53440,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -50072,7 +53584,8 @@ "uid": "494-5", "tag": "latest" } - ] + ], + "retry_count": 0 } }, { @@ -50124,7 +53637,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -53006,7 +56525,8 @@ "uid": "495-0", "tag": "latest" } - ] + ], + "retry_count": 1 } }, { @@ -53045,7 +56565,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -53183,7 +56709,8 @@ "uid": "496-5", "tag": "latest" } - ] + ], + "retry_count": 2 } }, { @@ -53234,7 +56761,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -56116,7 +59649,8 @@ "uid": "497-0", "tag": "latest" } - ] + ], + "retry_count": 0 } }, { @@ -56154,7 +59688,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -56264,7 +59804,8 @@ "uid": "498-5", "tag": "latest" } - ] + ], + "retry_count": 2 } }, { @@ -56288,7 +59829,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "running", @@ -56873,7 +60420,8 @@ "uid": "499-0", "tag": "latest" } - ] + ], + "retry_count": 1 } }, { @@ -56918,14 +60466,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "pending", "results": {}, "start_time": "2021-10-01T00:00:00.277689+00:00", "last_update": "2021-10-01T00:00:12.345881+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -56973,7 +60528,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -56981,7 +60542,8 @@ "start_time": "2021-09-01T00:00:07.362502+00:00", "last_update": "2021-09-01T00:00:07.556686+00:00", "error": "file type unhandled dataset", - "artifacts": [] + "artifacts": [], + "retry_count": 0 } }, { @@ -57018,7 +60580,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 6, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", @@ -57026,7 +60594,8 @@ "start_time": "2021-08-31T12:28:09.838061+00:00", "last_update": "2021-08-31T12:28:10.003381+00:00", "error": "file type unhandled table", - "artifacts": [] + "artifacts": [], + "retry_count": 1 } }, { @@ -57062,7 +60631,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -57091,7 +60666,8 @@ "uid": "503-0", "tag": "latest" } - ] + ], + "retry_count": 0 } }, { @@ -57127,7 +60703,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -57746,7 +61328,8 @@ "uid": "504-4", "tag": "latest" } - ] + ], + "retry_count": 0 } }, { @@ -57786,7 +61369,13 @@ "inputs": { "dataset": "store://datasets/sk-project-admin/get-data_iris_dataset:a0e31343-3be8-4aa2-9de5-0e54342f8e1a" }, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -58664,7 +62253,8 @@ "uid": "505-5", "tag": "latest" } - ] + ], + "retry_count": 1 } }, { @@ -58704,7 +62294,13 @@ "inputs": { "dataset": "store://datasets/sk-project-admin/get-data_iris_dataset:a0e31343-3be8-4aa2-9de5-0e54342f8e1a" }, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -59565,7 +63161,8 @@ "uid": "506-4", "tag": "latest" } - ] + ], + "retry_count": 0 } }, { @@ -59605,7 +63202,13 @@ "inputs": { "dataset": "store://datasets/sk-project-admin/get-data_iris_dataset:a0e31343-3be8-4aa2-9de5-0e54342f8e1a" }, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -60483,7 +64086,8 @@ "uid": "507-5", "tag": "latest" } - ] + ], + "retry_count": 1 } }, { @@ -60518,7 +64122,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 7, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -60628,7 +64238,8 @@ "uid": "508-5", "tag": "latest" } - ] + ], + "retry_count": 0 } }, { @@ -60675,7 +64286,13 @@ "hyper_param_options": { "selector": "max.accuracy" }, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 12, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -61645,7 +65262,8 @@ "uid": "509-6", "tag": "latest" } - ] + ], + "retry_count": 0 } }, { @@ -61679,7 +65297,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 4, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -62193,7 +65817,8 @@ "uid": "510-0", "tag": "latest" } - ] + ], + "retry_count": 1 } }, { @@ -62224,7 +65849,13 @@ }, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 3, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -62334,7 +65965,8 @@ "uid": "511-5", "tag": "latest" } - ] + ], + "retry_count": 1 } }, { @@ -62361,7 +65993,13 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -62875,7 +66513,8 @@ "uid": "512-0", "tag": "latest" } - ] + ], + "retry_count": 1 } }, { @@ -62907,14 +66546,21 @@ "inputs": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "error", "results": {}, "start_time": "2021-10-28T13:52:42.987115+00:00", "last_update": "2021-10-28T13:52:55.115320+00:00", - "artifacts": [] + "artifacts": [], + "retry_count": 2 } }, { @@ -62960,7 +66606,13 @@ "hyper_param_options": { "selector": "max.accuracy" }, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 5, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "state": "completed", @@ -67755,7 +71407,8 @@ "uid": "514-7", "tag": "latest" } - ] + ], + "retry_count": 0 } }, { @@ -67792,7 +71445,13 @@ "node_selector": {}, "hyperparams": {}, "hyper_param_options": {}, - "data_stores": [] + "data_stores": [], + "retry": { + "count": 11, + "backoff": { + "base_delay": "30s" + } + } }, "status": { "results": {}, @@ -67800,8 +71459,61 @@ "last_update": "2024-10-08T14:34:12.621378+00:00", "state": "aborted", "abort_task_id": "74be3e06-56fb-4bc9-9ece-b77f7f818373", - "status_text": "aborted" + "status_text": "aborted", + "retry_count": 2 + } + }, + { + "kind": "run", + "metadata": { + "name": "test-func-oyn-handler", + "uid": "98418b756c4b4307be9a3e7c39e66f21", + "iteration": 0, + "project": "default", + "labels": { + "v3io_user": "normal-user", + "kind": "job", + "owner": "normal-user", + "mlrun/client_version": "1.10.0-rc23", + "mlrun/client_python_version": "3.9.18", + "host": "test-func-oyn-handler-h9xjm" + }, + "annotations": {} + }, + "spec": { + "function": "default/test-func-oyn@93124a9c66fcefbe27b24109a729691f8dbea5c0", + "log_level": "info", + "parameters": {}, + "handler": "handler", + "outputs": [], + "output_path": "v3io:///projects/mm-alerts-proj/artifacts", + "inputs": {}, + "notifications": [], + "state_thresholds": { + "pending_scheduled": "1h", + "pending_not_scheduled": "-1", + "image_pull_backoff": "1h", + "executing": "24h" + }, + "node_selector": {}, + "tolerations": {}, + "affinity": {}, + "retry": {}, + "hyperparams": {}, + "hyper_param_options": {}, + "data_stores": [] + }, + "status": { + "results": {}, + "start_time": "2025-09-04T12:45:48.586000+00:00", + "last_update": "2025-09-04T12:45:48.925000+00:00", + "retry_count": null, + "retries": [], + "state": "error", + "artifact_uris": {}, + "error": "This function intentionally fails", + "end_time": "2025-09-04T12:45:48.870872+00:00" } } ] -} \ No newline at end of file +} diff --git a/tests/mockServer/data/summary.json b/tests/mockServer/data/summary.json index 39f881e417..d11ade74e3 100644 --- a/tests/mockServer/data/summary.json +++ b/tests/mockServer/data/summary.json @@ -5,96 +5,141 @@ "endpoint_alerts_count": 4, "job_alerts_count": 2, "other_alerts_count": 6, + "failed_model_monitoring_functions": 2, "files_count": 13000, "feature_sets_count": 0, "models_count": 13000, "runs_completed_recent_count": 0, "runs_failed_recent_count": 0, + "batch_model_endpoint_count": 0, + "real_time_model_endpoint_count": 3, "runs_running_count": 3, + "running_model_monitoring_functions": 3, "distinct_schedules_count": 0, "distinct_scheduled_jobs_pending_count": 1, "distinct_scheduled_pipelines_pending_count": 0, "pipelines_completed_recent_count": 0, "pipelines_failed_recent_count": 0, - "pipelines_running_count": 0 + "pipelines_running_count": 0, + "datasets_count": 2, + "documents_count": 3, + "llm_prompts_count": 1 }, { "name": "cat-vs-dog-classification", "endpoint_alerts_count": 4, "job_alerts_count": 2, "other_alerts_count": 6, + "failed_model_monitoring_functions": 6, "files_count": 2, "feature_sets_count": 0, "models_count": 0, "runs_completed_recent_count": 0, "runs_failed_recent_count": 0, + "batch_model_endpoint_count": 0, + "real_time_model_endpoint_count": 3, "runs_running_count": 3, + "running_model_monitoring_functions": 3, "distinct_schedules_count": 0, "distinct_scheduled_jobs_pending_count": 1, "distinct_scheduled_pipelines_pending_count": 0, "pipelines_completed_recent_count": 0, "pipelines_failed_recent_count": 0, - "pipelines_running_count": 0 + "pipelines_running_count": 0, + "datasets_count": 1, + "documents_count": 4, + "llm_prompts_count": 2 }, { "name": "churn-project-admin", + "endpoint_alerts_count": 4, + "job_alerts_count": 2, + "other_alerts_count": 6, "files_count": 7, "feature_sets_count": 1, + "failed_model_monitoring_functions": 1, "models_count": 5, "runs_completed_recent_count": 0, "runs_failed_recent_count": 0, + "batch_model_endpoint_count": 0, + "real_time_model_endpoint_count": 0, "runs_running_count": 0, + "running_model_monitoring_functions": 0, "distinct_schedules_count": 0, "distinct_scheduled_jobs_pending_count": 2, "distinct_scheduled_pipelines_pending_count": 0, "pipelines_completed_recent_count": 0, "pipelines_failed_recent_count": 0, - "pipelines_running_count": 0 + "pipelines_running_count": 0, + "datasets_count": 4, + "documents_count": 2, + "llm_prompts_count": 3 }, { "name": "default", "endpoint_alerts_count": 3, - "project.job_alerts_count": 6, + "job_alerts_count": 6, "other_alerts_count": 1, + "failed_model_monitoring_functions": 1, "files_count": 2, "feature_sets_count": 23, "models_count": 1, "runs_completed_recent_count": 0, "runs_failed_recent_count": 1, + "batch_model_endpoint_count": 1, + "real_time_model_endpoint_count": 7, "runs_running_count": 7, + "running_model_monitoring_functions": 7, "distinct_schedules_count": 0, "distinct_scheduled_jobs_pending_count": 2, "distinct_scheduled_pipelines_pending_count": 0, "pipelines_completed_recent_count": 0, "pipelines_failed_recent_count": 0, - "pipelines_running_count": 0 + "pipelines_running_count": 0, + "datasets_count": 2, + "documents_count": 1, + "llm_prompts_count": 4 }, { "name": "fraud-demo2-admin", "endpoint_alerts_count": 1, "job_alerts_count": 8, "other_alerts_count": 2, + "failed_model_monitoring_functions": 2, "files_count": 0, "feature_sets_count": 1, "models_count": 0, "runs_completed_recent_count": 0, "runs_failed_recent_count": 0, + "batch_model_endpoint_count": 0, + "real_time_model_endpoint_count": 0, "runs_running_count": 0, + "running_model_monitoring_functions": 0, "distinct_schedules_count": 0, "distinct_scheduled_jobs_pending_count": 0, "distinct_scheduled_pipelines_pending_count": 0, "pipelines_completed_recent_count": 0, "pipelines_failed_recent_count": 0, - "pipelines_running_count": 0 + "pipelines_running_count": 0, + "datasets_count": 3, + "documents_count": 2, + "llm_prompts_count": 2 }, { "name": "fsdemo-admin", + "endpoint_alerts_count": 4, + "job_alerts_count": 2, + "other_alerts_count": 6, + "failed_model_monitoring_functions": 0, "files_count": 0, "feature_sets_count": 4, "models_count": 0, "runs_completed_recent_count": 0, "runs_failed_recent_count": 0, + "batch_model_endpoint_count": 0, + "real_time_model_endpoint_count": 0, "runs_running_count": 0, + "running_model_monitoring_functions": 0, "distinct_schedules_count": 0, "distinct_scheduled_jobs_pending_count": 0, "distinct_scheduled_pipelines_pending_count": 0, @@ -104,168 +149,328 @@ }, { "name": "getting-started-tutorial-admin", + "endpoint_alerts_count": 4, + "job_alerts_count": 2, + "other_alerts_count": 6, + "failed_model_monitoring_functions": 1, "files_count": 1, "feature_sets_count": 0, "models_count": 2, "runs_completed_recent_count": 0, "runs_failed_recent_count": 0, + "batch_model_endpoint_count": 0, + "real_time_model_endpoint_count": 1, "runs_running_count": 1, + "running_model_monitoring_functions": 1, "distinct_schedules_count": 0, "distinct_scheduled_jobs_pending_count": 1, "distinct_scheduled_pipelines_pending_count": 0, "pipelines_completed_recent_count": 0, "pipelines_failed_recent_count": 0, - "pipelines_running_count": 0 + "pipelines_running_count": 0, + "datasets_count": 2, + "documents_count": 1, + "llm_prompts_count": 4 }, { "name": "hedi-proj", + "endpoint_alerts_count": 4, + "job_alerts_count": 2, + "other_alerts_count": 6, + "failed_model_monitoring_functions": 0, "files_count": 0, "feature_sets_count": 0, "models_count": 0, "runs_completed_recent_count": 0, "runs_failed_recent_count": 0, + "batch_model_endpoint_count": 0, + "real_time_model_endpoint_count": 0, "runs_running_count": 0, + "running_model_monitoring_functions": 0, "distinct_schedules_count": 0, "distinct_scheduled_jobs_pending_count": 0, "distinct_scheduled_pipelines_pending_count": 0, "pipelines_completed_recent_count": 0, "pipelines_failed_recent_count": 0, - "pipelines_running_count": 0 + "pipelines_running_count": 0, + "datasets_count": 2, + "documents_count": 1, + "llm_prompts_count": 4 }, { "name": "mask-detection", + "endpoint_alerts_count": 0, + "job_alerts_count": 0, + "other_alerts_count": 0, + "failed_model_monitoring_functions": 0, "files_count": 0, "feature_sets_count": 0, "models_count": 0, "runs_completed_recent_count": 0, "runs_failed_recent_count": 0, + "batch_model_endpoint_count": 0, + "real_time_model_endpoint_count": 0, "runs_running_count": 0, + "running_model_monitoring_functions": 0, "distinct_schedules_count": 0, "distinct_scheduled_jobs_pending_count": 0, "distinct_scheduled_pipelines_pending_count": 0, "pipelines_completed_recent_count": 0, "pipelines_failed_recent_count": 0, - "pipelines_running_count": 0 + "pipelines_running_count": 0, + "datasets_count": 2, + "documents_count": 1, + "llm_prompts_count": 4 }, { "name": "model-deployment-pipeline-admin", + "endpoint_alerts_count": 0, + "job_alerts_count": 0, + "other_alerts_count": 0, + "failed_model_monitoring_functions": 0, "files_count": 0, "feature_sets_count": 0, "models_count": 0, "runs_completed_recent_count": 0, "runs_failed_recent_count": 0, + "batch_model_endpoint_count": 0, + "real_time_model_endpoint_count": 0, "runs_running_count": 0, + "running_model_monitoring_functions": 0, "distinct_schedules_count": 0, "distinct_scheduled_jobs_pending_count": 0, "distinct_scheduled_pipelines_pending_count": 0, "pipelines_completed_recent_count": 0, "pipelines_failed_recent_count": 0, - "pipelines_running_count": 0 + "pipelines_running_count": 0, + "datasets_count": 2, + "documents_count": 1, + "llm_prompts_count": 4 }, { "name": "moreofthesame", + "endpoint_alerts_count": 0, + "job_alerts_count": 0, + "other_alerts_count": 0, + "failed_model_monitoring_functions": 0, "files_count": 0, "feature_sets_count": 0, "models_count": 0, "runs_completed_recent_count": 0, "runs_failed_recent_count": 0, + "batch_model_endpoint_count": 2, + "real_time_model_endpoint_count": 2, "runs_running_count": 2, + "running_model_monitoring_functions": 2, "distinct_schedules_count": 0, "distinct_scheduled_jobs_pending_count": 0, "distinct_scheduled_pipelines_pending_count": 0, "pipelines_completed_recent_count": 0, "pipelines_failed_recent_count": 0, - "pipelines_running_count": 0 + "pipelines_running_count": 0, + "datasets_count": 2, + "documents_count": 1, + "llm_prompts_count": 4 }, { "name": "network-operations", + "endpoint_alerts_count": 0, + "job_alerts_count": 0, + "other_alerts_count": 0, + "failed_model_monitoring_functions": 0, "files_count": 0, "feature_sets_count": 0, "models_count": 0, "runs_completed_recent_count": 0, "runs_failed_recent_count": 0, + "batch_model_endpoint_count": 0, + "real_time_model_endpoint_count": 0, "runs_running_count": 0, + "running_model_monitoring_functions": 0, "distinct_schedules_count": 0, "distinct_scheduled_jobs_pending_count": 0, "distinct_scheduled_pipelines_pending_count": 0, "pipelines_completed_recent_count": 0, "pipelines_failed_recent_count": 0, - "pipelines_running_count": 0 + "pipelines_running_count": 0, + "datasets_count": 2, + "documents_count": 1, + "llm_prompts_count": 4 }, { "name": "network-operations-admin", + "endpoint_alerts_count": 0, + "job_alerts_count": 0, + "other_alerts_count": 0, + "failed_model_monitoring_functions": 13, "files_count": 13, "feature_sets_count": 0, "models_count": 6, "runs_completed_recent_count": 0, "runs_failed_recent_count": 0, + "batch_model_endpoint_count": 3, + "real_time_model_endpoint_count": 3, "runs_running_count": 3, + "running_model_monitoring_functions": 3, "distinct_schedules_count": 0, "distinct_scheduled_jobs_pending_count": 0, "distinct_scheduled_pipelines_pending_count": 0, "pipelines_completed_recent_count": 0, "pipelines_failed_recent_count": 0, - "pipelines_running_count": 0 + "pipelines_running_count": 0, + "datasets_count": 2, + "documents_count": 1, + "llm_prompts_count": 4 }, { "name": "sk-project-admin", + "endpoint_alerts_count": 0, + "job_alerts_count": 0, + "other_alerts_count": 0, + "failed_model_monitoring_functions": 4, "files_count": 4, "feature_sets_count": 0, "models_count": 3, "runs_completed_recent_count": 0, "runs_failed_recent_count": 0, + "batch_model_endpoint_count": 1, + "real_time_model_endpoint_count": 1, "runs_running_count": 1, + "running_model_monitoring_functions": 1, "distinct_schedules_count": 0, "distinct_scheduled_jobs_pending_count": 1, "distinct_scheduled_pipelines_pending_count": 0, "pipelines_completed_recent_count": 0, "pipelines_failed_recent_count": 0, - "pipelines_running_count": 0 + "pipelines_running_count": 0, + "datasets_count": 2, + "documents_count": 1, + "llm_prompts_count": 4 }, { "name": "stocks", + "endpoint_alerts_count": 0, + "job_alerts_count": 0, + "other_alerts_count": 0, + "failed_model_monitoring_functions": 0, "files_count": 0, "feature_sets_count": 2, "models_count": 0, "runs_completed_recent_count": 0, "runs_failed_recent_count": 0, + "batch_model_endpoint_count": 0, + "real_time_model_endpoint_count": 0, "runs_running_count": 0, + "running_model_monitoring_functions": 0, "distinct_schedules_count": 0, "distinct_scheduled_jobs_pending_count": 0, "distinct_scheduled_pipelines_pending_count": 0, "pipelines_completed_recent_count": 0, "pipelines_failed_recent_count": 0, - "pipelines_running_count": 0 + "pipelines_running_count": 0, + "datasets_count": 2, + "documents_count": 1, + "llm_prompts_count": 4 }, { "name": "stocks-admin", + "endpoint_alerts_count": 0, + "job_alerts_count": 0, + "other_alerts_count": 0, + "failed_model_monitoring_functions": 0, "files_count": 0, "feature_sets_count": 2, "models_count": 0, "runs_completed_recent_count": 0, "runs_failed_recent_count": 0, + "batch_model_endpoint_count": 0, + "real_time_model_endpoint_count": 0, "runs_running_count": 0, "distinct_schedules_count": 0, "distinct_scheduled_jobs_pending_count": 0, "distinct_scheduled_pipelines_pending_count": 0, "pipelines_completed_recent_count": 0, "pipelines_failed_recent_count": 0, - "pipelines_running_count": 0 + "pipelines_running_count": 0, + "datasets_count": 2, + "documents_count": 1, + "llm_prompts_count": 4 }, { "name": "test-test", + "endpoint_alerts_count": 0, + "job_alerts_count": 0, + "other_alerts_count": 0, + "failed_model_monitoring_functions": 1, "files_count": 1, "feature_sets_count": 0, "models_count": 0, "runs_completed_recent_count": 0, "runs_failed_recent_count": 0, + "batch_model_endpoint_count": 0, + "real_time_model_endpoint_count": 0, "runs_running_count": 0, "distinct_schedules_count": 0, "distinct_scheduled_jobs_pending_count": 0, "distinct_scheduled_pipelines_pending_count": 0, "pipelines_completed_recent_count": 0, "pipelines_failed_recent_count": 0, - "pipelines_running_count": 0 + "pipelines_running_count": 0, + "datasets_count": 2, + "documents_count": 1, + "llm_prompts_count": 4 + }, + { + "name": "llmdeploy335", + "files_count": 0, + "feature_sets_count": 0, + "models_count": 1, + "runs_completed_recent_count": 0, + "runs_failed_recent_count": 0, + "runs_running_count": 0, + "distinct_schedules_count": 0, + "distinct_scheduled_jobs_pending_count": 0, + "distinct_scheduled_pipelines_pending_count": 0, + "pipelines_completed_recent_count": 0, + "pipelines_failed_recent_count": 0, + "pipelines_running_count": 0, + "updated": "2025-09-22T17:55:02.296348+00:00", + "endpoint_alerts_count": 0, + "job_alerts_count": 0, + "other_alerts_count": 0, + "datasets_count": 0, + "documents_count": 0, + "llm_prompts_count": 1, + "running_model_monitoring_functions": 0, + "failed_model_monitoring_functions": 0, + "real_time_model_endpoint_count": 1, + "batch_model_endpoint_count": 0 + }, + { + "name": "llmdeploy332", + "files_count": 0, + "feature_sets_count": 0, + "models_count": 1, + "runs_completed_recent_count": 0, + "runs_failed_recent_count": 0, + "runs_running_count": 0, + "distinct_schedules_count": 0, + "distinct_scheduled_jobs_pending_count": 0, + "distinct_scheduled_pipelines_pending_count": 0, + "pipelines_completed_recent_count": 0, + "pipelines_failed_recent_count": 0, + "pipelines_running_count": 0, + "updated": "2025-09-22T18:01:05.616740+00:00", + "endpoint_alerts_count": 0, + "job_alerts_count": 0, + "other_alerts_count": 0, + "datasets_count": 0, + "documents_count": 0, + "llm_prompts_count": 1, + "running_model_monitoring_functions": 0, + "failed_model_monitoring_functions": 0, + "real_time_model_endpoint_count": 1, + "batch_model_endpoint_count": 0 } ] } diff --git a/tests/mockServer/dataGenerators.js b/tests/mockServer/dataGenerators.js index 288dc83825..d9601c546f 100644 --- a/tests/mockServer/dataGenerators.js +++ b/tests/mockServer/dataGenerators.js @@ -31,6 +31,8 @@ export function makeUID(length) { return result } +export const makeHash = () => Math.random().toString(16).substring(2, 42) + export const generateArtifacts = existingArtifacts => { const artifactKinds = ['dataset', 'model', 'document', 'artifact'] const getArtifactTemplate = i => ({ @@ -64,6 +66,243 @@ export const generateArtifacts = existingArtifacts => { }, status: {} }) + + // unique model with unique prompt + const getModelWithPrompt = i => { + const modelKey = `model_${i}_${makeUID(6)}` + const modelUid = makeUID(32) + const modelTree = makeUID(32) + const modelHash = makeHash() + + const model = { + kind: 'model', + metadata: { + project: 'auto-generated-data', + uid: modelUid, + key: modelKey, + iter: 0, + tree: modelTree, + hash: modelHash, + updated: new Date().toISOString(), + created: new Date().toISOString(), + tag: 'latest' + }, + spec: { + target_path: `v3io:///projects/auto-generated-data/artifacts/${modelKey}`, + size: 4000, + license: '', + framework: '', + db_key: modelKey, + has_children: true, + model_file: 'RandomForestClassifier_file1.pkl', + parameters: { + default_config: { + model_version: '4' + } + }, + producer: { + kind: 'project', + name: 'auto-generated-data', + tag: modelTree, + owner: 'auto-user' + }, + parent_uri: null + }, + status: { state: 'created' }, + project: 'auto-generated-data' + } + + const promptKey = `prompt_${i}_${makeUID(6)}` + const promptHash = makeHash() + + const promptLabels = [ + { type: 'single-turn', language: 'english' }, + { type: 'multi-turn', language: 'ukrainian' }, + { type: 'qa', language: 'polish' }, + { type: 'complex', language: 'english' }, + { type: 'instruction-following', language: 'german' } + ] + const randomLabels = promptLabels[Math.floor(Math.random() * promptLabels.length)] + + + const prompt = { + kind: 'llm-prompt', + metadata: { + project: 'auto-generated-data', + uid: makeUID(32), + key: promptKey, + iter: 0, + tree: makeUID(32), + hash: promptHash, + labels: randomLabels, + updated: new Date().toISOString(), + created: new Date().toISOString(), + tag: 'latest' + }, + spec: { + target_path: `v3io:///projects/auto-generated-data/artifacts/${promptKey}`, + size: 256, + license: '', + invocation_config: { + temperature: 0.5 + }, + db_key: promptKey, + parent_uri: `store://models/auto-generated-data/${modelKey}#0:v1@${modelUid}`, + has_children: false, + prompt_legend: { + something_with_meaning: { + field: 'word', + description: 'The essence of all things' + } + }, + prompt_template: [ + { role: 'system', content: "don't tell them anything" }, + { role: 'user', content: 'What is the meaning of {something_with_meaning}?' }, + { role: 'system', content: 'tell you story' }, + { role: 'user', content: 'What is the biggest of {country} at all?' } + ], + producer: { + kind: 'project', + name: 'auto-generated-data', + tag: modelTree, + owner: 'auto-user' + } + }, + status: { state: 'created' }, + project: 'auto-generated-data' + } + + return [model, prompt] + } + + // mix - model shared prompts, prompts per model + const getMixedModelWithPrompt = (modelIndex, existingPromptsPool = []) => { + const modelKey = 'mix_model_' + makeUID(6) + const modelUid = makeUID(32) + const modelTree = makeUID(32) + const modelHash = makeUID(40) + + const model = { + kind: 'model', + metadata: { + project: 'auto-generated-data', + uid: modelUid, + key: modelKey, + iter: 0, + tree: modelTree, + hash: modelHash, + updated: new Date().toISOString(), + created: new Date().toISOString(), + tag: 'latest' + }, + spec: { + target_path: `v3io:///projects/auto-generated-data/artifacts/${modelKey}`, + size: 4000, + license: '', + framework: '', + db_key: modelKey, + has_children: true, + model_file: 'RandomForestClassifier_file1.pkl', + parameters: { + default_config: { + model_version: '4' + } + }, + producer: { + kind: 'project', + name: 'auto-generated-data', + tag: modelTree, + owner: 'auto-user' + }, + parent_uri: null + }, + status: { state: 'created' }, + project: 'auto-generated-data' + } + + const prompts = new Array(Math.floor(Math.random() * 3) + 1).fill().map((_, promptIndex) => { + let prompt + + if (existingPromptsPool.length && Math.random() < 0.5) { + const oldPrompt = existingPromptsPool[Math.floor(Math.random() * existingPromptsPool.length)] + existingPromptsPool + .filter(p => p.metadata.key === oldPrompt.metadata.key) + .forEach(p => p.metadata.tag = '') + prompt = { + ...oldPrompt, + metadata: { + ...oldPrompt.metadata, + tree: makeUID(32), + uid: makeUID(32), + tag: 'latest', + updated: new Date().toISOString(), + created: new Date().toISOString() + }, + spec: { + ...oldPrompt.spec, + parent_uri: `store://models/auto-generated-data/${modelKey}#0:v1@${modelUid}` + } + } + existingPromptsPool.push(prompt) + } else { + const promptKey = `prompt_${modelIndex}_${promptIndex}_${makeUID(6)}` + const promptHash = makeHash() + prompt = { + kind: 'llm-prompt', + metadata: { + project: 'auto-generated-data', + uid: makeUID(32), + key: promptKey, + iter: 0, + tree: makeUID(32), + hash: promptHash, + labels: { + example: 'single', + hebrew: 'english' + }, + updated: new Date().toISOString(), + created: new Date().toISOString(), + tag: 'latest' + }, + spec: { + target_path: `v3io:///projects/auto-generated-data/artifacts/${promptKey}`, + size: 256, + license: '', + invocation_config: { temperature: 0.5 }, + db_key: promptKey, + parent_uri: `store://models/auto-generated-data/${modelKey}#0:v1@${modelUid}`, + has_children: false, + prompt_legend: { + something_with_meaning: { + field: 'word', + description: 'The essence of all things' + } + }, + prompt_template: [ + { role: 'system', content: "don't tell them anything" }, + { role: 'user', content: 'What is the meaning of {something_with_meaning}?' }, + { role: 'system', content: 'tell you story' }, + { role: 'user', content: 'What is the biggest of {country} at all?' } + ], + producer: { + kind: 'project', + name: 'auto-generated-data', + tag: modelTree, + owner: 'auto-user' + } + }, + status: { state: 'created' }, + project: 'auto-generated-data' + } + existingPromptsPool.push(prompt) + } + + return prompt + }) + + return [model, ...prompts] + } + const newArtifactsWithDiffKeys = new Array(40000).fill().map((_, i) => { const artifact = getArtifactTemplate(i) @@ -85,10 +324,25 @@ export const generateArtifacts = existingArtifacts => { return artifact }) + // generate models and mix-prompts + const modelArtifacts = [] + const mixModelArtifacts = [] + const promptPool = [] + + for (let i = 0; i < 100; i++) { + modelArtifacts.push(...getModelWithPrompt(i)) + } + + for (let modelIndex = 0; modelIndex < 100; modelIndex++) { + mixModelArtifacts.push(...getMixedModelWithPrompt(modelIndex, promptPool)) + } + existingArtifacts.artifacts = [ ...existingArtifacts.artifacts, ...newArtifactsWithDiffKeys, - ...newArtifactsWithSameKey + ...newArtifactsWithSameKey, + ...modelArtifacts, + ...mixModelArtifacts ] } diff --git a/tests/mockServer/mock.js b/tests/mockServer/mock.js index 030a64d889..854c98917b 100644 --- a/tests/mockServer/mock.js +++ b/tests/mockServer/mock.js @@ -45,6 +45,7 @@ import { set } from 'lodash' import mime from 'mime-types' +import moment from 'moment' import alerts from './data/alerts.json' import frontendSpec from './data/frontendSpec.json' @@ -213,6 +214,7 @@ const artifactsCategories = { dataset: ['dataset'], document: ['document'], model: ['model'], + 'llm-prompt': ['llm-prompt'], other: ['', 'table', 'link', 'plot', 'chart', 'plotly', 'artifact'] } @@ -389,7 +391,14 @@ function filterByLabels(elementLabels, requestLabels) { function getPartitionedData(listOfItems, pathToPartition, pathToUpdated, defaultPathToPartition) { return chain(listOfItems) - .groupBy(arrayItem => get(arrayItem, pathToPartition, defaultPathToPartition)) + .groupBy(item => { + if (Array.isArray(pathToPartition)) { + return pathToPartition + .map(path => get(item, path, get(item, defaultPathToPartition))) + .join('||') + } + return get(item, pathToPartition, defaultPathToPartition) + }) .map(group => maxBy(group, groupItem => new Date(get(groupItem, pathToUpdated)))) .value() } @@ -431,9 +440,13 @@ function getFeatureSet(req, res) { } if (req.query['name']) { - collectedFeatureSets = collectedFeatureSets.filter(featureSet => - featureSet.metadata.name.includes(req.query['name'].slice(1)) - ) + collectedFeatureSets = collectedFeatureSets.filter(featureSet => { + if (req.query['name'].startsWith?.('~')) { + return featureSet.metadata.name.includes(req.query['name'].slice(1)) + } + + return featureSet.metadata.name === req.query['name'] + }) } if (req.query['label']) { @@ -471,6 +484,27 @@ function createProjectsFeatureSet(req, res) { res.send(featureSet) } +function updateProjectsFeatureSet(req, res) { + let featureSet = req.body + + const featureSetIndex = featureSets.feature_sets.findIndex( + featureSetItem => + req.params.project === featureSetItem.metadata.project && + req.params.name === featureSetItem.metadata.name && + req.params.tag === featureSetItem.metadata.tag && + featureSet.metadata.uid === featureSetItem.metadata.uid + ) + + if (featureSetIndex === -1) { + return createProjectsFeatureSet(req, res) + } + + featureSet.metadata.updated = new Date().toISOString() + featureSets.feature_sets[featureSetIndex] = featureSet + + res.send(featureSet) +} + function deleteFeatureSet(req, res) { const collecledFeatureSet = featureSets.feature_sets .filter(featureSet => featureSet.metadata.project === req.params.project) @@ -802,7 +836,10 @@ function getMonitoringApplications(req, res) { const collectedMonitoringApplications = (monitoringApplications[req.params['project']] || []).map( application => ({ ...application, - stats: omit(application.stats, ['shards', 'processed_model_endpoints', 'metrics']) + stats: { + ...omit(application.stats, ['shards', 'processed_model_endpoints', 'metrics']), + stream_stats: application.stats.stream_stats['0'] + } }) ) @@ -832,11 +869,11 @@ function getMonitoringApplicationsSummary(req, res) { function getMonitoringApplicationData(req, res) { const monitoringApplication = (monitoringApplications[req.params['project']] || []).find( application => { - return application.name === req.params['func'] + return application.name.toLowerCase() === req.params['func'].toLowerCase() } ) - if (monitoringApplication.length === 0) { + if (!monitoringApplication) { res.statusCode = 404 res.send({ detail: "MLRunNotFoundError('Monitoring application not found')" @@ -846,6 +883,27 @@ function getMonitoringApplicationData(req, res) { } } +function getMonitoringApplicationDrift(req, res) { + const data = [] + const endDate = moment(Number(req.query.end) || new Date()) + + for ( + const startDate = moment(Number(req.query.start)); + startDate < endDate; + startDate.add(1, 'minute') + ) { + data.push([ + startDate.utc().format('YYYY-MM-DDTHH:mm:ss.SSS[Z]'), + Math.floor(Math.random() * 11), + Math.floor(Math.random() * 11) + ]) + } + + res.send({ + values: data + }) +} + function getRuns(req, res) { let collectedRuns = runs.runs //get runs for Projects Monitoring page @@ -908,7 +966,13 @@ function getRuns(req, res) { } if (req.query['partition-by'] && req.query['partition-sort-by']) { - collectedRuns = getPartitionedData(collectedRuns, 'metadata.name', 'status.last_update') + const pathToPartition = ['metadata.name'] + + if (req.query['partition-by'] === 'project_and_name') { + pathToPartition.push('metadata.project') + } + + collectedRuns = getPartitionedData(collectedRuns, pathToPartition, 'status.last_update') } if (req.query['name']) { @@ -1248,6 +1312,18 @@ function invokeSchedule(req, res) { res.send(respTemplate) } +function updateSchedule(req, res) { + const existingScheduledJobIndex = schedules.schedules.find( + schedule => + schedule.name === req.params.schedule && + schedule.project === req.body.scheduled_object.task.metadata.project + ) + + existingScheduledJobIndex.scheduled_object = req.body.scheduled_object + + return res.send() +} + function getProjectsFeaturesEntities(req, res) { const artifact = req.path.substring(req.path.lastIndexOf('/') + 1) let collectedArtifacts = [] @@ -1413,6 +1489,7 @@ function getArtifacts(req, res) { collectedArtifacts = collectedArtifacts.filter(artifact => { if (req.query['name'].includes('~')) { const value = artifact.spec?.db_key ?? artifact.db_key + if (req.query['name'].includes('~')) { return value.includes(req.query['name'].slice(1)) } else { @@ -1436,16 +1513,50 @@ function getArtifacts(req, res) { break default: collectedArtifacts = collectedArtifacts.filter( - artifact => - artifact.metadata?.tag === req.query['tag'] || artifact.tag === req.query['tag'] + artifact => artifact.metadata?.tag === req.query['tag'] ) break } } + if (req.query['tree']) { + collectedArtifacts = collectedArtifacts.filter( + artifact => artifact.metadata?.tree === req.query['tree'] + ) + } + + if (req.query['parent']) { + if (req.query['parent'].includes(':')) { + const [key, tag] = req.query['parent'].split(':') + + collectedArtifacts = collectedArtifacts.filter(artifact => { + const match = artifact.spec.parent_uri.match( + /^store:\/\/(?.+?)\/(?.+?)\/(?.+?)(#(?.+?))?(:(?.+?))?(@(?[^^]+))?(\^(?.+))?$/ + ) + + return match && match.groups.key.includes(key) && match.groups.tag.includes(tag) + }) + } else { + collectedArtifacts = collectedArtifacts.filter(artifact => + artifact.spec?.parent_uri + ?.match(/^store:\/\/[^/]+\/[^/]+\/([^#/]+)/)?.[1] + ?.includes(req.query['parent']) + ) + } + } + if (req.query['format'] === 'minimal') { collectedArtifacts = collectedArtifacts.map(func => { - const fieldsToPick = ['db_key', 'producer', 'size', 'target_path', 'framework', 'metrics'] + const fieldsToPick = [ + 'db_key', + 'producer', + 'size', + 'target_path', + 'framework', + 'metrics', + 'has_children', + 'parent_uri' + ] const specFieldsToPick = fieldsToPick.map(fieldName => `spec.${fieldName}`) return pick(func, [ @@ -1460,9 +1571,15 @@ function getArtifacts(req, res) { } if (req.query['partition-by']) { + const pathToPartition = ['spec.db_key'] + + if (req.query['partition-by'] === 'project_and_name') { + pathToPartition.push('metadata.project') + } + collectedArtifacts = getPartitionedData( collectedArtifacts, - 'spec.db_key', + pathToPartition, 'metadata.updated', 'db_key' ) @@ -1697,6 +1814,87 @@ function getPipeline(req, res) { res.send(collectedPipeline) } +function pipelineRetry(req, res) { + const originalPipelineID = pipelineIDs.find( + item => item.run.id === req.params.pipelineID && item.run.project === req.params.project + ) + const originalPipeline = (pipelines[req.params.project]?.runs ?? []).find(pipeline => { + return (pipeline.id = req.params.pipelineID) + }) + if (originalPipeline) { + const runID = makeUID(32) + const newPipelineID = { + ...originalPipelineID, + run: { + ...originalPipelineID.run, + id: runID, + name: `Retry of ${originalPipelineID.run.name}`, + status: 'Running' + } + } + const newPipeline = { + ...originalPipeline, + id: runID, + name: `Retry of ${originalPipeline.name}`, + status: 'Running' + } + + pipelines[req.params.project]?.runs.push(newPipeline) + pipelineIDs.push(newPipelineID) + + setTimeout(() => { + newPipelineID.run.status = 'Failed' + newPipeline.status = 'Failed' + }, 5000) + + res.send(runID) + } else { + res.statusCode = 404 + res.send({ + detail: { + reason: `MLRunNotFoundError('Workflow not found ${req.params.project}/${req.params.pipelineID}')` + } + }) + } +} + +function pipelineTerminate(req, res) { + const { project, pipelineID } = req.params + + const pipeline = (pipelines[project]?.runs ?? []).find(p => p.id === pipelineID) + const pipelineMeta = pipelineIDs.find( + item => item.run.id === pipelineID && item.run.project === project + ) + + if (!pipeline || !pipelineMeta) { + return res.status(404).send({ + detail: { + reason: `MLRunNotFoundError('Workflow not found ${project}/${pipelineID}')` + } + }) + } + + pipeline.status = 'terminating' + pipelineMeta.run.status = 'terminating' + + const taskFunc = () => { + return new Promise(resolve => { + setTimeout(() => { + pipeline.status = 'failed' + pipelineMeta.run.status = 'failed' + resolve() + }, 6000) + }) + } + + const task = createTask(project, { + taskFunc, + kind: `pipeline.termination.wrapper.${pipelineID}` + }) + + res.status(202).send(task) +} + function getFuncs(req, res) { const dt = parseInt(Date.now()) const collectedFuncsByPrjTime = funcs.funcs @@ -1785,7 +1983,9 @@ function getFunc(req, res) { let collectedFuncs = funcs.funcs .filter(func => func.metadata.project === req.params['project']) .filter(func => func.metadata.name === req.params['func']) - .filter(func => func.metadata.hash === req.query.hash_key) + .filter( + func => func.metadata.hash === req.query.hash_key || func.metadata.uid === req.query.hash_key + ) if (req.query.tag) { collectedFuncs = collectedFuncs.filter(func => func.metadata.tag === req.query.tag) @@ -2170,9 +2370,35 @@ function putTags(req, res) { }) if (collectedArtifacts?.length > 0) { - let editedTag = cloneDeep(collectedArtifacts[0]) - editedTag.metadata ? (editedTag.metadata.tag = tagName) : (editedTag.tag = tagName) - artifacts.artifacts.push(editedTag) + let artifactWithEditedTag = cloneDeep(collectedArtifacts[0]) + artifactWithEditedTag.metadata + ? (artifactWithEditedTag.metadata.tag = tagName) + : (artifactWithEditedTag.tag = tagName) + + const collectedArtifactsWithSameName = artifacts.artifacts.filter(artifact => { + return ( + artifact.metadata?.project === req.params.project && + ((artifact.spec && artifact.spec.db_key === req.body.identifiers[0].key) || + artifact.metadata.key === req.body.identifiers[0].key) + ) + }) + + // handle existing artifacts with same name and tag + collectedArtifactsWithSameName.forEach(artifact => { + if (artifact.metadata?.tag === tagName) { + if ( + collectedArtifactsWithSameName.filter( + searchedArtifact => searchedArtifact.metadata.uid === artifact.metadata.uid + ).length > 1 + ) { + remove(artifacts.artifacts, artifact) + } else { + artifact.metadata.tag = null + } + } + }) + + artifacts.artifacts.push(artifactWithEditedTag) } res.send({ @@ -2211,24 +2437,36 @@ function deleteTags(req, res) { function getArtifact(req, res) { let resData - let requestedArtifact = artifacts.artifacts.find( - artifact => + let artifactMatchedByUID = null + let requestedArtifact = artifacts.artifacts.find(artifact => { + if ( + !isNil(req.query.uid) && + (artifact.metadata?.project === req.params.project || + artifact.project === req.params.project) && + (artifact.spec?.db_key === req.params.key || artifact?.db_key === req.params.key) && + artifact.metadata?.uid === req.query.uid + ) { + artifactMatchedByUID = artifact + } + + return ( (artifact.metadata?.project === req.params.project || artifact.project === req.params.project) && (artifact.spec?.db_key === req.params.key || artifact?.db_key === req.params.key) && (isNil(req.query.iter) || +req.query.iter === artifact?.iter || +req.query.iter === artifact.metadata?.iter) && - (isNil(req.query.tag) || - artifact.metadata?.tag === req.query.tag || - artifact?.tag === req.query.tag) && + (isNil(req.query.tag) || artifact.metadata?.tag === req.query.tag) && (isNil(req.query.tree) || artifact.metadata?.tree === req.query.tree || artifact?.tree === req.query.tree) && (isNil(req.query.uid) || - artifact.metadata?.uid === req.query.uid || - artifact?.uid === req.query.uid) - ) + artifact.metadata?.uid === req.query['object-uid'] || + artifact?.uid === req.query['object-uid']) + ) + }) + + requestedArtifact = requestedArtifact ?? artifactMatchedByUID if (requestedArtifact) { resData = requestedArtifact @@ -2418,9 +2656,15 @@ function getModelEndpoints(req, res) { ) } - if (req.query['endpoint_id']) { + if (req.query['mode']) { + collectedEndpoints = collectedEndpoints.filter( + endpoint => Number(endpoint.metadata.mode) === Number(req.query['mode']) + ) + } + + if (req.query['endpoint-id']) { const modelEndpoint = collectedEndpoints.find( - endpoint => endpoint.metadata.uid === req.query.endpoint_id + endpoint => endpoint.metadata.uid === req.query['endpoint-id'] ) return res.send(modelEndpoint) @@ -2755,7 +2999,7 @@ app.get(`${mlrunAPIIngress}/projects/:project/feature-sets`, getFeatureSet) app.post(`${mlrunAPIIngress}/projects/:project/feature-sets`, createProjectsFeatureSet) app.put( `${mlrunAPIIngress}/projects/:project/feature-sets/:name/references/:tag`, - createProjectsFeatureSet + updateProjectsFeatureSet ) app.delete(`${mlrunAPIIngress}/projects/:project/feature-sets/:featureSet`, deleteFeatureSet) @@ -2776,14 +3020,17 @@ app.get( `${mlrunAPIIngress}/projects/:project/model-monitoring/function-summaries`, getMonitoringApplications ) -app.get(`${mlrunAPIIngress}/project-summary/:project`, getMonitoringApplicationsSummary) +app.get(`${mlrunAPIIngress}/project-summaries/:project`, getMonitoringApplicationsSummary) app.get( - `${mlrunAPIIngress}/projects/:project/model-monitoring/function-summary/:func`, + `${mlrunAPIIngress}/projects/:project/model-monitoring/function-summaries/:func`, getMonitoringApplicationData ) +app.get( + `${mlrunAPIIngress}/projects/:project/model-monitoring/drift-over-time`, + getMonitoringApplicationDrift +) app.get(`${mlrunAPIIngress}/projects/:project/runs`, getRuns) -app.get(`${mlrunAPIIngress}/projects/*/runs`, getRuns) app.get(`${mlrunAPIIngress}/projects/:project/alert-activations`, getAlerts) app.get(`${mlrunAPIIngress}/projects/:project/alert-activations/:id`, getAlert) app.get(`${mlrunAPIIngress}/projects/:project/runs/:uid`, getRun) @@ -2799,14 +3046,15 @@ app.get(`${mlrunAPIIngress}/hub/sources/:project/item-object`, getFunctionObject app.get(`${mlrunIngress}/:function/function.yaml`, getFunctionTemplate) app.get(`${mlrunAPIIngress}/projects/:project/schedules`, getProjectsSchedules) -app.get(`${mlrunAPIIngress}/projects/*/schedules`, getProjectsSchedules) app.get(`${mlrunAPIIngress}/projects/:project/schedules/:schedule`, getProjectsSchedule) app.delete(`${mlrunAPIIngress}/projects/:project/schedules/:schedule`, deleteSchedule) app.post(`${mlrunAPIIngress}/projects/:project/schedules/:schedule/invoke`, invokeSchedule) +app.put(`${mlrunAPIIngress}/projects/:project/schedules/:schedule/`, updateSchedule) app.get(`${mlrunAPIIngress}/projects/:project/pipelines`, getPipelines) -app.get(`${mlrunAPIIngress}/projects/*/pipelines`, getPipelines) app.get(`${mlrunAPIIngress}/projects/:project/pipelines/:pipelineID`, getPipeline) +app.post(`${mlrunAPIIngress}/projects/:project/pipelines/:pipelineID/retry`, pipelineRetry) +app.post(`${mlrunAPIIngress}/projects/:project/pipelines/:pipelineID/terminate`, pipelineTerminate) app.get(`${mlrunAPIIngress}/projects/:project/artifact-tags`, getProjectsArtifactTags) app.get(`${mlrunAPIIngressV2}/projects/:project/artifacts`, getArtifacts) @@ -2851,7 +3099,7 @@ app.get(`${mlrunAPIIngress}/projects/:project/functions/:func`, getFunc) app.post(`${mlrunAPIIngress}/projects/:project/functions/:func`, postFunc) app.get( - `${mlrunAPIIngress}/projects/:project/:featureArtifact/*/tags`, + `${mlrunAPIIngress}/projects/:project/:featureArtifact/:name/tags`, getProjectsFeatureArtifactTags ) diff --git a/vite.config.mjs b/vite.config.mjs index b2a3797fcc..0a9b9907c3 100644 --- a/vite.config.mjs +++ b/vite.config.mjs @@ -9,7 +9,7 @@ export default defineConfig(({ mode }) => { const env = loadEnv(mode, path.resolve(process.cwd()), '') return { - plugins: [commonjs(), react(), svgr(), eslint()], + plugins: [commonjs(), react(), svgr(), eslint({ failOnError: false })], base: env.NODE_ENV === 'production' ? env.VITE_PUBLIC_URL : '/', server: { proxy: { @@ -59,7 +59,8 @@ export default defineConfig(({ mode }) => { 'igz-controls': path.resolve( __dirname, 'node_modules/iguazio.dashboard-react-controls/dist' - ) + ), + '@': path.resolve(__dirname, 'src') }, dedupe: [ 'react', @@ -76,7 +77,7 @@ export default defineConfig(({ mode }) => { ] }, optimizeDeps: { - force: true, + force: true }, build: { sourcemap: true, @@ -84,8 +85,10 @@ export default defineConfig(({ mode }) => { chunkSizeWarningLimit: 3000 }, css: { + devSourcemap: true, preprocessorOptions: { scss: { + sourceMap: true, api: 'modern' } } diff --git a/vitest.config.mjs b/vitest.config.mjs new file mode 100644 index 0000000000..6f69c51546 --- /dev/null +++ b/vitest.config.mjs @@ -0,0 +1,12 @@ +import { defineConfig } from 'vitest/config' +import react from '@vitejs/plugin-react-swc' + +export default defineConfig({ + plugins: [react()], + test: { + globals: true, + environment: 'jsdom', + include: ['src/**/*.{test,spec}.{js,jsx}'], + exclude: ['node_modules', 'build', 'dist'], + } +})