瀏覽代碼

[server-ce] tests: optimize sharding (#27635)

* [server-ce] tests: optimize sharding

* [server-ce] tests: remove shard CE_CUSTOM_2

* [server-ce] tests: move project sharing tests onto a new shard

Previously they were on their own CE_CUSTOM_1 shard.

GitOrigin-RevId: de256e04f5956b4651a5dc4ab47cdb5972723c5d
Jakob Ackermann 1 年之前
父節點
當前提交
16daea27ad

+ 12 - 12
server-ce/test/Jenkinsfile

@@ -142,18 +142,6 @@ pipeline {
             }
           }
         }
-        stage('CE custom 2') {
-          environment {
-            CYPRESS_SHARD = "CE_CUSTOM_2"
-            COMPOSE_PROJECT_NAME = "test-ce-custom-2"
-          }
-          steps {
-            script { waitUntil { return job_npm_install_done && job_server_ce_build_done && job_prefetch_default_done && job_prefetch_custom_done } }
-            dir('server-ce/test') {
-              sh 'make test-e2e'
-            }
-          }
-        }
 
         stage('PRO default 1') {
           environment {
@@ -215,6 +203,18 @@ pipeline {
             }
           }
         }
+        stage('PRO custom 4') {
+          environment {
+            CYPRESS_SHARD = "PRO_CUSTOM_4"
+            COMPOSE_PROJECT_NAME = "test-pro-custom-4"
+          }
+          steps {
+            script { waitUntil { return job_npm_install_done && job_server_pro_build_done && job_prefetch_default_done && job_prefetch_custom_done } }
+            dir('server-ce/test') {
+              sh 'make test-e2e'
+            }
+          }
+        }
       }
     }
   }

+ 31 - 1
server-ce/test/cypress.config.js

@@ -1,7 +1,37 @@
 const { defineConfig } = require('cypress')
 const { readPdf, readFileInZip } = require('./helpers/read-file')
+const fs = require('node:fs')
 
-const specPattern = process.env.SPEC_PATTERN || './**/*.spec.{js,ts,tsx}'
+if (process.env.CYPRESS_SHARD && !process.env.SPEC_PATTERN) {
+  // Running Cypress on all the specs is wasteful (~1min) when only few of them
+  // will have relevant tasks to run for a given shard. Filter the spec files
+  // based on the existence of the shard identifier in the spec source.
+  const files = []
+  for (const name of fs.readdirSync('.')) {
+    if (!name.endsWith('.spec.ts')) continue
+    const src = fs.readFileSync(name, 'utf-8')
+    if (!src.includes('isExcludedBySharding(')) {
+      throw new Error(
+        `Spec ${name} is not using sharding. Add an appropriate "'if (isExcludedBySharding('...')) return" call.`
+      )
+    }
+    if (!src.includes(process.env.CYPRESS_SHARD)) continue
+    files.push(name)
+  }
+  if (files.length === 0) {
+    throw new Error(
+      `Bad process.env.CYPRESS_SHARD=${process.env.CYPRESS_SHARD}; no spec files matched!`
+    )
+  }
+  if (files.length === 1) {
+    // Cypress does not like `{single-file}`. Make this a special case.
+    process.env.SPEC_PATTERN = `./${files[0]}`
+  } else {
+    process.env.SPEC_PATTERN = `./{${files.join(',')}}`
+  }
+}
+
+const specPattern = process.env.SPEC_PATTERN || './**/*.spec.ts'
 
 module.exports = defineConfig({
   defaultCommandTimeout: 10_000,

+ 0 - 1
server-ce/test/docker-compose.yml

@@ -76,7 +76,6 @@ services:
       CYPRESS_SHARD:
       CYPRESS_BASE_URL: http://sharelatex
       CYPRESS_FULL_FILESTORE_MIGRATION:
-      SPEC_PATTERN: '**/*.spec.{js,jsx,ts,tsx}'
     depends_on:
       sharelatex:
         condition: service_healthy

+ 1 - 1
server-ce/test/helpers/config.ts

@@ -9,12 +9,12 @@ export function isExcludedBySharding(
     | 'LOCAL_ONLY'
     | 'CE_DEFAULT'
     | 'CE_CUSTOM_1'
-    | 'CE_CUSTOM_2'
     | 'PRO_DEFAULT_1'
     | 'PRO_DEFAULT_2'
     | 'PRO_CUSTOM_1'
     | 'PRO_CUSTOM_2'
     | 'PRO_CUSTOM_3'
+    | 'PRO_CUSTOM_4'
 ) {
   const SHARD = Cypress.env('SHARD')
   return SHARD && shard !== SHARD

+ 1 - 1
server-ce/test/project-sharing.spec.ts

@@ -14,7 +14,7 @@ import { throttledRecompile } from './helpers/compile'
 import { beforeWithReRunOnTestRetry } from './helpers/beforeWithReRunOnTestRetry'
 
 describe('Project Sharing', function () {
-  if (isExcludedBySharding('PRO_CUSTOM_2')) return
+  if (isExcludedBySharding('PRO_CUSTOM_4')) return
   ensureUserExists({ email: 'user@example.com' })
   startWith({ withDataDir: true, pro: true })