1
0
Fork 0

Add upgrade_data_<VER>_<STORAGE> tests execution possibility (#8458)

This commit is contained in:
KVS85 2019-03-21 18:01:54 +03:00 committed by Jan
parent 0080cdbb8c
commit 2d72c442e8
6 changed files with 407 additions and 2 deletions

1
.gitignore vendored
View File

@ -29,6 +29,7 @@ build
Thumbs.db
enterprise
upgrade-data-tests
compile_commands.json
instanceinfo.json
testresult.json

View File

@ -2,6 +2,5 @@ load_balancing
load_balancing_auth
shell_client_aql
version
upgrade_data_3.2.*
upgrade_data_3.3.*
upgrade_data_3.4.*

View File

@ -63,6 +63,7 @@ function diffArray (arr1, arr2) {
// //////////////////////////////////////////////////////////////////////////////
function makePathUnix (path) {
if(typeof path !== "string" && path !== undefined) { path = path.toString(); }
return fs.join.apply(null, path.split('/'));
}

View File

@ -459,8 +459,16 @@ function unitTest (cases, options) {
// tests to run
let caselist = [];
const expandWildcard = ( name ) => {
if (!name.endsWith('*')) {
return name;
}
const prefix = name.substring(0, name.length - 1);
return allTests.filter( ( s ) => s.startsWith(prefix) ).join(',');
};
for (let n = 0; n < cases.length; ++n) {
let splitted = cases[n].split(/[,;\.|]/);
let splitted = expandWildcard(cases[n]).split(/[,;|]/);
for (let m = 0; m < splitted.length; ++m) {
let which = splitted[m];

View File

@ -0,0 +1,253 @@
/* jshint strict: false, sub: true */
/* global print */
'use strict';
////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2017 ArangoDB GmbH, Cologne, Germany
/// Copyright 2014 triagens GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License")
/// 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.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Dan Larkin-York
////////////////////////////////////////////////////////////////////////////////
const _ = require('lodash');
const fs = require('fs');
const pu = require('@arangodb/process-utils');
const tu = require('@arangodb/test-utils');
const toArgv = require('internal').toArgv;
const optionsDocumentation = [
' - `upgradeDataPath`: path to directory containing upgrade data archives'
];
const compareSemVer = (a, b) => {
if (a === b) {
return 0;
}
let lex = false;
const partsA = a.split('-')[0].split('.');
const partsB = b.split('-')[0].split('.');
if (partsA.length < 2 ||
partsA.length > 4 ||
partsB.length < 2 ||
partsB.length > 4 ||
!partsA.every(p => isNaN(Number(p))) ||
!partsB.every(p => isNaN(Number(b)))) {
return (a < b) ? -1 : 1;
}
for (let i = partsA.length; i < 4; i++) {
partsA.push_back("0");
}
for (let i = partsB.length; i < 4; i++) {
partsB.push_back("0");
}
for (let i = 0; i < 4; i++) {
const numA = Number(partsA[i]);
const numB = Number(partsB[i]);
if (numA < numB) {
return -1;
}
if (numB < numA) {
return 1;
}
}
};
const byMinimumSuportedVersion = (version) => {
return (testCase) => {
let supported = true;
testCase.substring(0, testCase.length - 3).split('-').map((s) => {
if (s.startsWith("msv")) {
const msv = s.substring(3);
if (compareSemVer(msv, version) > 0) {
supported = false;
}
}
});
return supported;
};
};
////////////////////////////////////////////////////////////////////////////////
/// set up the test according to the testcase.
////////////////////////////////////////////////////////////////////////////////
const unpackOldData = (engine, version, options, serverOptions) => {
const archiveName = `upgrade-data-${version}-${engine}`;
const dataFile = fs.join(options.upgradeDataPath,
'data',
`${archiveName}.tar.gz`);
const tarOptions = [
'--extract',
'--gunzip',
`--file=${dataFile}`,
`--directory=${serverOptions['database.directory']}`
];
let unpack = pu.executeAndWait('tar', tarOptions, { disableMonitor: true }, '');
if (unpack.status === false) {
unpack.failed = 1;
return {
status: false,
message: unpack.message
};
}
return {
status: true
};
};
////////////////////////////////////////////////////////////////////////////////
/// testcases themselves
////////////////////////////////////////////////////////////////////////////////
const upgradeData = (engine, version) => {
return (options) => {
const testName = `upgrade_data_${version}_${engine}`;
const dataFile = fs.join(options.upgradeDataPath,
'data',
`upgrade-data-${version}-${engine}.tar.gz`);
if (options.storageEngine !== engine) {
// engine mismatch, skip!
const res = {};
res[testName] = {
failed: 0,
'status': true,
'message': 'skipped because of engine mismatch',
'skipped': true
};
return res;
} else if (!fs.exists(dataFile)) {
// data file missing
const res = {};
if (options.upgradeDataMissingShouldFail) {
res[testName] = {
failed: 1,
'status': false,
'message': `failed due to missing data file ${dataFile}`,
'skipped': false
};
} else {
res[testName] = {
failed: 0,
'status': true,
'message': `skipped due to missing data file ${dataFile}`,
'skipped': true
};
}
return res;
}
const tmpDataDir = fs.join(fs.getTempPath(), testName);
fs.makeDirectoryRecursive(tmpDataDir);
pu.cleanupDBDirectoriesAppend(tmpDataDir);
const appDir = fs.join(tmpDataDir, 'apps');
fs.makeDirectoryRecursive(appDir);
const tmpDir = fs.join(tmpDataDir, 'tmp');
fs.makeDirectoryRecursive(tmpDir);
const dataDir = fs.join(tmpDataDir, 'data');
fs.makeDirectoryRecursive(dataDir);
const port = pu.findFreePort(options.minPort, options.maxPort);
let args = pu.makeArgs.arangod(options, appDir, '', tmpDir);
args['server.endpoint'] = 'tcp://127.0.0.1:' + port;
args['database.directory'] = dataDir;
args['database.auto-upgrade'] = true;
require('internal').print('Unpacking old data...');
let result = unpackOldData(engine, version, options, args);
if (result.status !== true) {
return result;
}
require('internal').print('Running upgrade...');
const argv = toArgv(args);
result = pu.executeAndWait(pu.ARANGOD_BIN, argv, options, 'upgrade', tmpDataDir);
if (result.status !== true) {
return {
failed: 1,
'status': false,
'message': 'upgrade result: ' + result.message,
'skipped': false
};
}
args['database.auto-upgrade'] = false;
const testCases = tu.scanTestPath(['js/server/tests/upgrade-data'])
.filter(byMinimumSuportedVersion(version));
require('internal').print('Checking results...');
return tu.performTests(
options,
testCases,
`upgrade_data_${engine}_${version}`,
tu.runThere,
args);
};
};
exports.setup = function(testFns, defaultFns, opts, fnDocs, optionsDoc) {
const functionsDocumentation = {};
const configurations = fs.list('upgrade-data-tests/data').map(
(filename) => {
const re = /upgrade-data-(\d+(?:\.\d+)*(-\d)?)-(mmfiles|rocksdb)\.tar\.gz/;
const matches = re.exec(filename);
return {
engine: matches[3],
version: matches[1]
};
}
).sort((a, b) => {
const versionDiff = compareSemVer(a.version, b.version);
if (versionDiff !== 0) {
return versionDiff;
}
if (a.engine < b.engine) return -1;
if (a.engine > b.engine) return 1;
return 0;
});
for (let i = 0; i < configurations.length; i++) {
const {
engine,
version
} = configurations[i];
const testName = `upgrade_data_${version}_${engine}`;
testFns[testName] = upgradeData(engine, version);
defaultFns.push(testName);
functionsDocumentation[testName] =
`test upgrade from version ${version} using ${engine} engine`;
}
opts['upgradeDataPath'] = 'upgrade-data-tests';
opts['upgradeDataMissingShouldFail'] = false;
/* jshint forin: false */
for (var attrname in functionsDocumentation) {
fnDocs[attrname] = functionsDocumentation[attrname];
}
for (var i = 0; i < optionsDocumentation.length; i++) {
optionsDoc.push(optionsDocumentation[i]);
}
};

View File

@ -0,0 +1,143 @@
/*jshint globalstrict:false, strict:false */
/*global assertEqual, assertTrue, assertEqual, assertTypeOf, assertNotEqual, fail */
////////////////////////////////////////////////////////////////////////////////
/// @brief test the view interface
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2010-2012 triagens GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// 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.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Dan Larkin-York
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
var jsunity = require("jsunity");
var arangodb = require("@arangodb");
var db = require('internal').db;
////////////////////////////////////////////////////////////////////////////////
/// @brief test suite: upgrade with data from mmfiles instance
////////////////////////////////////////////////////////////////////////////////
function UpgradeData () {
'use strict';
return {
////////////////////////////////////////////////////////////////////////////
/// @brief bad name (empty)
////////////////////////////////////////////////////////////////////////////
testLargeCollection : function () {
const c = db._collection('LargeCollection');
assertEqual(c.count(), 10000);
// verify documents and contents
for (let i = 0; i < 10000; i++) {
const doc = c.document( { _key: `key${i}` } );
assertEqual(doc.even, ( ( i % 2 ) === 0 ));
assertEqual(doc.name, `Name ${i}`);
assertEqual(doc.num, i);
assertEqual(doc.num100, i % 100);
}
// verify indexes
const indices = c.getIndexes();
assertEqual(indices.length, 5);
// primary
assertEqual(indices[0].type, "primary");
assertEqual(indices[0].unique, true);
// unique hash
assertEqual(indices[1].type, "hash");
assertEqual(indices[1].unique, true);
assertEqual(indices[1].fields, [ "num" ]);
const uhQuery =
`FOR doc in LargeCollection
FILTER doc.num == 8 || doc.num == 8001
SORT doc.num ASC
RETURN doc`;
const uhExplain = db._createStatement(uhQuery).explain({});
assertNotEqual(-1, uhExplain.plan.rules.indexOf('use-indexes'));
const uhResults = db._query(uhQuery).toArray();
assertEqual(uhResults.length, 2);
assertEqual(uhResults[0].num, 8);
assertEqual(uhResults[1].num, 8001);
// non-unique hash
assertEqual(indices[2].type, "hash");
assertEqual(indices[2].unique, false);
assertEqual(indices[2].fields, [ "even" ]);
const nhQuery =
`FOR doc in LargeCollection
FILTER doc.even == true
RETURN doc`;
const nhExplain = db._createStatement(nhQuery).explain({});
assertNotEqual(-1, nhExplain.plan.rules.indexOf('use-indexes'));
const nhResults = db._query(nhQuery).toArray();
assertEqual(nhResults.length, 5000);
nhResults.forEach( ( doc ) => { assertTrue(doc.even); } );
// unique skiplist
assertEqual(indices[3].type, "skiplist");
assertEqual(indices[3].unique, true);
assertEqual(indices[3].fields, [ "name" ]);
const usQuery =
`FOR doc in LargeCollection
FILTER doc.name >= "Name 1114" && doc.name <= "Name 1117"
SORT doc.name ASC
RETURN doc`;
const usExplain = db._createStatement(usQuery).explain({});
assertNotEqual(-1, usExplain.plan.rules.indexOf('use-indexes'));
const usResults = db._query(usQuery).toArray();
assertEqual(usResults.length, 4);
assertEqual(usResults[0].name, "Name 1114");
assertEqual(usResults[1].name, "Name 1115");
assertEqual(usResults[2].name, "Name 1116");
assertEqual(usResults[3].name, "Name 1117");
// non-unique skiplist
assertEqual(indices[4].type, "skiplist");
assertEqual(indices[4].unique, false);
assertEqual(indices[4].fields, [ "num100" ]);
const nsQuery =
`FOR doc in LargeCollection
FILTER doc.num100 == 57
RETURN doc`;
const nsExplain = db._createStatement(nsQuery).explain({});
assertNotEqual(-1, nsExplain.plan.rules.indexOf('use-indexes'));
const nsResults = db._query(nsQuery).toArray();
assertEqual(nsResults.length, 100);
nsResults.forEach( ( doc ) => { assertEqual(doc.num100, 57); } );
}
};
}
////////////////////////////////////////////////////////////////////////////////
/// @brief executes the test suites
////////////////////////////////////////////////////////////////////////////////
jsunity.run(UpgradeData);
return jsunity.done();