Browse Source

[test] cypress: 8x parallel execution

Signed-off-by: Raju Udava <sivadstala@gmail.com>
pull/714/head
Raju Udava 3 years ago
parent
commit
8a14e4dbd3
  1. 227
      .github/workflows/ci-cd.yml
  2. 2
      package.json
  3. 10
      scripts/cypress/cypress.json
  4. 52
      scripts/cypress/integration/test/gqlMisc.js
  5. 49
      scripts/cypress/integration/test/gqlRoles.js
  6. 61
      scripts/cypress/integration/test/gqlTableOps.js
  7. 57
      scripts/cypress/integration/test/gqlViews.js
  8. 52
      scripts/cypress/integration/test/restMisc.js
  9. 49
      scripts/cypress/integration/test/restRoles.js
  10. 62
      scripts/cypress/integration/test/restTableOps.js
  11. 57
      scripts/cypress/integration/test/restViews.js

227
.github/workflows/ci-cd.yml

@ -9,7 +9,7 @@ on:
branches: [master]
jobs:
cypress-rest--run:
cypress-restTableOps-run:
runs-on: ubuntu-20.04
steps:
- name: Checkout
@ -41,11 +41,226 @@ jobs:
npm run start:api
npm run start:web
docker-compose -f ./scripts/docker-compose-cypress.yml up -d
spec: "./scripts/cypress/integration/test/masterSuiteRest.js"
spec: "./scripts/cypress/integration/test/restTableOps.js"
wait-on: "http://localhost:8080, http://localhost:3000/_nuxt/runtime.js"
wait-on-timeout: 1200
config-file: scripts/cypress.json
cypress-graphql-run:
config-file: scripts/cypress/cypress.json
cypress-restViews-run:
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Check for update
run: |
echo "CHANGED=$([[ $(lerna ls --since ${{github.event.before}} | grep nc-gui) = nc-gui ]] && echo 'OK')" >> $GITHUB_ENV
- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: Cypress run
if: ${{ env.CHANGED == 'OK' }}
uses: cypress-io/github-action@v2
with:
start: |
npm run start:api
npm run start:web
docker-compose -f ./scripts/docker-compose-cypress.yml up -d
spec: "./scripts/cypress/integration/test/restViews.js"
wait-on: "http://localhost:8080, http://localhost:3000/_nuxt/runtime.js"
wait-on-timeout: 1200
config-file: scripts/cypress/cypress.json
cypress-restRoles-run:
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Check for update
run: |
echo "CHANGED=$([[ $(lerna ls --since ${{github.event.before}} | grep nc-gui) = nc-gui ]] && echo 'OK')" >> $GITHUB_ENV
- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: Cypress run
if: ${{ env.CHANGED == 'OK' }}
uses: cypress-io/github-action@v2
with:
start: |
npm run start:api
npm run start:web
docker-compose -f ./scripts/docker-compose-cypress.yml up -d
spec: "./scripts/cypress/integration/test/restRoles.js"
wait-on: "http://localhost:8080, http://localhost:3000/_nuxt/runtime.js"
wait-on-timeout: 1200
config-file: scripts/cypress/cypress.json
cypress-restMisc-run:
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Check for update
run: |
echo "CHANGED=$([[ $(lerna ls --since ${{github.event.before}} | grep nc-gui) = nc-gui ]] && echo 'OK')" >> $GITHUB_ENV
- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: Cypress run
if: ${{ env.CHANGED == 'OK' }}
uses: cypress-io/github-action@v2
with:
start: |
npm run start:api
npm run start:web
docker-compose -f ./scripts/docker-compose-cypress.yml up -d
spec: "./scripts/cypress/integration/test/restMisc.js"
wait-on: "http://localhost:8080, http://localhost:3000/_nuxt/runtime.js"
wait-on-timeout: 1200
config-file: scripts/cypress/cypress.json
cypress-gqlTableOps-run:
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Check for update
run: |
echo "CHANGED=$([[ $(lerna ls --since ${{github.event.before}} | grep nc-gui) = nc-gui ]] && echo 'OK')" >> $GITHUB_ENV
- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: Cypress run
if: ${{ env.CHANGED == 'OK' }}
uses: cypress-io/github-action@v2
with:
start: |
npm run start:api
npm run start:web
docker-compose -f ./scripts/docker-compose-cypress.yml up -d
spec: "./scripts/cypress/integration/test/gqlTableOps.js"
wait-on: "http://localhost:8080, http://localhost:3000/_nuxt/runtime.js"
wait-on-timeout: 1200
config-file: scripts/cypress/cypress.json
cypress-gqlViews-run:
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Check for update
run: |
echo "CHANGED=$([[ $(lerna ls --since ${{github.event.before}} | grep nc-gui) = nc-gui ]] && echo 'OK')" >> $GITHUB_ENV
- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: Cypress run
if: ${{ env.CHANGED == 'OK' }}
uses: cypress-io/github-action@v2
with:
start: |
npm run start:api
npm run start:web
docker-compose -f ./scripts/docker-compose-cypress.yml up -d
spec: "./scripts/cypress/integration/test/gqlViews.js"
wait-on: "http://localhost:8080, http://localhost:3000/_nuxt/runtime.js"
wait-on-timeout: 1200
config-file: scripts/cypress/cypress.json
cypress-gqlRoles-run:
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Check for update
run: |
echo "CHANGED=$([[ $(lerna ls --since ${{github.event.before}} | grep nc-gui) = nc-gui ]] && echo 'OK')" >> $GITHUB_ENV
- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: Cypress run
if: ${{ env.CHANGED == 'OK' }}
uses: cypress-io/github-action@v2
with:
start: |
npm run start:api
npm run start:web
docker-compose -f ./scripts/docker-compose-cypress.yml up -d
spec: "./scripts/cypress/integration/test/gqlRoles.js"
wait-on: "http://localhost:8080, http://localhost:3000/_nuxt/runtime.js"
wait-on-timeout: 1200
config-file: scripts/cypress/cypress.json
cypress-gqlMisc-run:
runs-on: ubuntu-20.04
steps:
- name: Checkout
@ -76,10 +291,10 @@ jobs:
npm run start:api
npm run start:web
docker-compose -f ./scripts/docker-compose-cypress.yml up -d
spec: "./scripts/cypress/integration/test/masterSuiteGql.js"
spec: "./scripts/cypress/integration/test/gqlMisc.js"
wait-on: "http://localhost:8080, http://localhost:3000/_nuxt/runtime.js"
wait-on-timeout: 1200
config-file: scripts/cypress.json
config-file: scripts/cypress/cypress.json
docker:
runs-on: ubuntu-latest
steps:

