diff --git a/cypress.config.ts b/cypress.config.ts index 1ea9873d..b8e8eea9 100644 --- a/cypress.config.ts +++ b/cypress.config.ts @@ -1,8 +1,79 @@ import { defineConfig } from 'cypress'; import { plugin as cypressGrepPlugin } from '@cypress/grep/plugin'; +import { execFileSync } from 'child_process'; import * as fs from 'fs'; +import * as path from 'path'; import * as console from 'console'; +const ARTIFACTS_DIR = './gui_test_screenshots/artifacts'; +const OLS_NAMESPACE = 'openshift-lightspeed'; +const OC_TIMEOUT = 30000; + +const CLUSTER_RESOURCES = [ + 'pods', + 'services', + 'deployments', + 'replicasets', + 'routes', + 'rolebindings', + 'serviceaccounts', + 'olsconfig', + 'clusterserviceversion', + 'installplan', + 'configmap', +]; + +function runOC(args: string[], kubeconfigPath: string): string | null { + const argv = kubeconfigPath ? [...args, '--kubeconfig', kubeconfigPath] : args; + try { + return execFileSync('oc', argv, { + encoding: 'utf-8', + timeout: OC_TIMEOUT, + }); + } catch (e: unknown) { + console.error(`oc ${args.slice(0, 3).join(' ')} failed: ${e}`); + return null; + } +} + +function gatherClusterArtifacts(kubeconfigPath: string) { + const clusterDir = path.join(ARTIFACTS_DIR, 'cluster'); + const podLogsDir = path.join(clusterDir, 'podlogs'); + fs.mkdirSync(podLogsDir, { recursive: true }); + + for (const resource of CLUSTER_RESOURCES) { + const output = runOC(['get', resource, '-n', OLS_NAMESPACE, '-o', 'yaml'], kubeconfigPath); + if (output) { + fs.writeFileSync(path.join(clusterDir, `${resource}.yaml`), output); + } + } + + // Pod logs + const podsJson = runOC(['get', 'pods', '-n', OLS_NAMESPACE, '-o', 'json'], kubeconfigPath); + if (podsJson) { + try { + const pods = JSON.parse(podsJson); + for (const pod of pods.items || []) { + const podName = pod.metadata?.name; + const containers = (pod.spec?.containers || []).map((c: { name: string }) => c.name); + for (const container of containers) { + const logs = runOC( + ['logs', `pod/${podName}`, '-c', container, '-n', OLS_NAMESPACE], + kubeconfigPath, + ); + if (logs) { + fs.writeFileSync(path.join(podLogsDir, `${podName}-${container}.log`), logs); + } + } + } + } catch (e: unknown) { + console.error(`Failed to parse pod JSON: ${e}`); + } + } + + console.log(`Cluster artifacts gathered in ${clusterDir}`); +} + export default defineConfig({ screenshotsFolder: './gui_test_screenshots/cypress/screenshots', screenshotOnRunFailure: true, @@ -85,6 +156,8 @@ export default defineConfig({ fs.unlinkSync(results.video); } } + console.log('Gathering cluster artifacts...'); + gatherClusterArtifacts(config.env.KUBECONFIG_PATH || ''); }); return config; },