2
package.json

@ -9,7 +9,7 @@
"scripts": {
"start:api": "cd ./packages/nocodb; npm install; npm run watch:run",
"start:web": "cd ./packages/nc-gui; npm install; npm run dev",
"cypress:run": "cypress run --config-file ./scripts/cypress.json",
"cypress:run": "cypress run --config-file ./scripts/cypress/cypress.json",
"cypress:open": "cypress open",
"test:travis": "git log --pretty=format:'%h' -n 1 --skip 1 | xargs lerna run test:travis --since",
"lerna:install": "git log --pretty=format:'%h' -n 1 --skip 1 | xargs lerna bootstrap --ignore nc-cli --since",

10
scripts/cypress.json → scripts/cypress/cypress.json

@ -1,8 +1,14 @@
{
"baseUrl": "http://localhost:3000/",
"testFiles": [
"test/masterSuiteRest.js",
"test/masterSuiteGql.js"
"test/restTableOps.js",
"test/restViews.js",
"test/restRoles.js",
"test/restMisc.js",
"test/gqlTableOps.js",
"test/gqlViews.js",
"test/gqlRoles.js",
"test/gqlMisc.js"
],
"defaultCommandTimeout": 13000,
"pageLoadTimeout": 600000,

52
scripts/cypress/integration/test/gqlMisc.js

@ -0,0 +1,52 @@
let t0 = require('./explicitLogin')
let t01 = require('../common/00_pre_configurations')
let t6c = require('../common/6c_swagger_api')
let t6d = require('../common/6d_language_validation')
let t6e = require('../common/6e_project_operations')
// use 0 as mode to execute individual files (debug mode, skip pre-configs)
// use 1 mode if noco.db doesnt contain user credentials (full run over GIT)
const executionMode = 1
const nocoTestSuite = (type, xcdb) => {
if (0 == executionMode) {
t0.genTest(type, xcdb)
} else {
t01.genTest(type, xcdb)
}
t6c.genTest(type, xcdb)
t6d.genTest(type, xcdb)
// **deletes created project, hence place it @ end
t6e.genTest(type, xcdb)
}
nocoTestSuite('graphql', false)
/**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd
*
* @author Raju Udava <sivadstala@gmail.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

49
scripts/cypress/integration/test/gqlRoles.js

@ -0,0 +1,49 @@
let t0 = require('./explicitLogin')
let t01 = require('../common/00_pre_configurations')
let t5a = require('../common/5a_user_role')
let t5b = require('../common/5b_preview_role')
// use 0 as mode to execute individual files (debug mode, skip pre-configs)
// use 1 mode if noco.db doesnt contain user credentials (full run over GIT)
const executionMode = 1
const nocoTestSuite = (type, xcdb) => {
if (0 == executionMode) {
t0.genTest(type, xcdb)
} else {
t01.genTest(type, xcdb)
}
t5a.genTest(type, xcdb)
t5b.genTest(type, xcdb)
}
nocoTestSuite('graphql', false)
/**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd
*
* @author Raju Udava <sivadstala@gmail.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

61
scripts/cypress/integration/test/gqlTableOps.js

@ -0,0 +1,61 @@
let t0 = require('./explicitLogin')
let t01 = require('../common/00_pre_configurations')
let t1a = require('../common/1a_table_operations')
let t1b = require('../common/1b_table_column_operations')
let t2a = require('../common/2a_table_with_belongs_to_colulmn')
let t2b = require('../common/2b_table_with_m2m_column')
let t3a = require('../common/3a_filter_sort_fields_operations')
let t3b = require('../common/3b_formula_column')
let t3c = require('../common/3c_lookup_column')
let t3d = require('../common/3d_rollup_column')
// use 0 as mode to execute individual files (debug mode, skip pre-configs)
// use 1 mode if noco.db doesnt contain user credentials (full run over GIT)
const executionMode = 1
const nocoTestSuite = (type, xcdb) => {
if (0 == executionMode) {
t0.genTest(type, xcdb)
} else {
t01.genTest(type, xcdb)
}
t1a.genTest(type, xcdb)
t1b.genTest(type, xcdb)
t2a.genTest(type, xcdb)
t2b.genTest(type, xcdb)
t3a.genTest(type, xcdb)
t3b.genTest(type, xcdb)
t3c.genTest(type, xcdb)
t3d.genTest(type, xcdb)
}
nocoTestSuite('graphql', false)
/**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd
*
* @author Raju Udava <sivadstala@gmail.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

57
scripts/cypress/integration/test/gqlViews.js

@ -0,0 +1,57 @@
let t0 = require('./explicitLogin')
let t01 = require('../common/00_pre_configurations')
let t4a = require('../common/4a_table_view_grid_gallery_form')
let t4b = require('../common/4b_table_view_share')
let t4c = require('../common/4c_form_view_detailed')
let t4d = require('../common/4d_table_view_grid_locked')
let t4e = require('../common/4e_form_view_share')
let t4f = require('../common/4f_grid_view_share')
// use 0 as mode to execute individual files (debug mode, skip pre-configs)
// use 1 mode if noco.db doesnt contain user credentials (full run over GIT)
const executionMode = 1
const nocoTestSuite = (type, xcdb) => {
if (0 == executionMode) {
t0.genTest(type, xcdb)
} else {
t01.genTest(type, xcdb)
}
t4a.genTest(type, xcdb)
t4b.genTest(type, xcdb)
t4c.genTest(type, xcdb)
t4d.genTest(type, xcdb)
t4e.genTest(type, xcdb)
t4f.genTest(type, xcdb)
}
nocoTestSuite('graphql', false)
/**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd
*
* @author Raju Udava <sivadstala@gmail.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

52
scripts/cypress/integration/test/restMisc.js

@ -0,0 +1,52 @@
let t0 = require('./explicitLogin')
let t01 = require('../common/00_pre_configurations')
let t6c = require('../common/6c_swagger_api')
let t6d = require('../common/6d_language_validation')
let t6e = require('../common/6e_project_operations')
// use 0 as mode to execute individual files (debug mode, skip pre-configs)
// use 1 mode if noco.db doesnt contain user credentials (full run over GIT)
const executionMode = 1
const nocoTestSuite = (type, xcdb) => {
if (0 == executionMode) {
t0.genTest(type, xcdb)
} else {
t01.genTest(type, xcdb)
}
t6c.genTest(type, xcdb)
t6d.genTest(type, xcdb)
// **deletes created project, hence place it @ end
t6e.genTest(type, xcdb)
}
nocoTestSuite('rest', false)
/**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd
*
* @author Raju Udava <sivadstala@gmail.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

49
scripts/cypress/integration/test/restRoles.js

@ -0,0 +1,49 @@
let t0 = require('./explicitLogin')
let t01 = require('../common/00_pre_configurations')
let t5a = require('../common/5a_user_role')
let t5b = require('../common/5b_preview_role')
// use 0 as mode to execute individual files (debug mode, skip pre-configs)
// use 1 mode if noco.db doesnt contain user credentials (full run over GIT)
const executionMode = 1
const nocoTestSuite = (type, xcdb) => {
if (0 == executionMode) {
t0.genTest(type, xcdb)
} else {
t01.genTest(type, xcdb)
}
t5a.genTest(type, xcdb)
t5b.genTest(type, xcdb)
}
nocoTestSuite('rest', false)
/**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd
*
* @author Raju Udava <sivadstala@gmail.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

62
scripts/cypress/integration/test/restTableOps.js

@ -0,0 +1,62 @@
let t0 = require('./explicitLogin')
let t01 = require('../common/00_pre_configurations')
let t1a = require('../common/1a_table_operations')
let t1b = require('../common/1b_table_column_operations')
let t2a = require('../common/2a_table_with_belongs_to_colulmn')
let t2b = require('../common/2b_table_with_m2m_column')
let t3a = require('../common/3a_filter_sort_fields_operations')
let t3b = require('../common/3b_formula_column')
let t3c = require('../common/3c_lookup_column')
let t3d = require('../common/3d_rollup_column')
// use 0 as mode to execute individual files (debug mode, skip pre-configs)
// use 1 mode if noco.db doesnt contain user credentials (full run over GIT)
const executionMode = 1
const nocoTestSuite = (type, xcdb) => {
if (0 == executionMode) {
t0.genTest(type, xcdb)
} else {
t01.genTest(type, xcdb)
}
t1a.genTest(type, xcdb)
t1b.genTest(type, xcdb)
// merged with t1b: t1c.genTest(type, xcdb)
t2a.genTest(type, xcdb)
t2b.genTest(type, xcdb)
t3a.genTest(type, xcdb)
t3b.genTest(type, xcdb)
t3c.genTest(type, xcdb)
t3d.genTest(type, xcdb)
}
nocoTestSuite('rest', false)
/**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd
*
* @author Raju Udava <sivadstala@gmail.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

57
scripts/cypress/integration/test/restViews.js

@ -0,0 +1,57 @@
let t0 = require('./explicitLogin')
let t01 = require('../common/00_pre_configurations')
let t4a = require('../common/4a_table_view_grid_gallery_form')
let t4b = require('../common/4b_table_view_share')
let t4c = require('../common/4c_form_view_detailed')
let t4d = require('../common/4d_table_view_grid_locked')
let t4e = require('../common/4e_form_view_share')
let t4f = require('../common/4f_grid_view_share')
// use 0 as mode to execute individual files (debug mode, skip pre-configs)
// use 1 mode if noco.db doesnt contain user credentials (full run over GIT)
const executionMode = 1
const nocoTestSuite = (type, xcdb) => {
if (0 == executionMode) {
t0.genTest(type, xcdb)
} else {
t01.genTest(type, xcdb)
}
t4a.genTest(type, xcdb)
t4b.genTest(type, xcdb)
t4c.genTest(type, xcdb)
t4d.genTest(type, xcdb)
t4e.genTest(type, xcdb)
t4f.genTest(type, xcdb)
}
nocoTestSuite('rest', false)
/**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd
*
* @author Raju Udava <sivadstala@gmail.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
Loading…
Cancel
Save