Merge branch 'al-sync-user-tests' of https://github.com/realm/realm-js into al-sync-user-tests
This commit is contained in:
commit
8bd5ee8be7
41
Dockerfile
41
Dockerfile
|
@ -1,37 +1,8 @@
|
|||
FROM node:6
|
||||
FROM ubuntu:xenial
|
||||
|
||||
# Make debugging quicker.
|
||||
RUN apt-get update && apt-get install -y gdb vim
|
||||
RUN apt-get update && \
|
||||
apt-get install -y curl && \
|
||||
curl -sL https://deb.nodesource.com/setup_4.x | bash - && \
|
||||
apt-get install -y nodejs gcc-4.9 python build-essential
|
||||
|
||||
# Add non-root user.
|
||||
RUN useradd -ms /bin/bash user
|
||||
|
||||
# Make our workspace directory and work from there.
|
||||
RUN mkdir -p /usr/src/app
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
# Get the node_modules setup before anything else.
|
||||
COPY package.json .
|
||||
RUN npm install
|
||||
|
||||
# Make sure core is downloaded.
|
||||
COPY scripts/download-core.sh scripts/
|
||||
RUN scripts/download-core.sh node
|
||||
|
||||
# Copy only what we need to build.
|
||||
COPY src/ src/
|
||||
|
||||
# Build the Debug version of the module.
|
||||
RUN src/node/build-node.sh Debug
|
||||
|
||||
# Copy everything else needed to run tests.
|
||||
COPY lib/ lib/
|
||||
COPY scripts/ scripts/
|
||||
COPY tests/ tests/
|
||||
|
||||
# Switch to the non-root user.
|
||||
RUN chown -R user .
|
||||
USER user
|
||||
|
||||
# Default to running the Node tests
|
||||
CMD ["node", "tests"]
|
||||
ENV NPM_CONFIG_UNSAFE_PERM true
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
#!/bin/sh
|
||||
# This is a wrapper script around ./scripts/test.sh which uses docker. The
|
||||
# arguments are the same, as they are passed directly to test.sh.
|
||||
# It can be used to locally check and debug the linux build process
|
||||
# outside of CI.
|
||||
|
||||
set -e
|
||||
|
||||
./scripts/docker_build_wrapper.sh ci/realm-js:build .
|
||||
|
||||
exec docker run --rm \
|
||||
-u $(id -u) \
|
||||
-e HOME=/tmp \
|
||||
-v $(pwd):/source \
|
||||
-w /source \
|
||||
ci/realm-js:build \
|
||||
./scripts/test.sh $@
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
#!/bin/bash
|
||||
# This is a wrapper script around `docker build`. It provides a mechanism
|
||||
# for using cached image layers from upstream repositories as well as an
|
||||
# automatic push back to the docker registry.
|
||||
|
||||
set -e
|
||||
|
||||
script_path="$(pushd "$(dirname "$0")" >/dev/null; pwd)"
|
||||
src_path="$(pushd "${script_path}/.." >/dev/null; pwd)"
|
||||
|
||||
die() { echo "$@" 1>&2 ; exit 1; }
|
||||
info() { echo "===> $*"; }
|
||||
|
||||
docker_build() {
|
||||
declare name="$1"; shift
|
||||
declare path="$1"; shift
|
||||
declare args="$*"
|
||||
|
||||
if [ "${DOCKER_REGISTRY}" != "" ]; then
|
||||
remote_name="${DOCKER_REGISTRY}/${name}"
|
||||
fi
|
||||
|
||||
info "Building ${name} image..."
|
||||
if [ "${DOCKER_REGISTRY}" != "" ]; then
|
||||
docker_pull "${remote_name}" && docker tag "${remote_name}" "${name}" || true
|
||||
fi
|
||||
|
||||
old_id=$(docker images -q "${name}")
|
||||
info "Old ${name} image id: ${old_id}"
|
||||
|
||||
if [ "${DOCKERFILE}" != "" ]; then
|
||||
docker build ${args} -t "${name}" -f "${DOCKERFILE}" "${path}" || \
|
||||
die "Building ${name} image failed"
|
||||
else
|
||||
docker build ${args} -t "${name}" "${path}" || \
|
||||
die "Building ${name} image failed"
|
||||
fi
|
||||
|
||||
new_id=$(docker images -q "${name}")
|
||||
info "New ${name} image id: ${new_id}"
|
||||
|
||||
if [ "${DEBUG}" ] && [ "${new_id}" != "${old_id}" ]; then
|
||||
info "History for old id $old_id:"
|
||||
if [ "${old_id}" != "" ]; then
|
||||
docker history "$old_id"
|
||||
fi
|
||||
|
||||
info "History for new id $new_id:"
|
||||
docker history "$new_id"
|
||||
fi
|
||||
|
||||
if [ "${DOCKER_PUSH:-0}" != "0" ] && [ "${DOCKER_REGISTRY}" != "" ]; then
|
||||
docker tag "${name}" "${remote_name}"
|
||||
docker_push "${remote_name}"
|
||||
fi
|
||||
}
|
||||
|
||||
# Due to https://github.com/docker/docker/issues/20316, we use
|
||||
# https://github.com/tonistiigi/buildcache to generate a cache of the layer
|
||||
# metadata for later builds.
|
||||
my_buildcache() {
|
||||
if [ "$DOCKER_REGISTRY" != "" ]; then
|
||||
|
||||
docker_path="/var/lib/docker"
|
||||
|
||||
# Stupid hack for our AWS nodes, which have docker data on another volume
|
||||
if [ -d "/mnt/docker" ]; then
|
||||
docker_path="/mnt/docker"
|
||||
fi
|
||||
|
||||
docker pull "${DOCKER_REGISTRY}/ci/buildcache" >/dev/null && \
|
||||
docker run --rm \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-v ${docker_path}:/var/lib/docker \
|
||||
"${DOCKER_REGISTRY}/ci/buildcache" "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
docker_pull() {
|
||||
info "Attempting to pull '$1' image from registry..."
|
||||
(
|
||||
tmpdir=$(mktemp -d)
|
||||
docker pull "$1"
|
||||
(
|
||||
# In addition, pull the cached metadata and load it (buildcache)
|
||||
cd "${tmpdir}" && docker pull "$1-cache" && docker save "$1-cache" | \
|
||||
tar -xf - && docker load -i ./*/layer.tar
|
||||
)
|
||||
rm -rf "${tmpdir}"
|
||||
) || true
|
||||
}
|
||||
|
||||
docker_push() {
|
||||
info "Pushing '$1' image to registry..."
|
||||
docker push "$1"
|
||||
# Create a cache of the layer metdata we need and push it as an image
|
||||
#docker rmi $1-cache 2>/dev/null || true
|
||||
my_buildcache save -g /var/lib/docker "$1" | gunzip -c | \
|
||||
docker import - "$1-cache" && \
|
||||
docker push "$1-cache"
|
||||
}
|
||||
|
||||
docker_build $@
|
|
@ -23,12 +23,14 @@ if [ "$1" = 'node' ]; then
|
|||
PLATFORM_TAG="node-osx-"
|
||||
SYNC_PLATFORM_TAG="node-cocoa-"
|
||||
CORE_DOWNLOAD_FILE="realm-core-node-osx-$REALM_CORE_VERSION.tar.gz"
|
||||
SYNC_DOWNLOAD_FILE="realm-sync-$SYNC_PLATFORM_TAG$REALM_SYNC_VERSION.zip"
|
||||
else
|
||||
PLATFORM_TAG="node-linux-"
|
||||
SYNC_PLATFORM_TAG="node-cocoa-"
|
||||
CORE_DOWNLOAD_FILE="realm-core-node-linux-$REALM_CORE_VERSION.tar.gz"
|
||||
SYNC_DOWNLOAD_FILE=""
|
||||
fi
|
||||
SYNC_DOWNLOAD_FILE="realm-sync-$SYNC_PLATFORM_TAG$REALM_SYNC_VERSION.zip"
|
||||
|
||||
SYNC_EXTRACT="unzip"
|
||||
EXTRACTED_DIR="realm-sync-node-cocoa-$REALM_SYNC_VERSION"
|
||||
else
|
||||
|
@ -115,26 +117,27 @@ else
|
|||
echo "The core library seems to be up to date."
|
||||
fi
|
||||
|
||||
|
||||
if [ ! -e "vendor/$SYNC_DIR" ]; then
|
||||
download_core $SYNC_DIR $REALM_SYNC_VERSION $SYNC_DOWNLOAD_FILE sync "$SYNC_EXTRACT" $EXTRACTED_DIR
|
||||
elif [ -d "vendor/$SYNC_DIR" -a -d ../realm-sync -a ! -L "vendor/$SYNC_DIR" ]; then
|
||||
# Allow newer versions than expected for local builds as testing
|
||||
# with unreleased versions is one of the reasons to use a local build
|
||||
if ! check_release_notes "vendor/$SYNC_DIR/version.txt"; then
|
||||
die "Local build of sync is out of date."
|
||||
if [ -n "$SYNC_DOWNLOAD_FILE" ];then
|
||||
if [ ! -e "vendor/$SYNC_DIR" ]; then
|
||||
download_core $SYNC_DIR $REALM_SYNC_VERSION $SYNC_DOWNLOAD_FILE sync "$SYNC_EXTRACT" $EXTRACTED_DIR
|
||||
elif [ -d "vendor/$SYNC_DIR" -a -d ../realm-sync -a ! -L "vendor/$SYNC_DIR" ]; then
|
||||
# Allow newer versions than expected for local builds as testing
|
||||
# with unreleased versions is one of the reasons to use a local build
|
||||
if ! check_release_notes "vendor/$SYNC_DIR/version.txt"; then
|
||||
die "Local build of sync is out of date."
|
||||
else
|
||||
echo "The sync library seems to be up to date."
|
||||
fi
|
||||
elif [ ! -L "vendor/$SYNC_DIR" ]; then
|
||||
echo "vendor/$SYNC_DIR is not a symlink. Deleting..."
|
||||
rm -rf "vendor/$SYNC_DIR"
|
||||
download_core $SYNC_DIR $REALM_SYNC_VERSION $SYNC_DOWNLOAD_FILE sync "$SYNC_EXTRACT" $EXTRACTED_DIR
|
||||
# With a prebuilt version we only want to check the first non-empty
|
||||
# line so that checking out an older commit will download the
|
||||
# appropriate version of core if the already-present version is too new
|
||||
elif ! grep -m 1 . "vendor/$SYNC_DIR/version.txt" | check_release_notes; then
|
||||
download_core $SYNC_DIR $REALM_SYNC_VERSION $SYNC_DOWNLOAD_FILE sync "$SYNC_EXTRACT" $EXTRACTED_DIR
|
||||
else
|
||||
echo "The sync library seems to be up to date."
|
||||
fi
|
||||
elif [ ! -L "vendor/$SYNC_DIR" ]; then
|
||||
echo "vendor/$SYNC_DIR is not a symlink. Deleting..."
|
||||
rm -rf "vendor/$SYNC_DIR"
|
||||
download_core $SYNC_DIR $REALM_SYNC_VERSION $SYNC_DOWNLOAD_FILE sync "$SYNC_EXTRACT" $EXTRACTED_DIR
|
||||
# With a prebuilt version we only want to check the first non-empty
|
||||
# line so that checking out an older commit will download the
|
||||
# appropriate version of core if the already-present version is too new
|
||||
elif ! grep -m 1 . "vendor/$SYNC_DIR/version.txt" | check_release_notes; then
|
||||
download_core $SYNC_DIR $REALM_SYNC_VERSION $SYNC_DOWNLOAD_FILE sync "$SYNC_EXTRACT" $EXTRACTED_DIR
|
||||
else
|
||||
echo "The sync library seems to be up to date."
|
||||
fi
|
||||
|
|
|
@ -185,8 +185,13 @@ case "$TARGET" in
|
|||
cat tests.xml
|
||||
;;
|
||||
"node")
|
||||
download_server
|
||||
start_server
|
||||
if [ "$(uname)" = 'Darwin' ]; then
|
||||
download_server
|
||||
start_server
|
||||
npm_tests_cmd="npm run test"
|
||||
else
|
||||
npm_tests_cmd="npm run test-nosync"
|
||||
fi
|
||||
npm install --build-from-source
|
||||
|
||||
# Change to a temp directory.
|
||||
|
@ -195,7 +200,7 @@ case "$TARGET" in
|
|||
|
||||
pushd "$SRCROOT/tests"
|
||||
npm install
|
||||
npm run test
|
||||
eval $npm_tests_cmd
|
||||
popd
|
||||
stop_server
|
||||
;;
|
||||
|
|
|
@ -106,10 +106,24 @@ module.exports = {
|
|||
|
||||
assertTrue: function(condition, errorMessage) {
|
||||
if (!condition) {
|
||||
throw new TestFailureError(errorMessage || 'Condition expected to be true');
|
||||
throw new TestFailureError(errorMessage || `Condition ${condition} expected to be true`);
|
||||
}
|
||||
},
|
||||
|
||||
assertInstanceOf: function(object, type, errorMessage) {
|
||||
if (!(object instanceof type)) {
|
||||
throw new TestFailureError(errorMessage || `Object ${object} expected to be of type ${type}`);
|
||||
}
|
||||
},
|
||||
|
||||
assertType: function(value, type) {
|
||||
this.assertEqual(typeof value, type, `Value ${value} expected to be of type ${type}`);
|
||||
},
|
||||
|
||||
assertUndefined: function(value) {
|
||||
this.assertEqual(value, undefined, `Value ${value} expected to be undefined`);
|
||||
},
|
||||
|
||||
isNode: function() {
|
||||
// eslint-disable-next-line no-undef
|
||||
return typeof process == 'object' && Object.prototype.toString.call(process) == '[object process]';
|
||||
|
|
|
@ -31,18 +31,46 @@ function uuid() {
|
|||
});
|
||||
}
|
||||
|
||||
function assertIsUser(user, isAdmin) {
|
||||
TestCase.assertType(user, 'object');
|
||||
TestCase.assertType(user.token, 'string');
|
||||
TestCase.assertType(user.identity, 'string');
|
||||
TestCase.assertInstanceOf(user, Realm.Sync.User);
|
||||
if (isAdmin !== undefined) {
|
||||
TestCase.assertEqual(user.isAdmin, isAdmin);
|
||||
}
|
||||
}
|
||||
|
||||
function assertIsError(error, code) {
|
||||
TestCase.assertInstanceOf(error, Error, 'The API should return an Error');
|
||||
if (code) {
|
||||
TestCase.assertEqual(error.code, code);
|
||||
}
|
||||
}
|
||||
|
||||
function assertIsAuthError(error, code, type) {
|
||||
TestCase.assertInstanceOf(error, Realm.Sync.AuthError, 'The API should return an AuthError');
|
||||
if (code) {
|
||||
TestCase.assertEqual(error.code, code);
|
||||
}
|
||||
if (type) {
|
||||
TestCase.assertEqual(error.type, type);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
testRegisterUser() {
|
||||
var username = uuid();
|
||||
return new Promise((resolve, reject) => {
|
||||
Realm.Sync.User.register('http://localhost:9080', username, 'password', (error, user) => {
|
||||
TestCase.assertEqual(typeof user, 'object');
|
||||
TestCase.assertEqual(typeof user.token, 'string');
|
||||
TestCase.assertEqual(typeof user.identity, 'string');
|
||||
TestCase.assertEqual(user.isAdmin, false);
|
||||
if (error) {
|
||||
reject(error);
|
||||
}
|
||||
assertIsUser(user);
|
||||
|
||||
// Can we open a realm with the registered user?
|
||||
var realm = new Realm({sync: {user: user, url: 'realm://localhost:9080/~/test'}});
|
||||
TestCase.assertNotEqual(realm instanceof Realm);
|
||||
TestCase.assertInstanceOf(realm, Realm);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
@ -52,26 +80,48 @@ module.exports = {
|
|||
var username = uuid();
|
||||
return new Promise((resolve, reject) => {
|
||||
Realm.Sync.User.register('http://localhost:9080', username, 'password', (error, user) => {
|
||||
TestCase.assertEqual(typeof user, 'object');
|
||||
if (error) {
|
||||
reject(error);
|
||||
}
|
||||
assertIsUser(user);
|
||||
|
||||
Realm.Sync.User.register('http://localhost:9080', username, 'password', (error, user) => {
|
||||
TestCase.assertTrue(error instanceof Realm.Sync.AuthError);
|
||||
TestCase.assertEqual(error.code, 613);
|
||||
TestCase.assertEqual(error.type, 'https://realm.io/docs/object-server/problems/existing-account');
|
||||
TestCase.assertEqual(user, undefined);
|
||||
assertIsAuthError(error, 613, 'https://realm.io/docs/object-server/problems/existing-account');
|
||||
TestCase.assertUndefined(user);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
testRegisterInvalidUsername() {
|
||||
var username = uuid();
|
||||
testRegisterMissingUsername() {
|
||||
return new Promise((resolve, reject) => {
|
||||
Realm.Sync.User.register('http://localhost:9080', undefined, 'password', (error, user) => {
|
||||
TestCase.assertTrue(error instanceof Realm.Sync.AuthError);
|
||||
TestCase.assertEqual(error.code, 602);
|
||||
TestCase.assertEqual(error.type, 'https://realm.io/docs/object-server/problems/missing-parameters');
|
||||
TestCase.assertEqual(user, undefined);
|
||||
assertIsAuthError(error, 602, 'https://realm.io/docs/object-server/problems/missing-parameters');
|
||||
TestCase.assertUndefined(user);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
testRegisterMissingPassword() {
|
||||
var username = uuid();
|
||||
return new Promise((resolve, reject) => {
|
||||
Realm.Sync.User.register('http://localhost:9080', username, undefined, (error, user) => {
|
||||
assertIsAuthError(error, 602, 'https://realm.io/docs/object-server/problems/missing-parameters');
|
||||
TestCase.assertUndefined(user);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
testRegisterServerOffline() {
|
||||
var username = uuid();
|
||||
return new Promise((resolve, reject) => {
|
||||
// Because it waits for answer this takes some time..
|
||||
Realm.Sync.User.register('http://fake_host.local', username, 'password', (error, user) => {
|
||||
assertIsError(error, 'ECONNRESET');
|
||||
TestCase.assertUndefined(user);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
@ -80,25 +130,62 @@ module.exports = {
|
|||
testLogin() {
|
||||
var username = uuid();
|
||||
return new Promise((resolve, reject) => {
|
||||
// Create user, logout the new user, then login
|
||||
Realm.Sync.User.register('http://localhost:9080', username, 'password', (error, user) => {
|
||||
user.logout();
|
||||
//TestCase.assertEqual(Realm.Sync.User.all.length, 0);
|
||||
|
||||
Realm.Sync.User.login('http://localhost:9080', username, 'password', (error, user) => {
|
||||
TestCase.assertEqual(typeof user, 'object');
|
||||
TestCase.assertEqual(typeof user.token, 'string');
|
||||
TestCase.assertEqual(typeof user.identity, 'string');
|
||||
TestCase.assertEqual(user.isAdmin, false);
|
||||
assertIsUser(user);
|
||||
|
||||
var realm = new Realm({sync: {user: user, url: 'realm://localhost:9080/~/test'}});
|
||||
TestCase.assertNotEqual(realm instanceof Realm);
|
||||
|
||||
//TestCase.assertEqual(Realm.Sync.User.all.length, 1);
|
||||
|
||||
TestCase.assertInstanceOf(realm, Realm);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
testLoginMissingUsername() {
|
||||
return new Promise((resolve, reject) => {
|
||||
Realm.Sync.User.login('http://localhost:9080', undefined, 'password', (error, user) => {
|
||||
assertIsAuthError(error, 602, 'https://realm.io/docs/object-server/problems/missing-parameters');
|
||||
TestCase.assertUndefined(user);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
testLoginMissingPassword() {
|
||||
var username = uuid();
|
||||
return new Promise((resolve, reject) => {
|
||||
Realm.Sync.User.login('http://localhost:9080', username, undefined, (error, user) => {
|
||||
assertIsAuthError(error, 602, 'https://realm.io/docs/object-server/problems/missing-parameters');
|
||||
TestCase.assertUndefined(user);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
testLoginNonExistingUser() {
|
||||
return new Promise((resolve, reject) => {
|
||||
Realm.Sync.User.login('http://localhost:9080', 'does_not', 'exist', (error, user) => {
|
||||
assertIsAuthError(error, 612, 'https://realm.io/docs/object-server/problems/unknown-account');
|
||||
TestCase.assertUndefined(user);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
testLoginServerOffline() {
|
||||
var username = uuid();
|
||||
return new Promise((resolve, reject) => {
|
||||
// Because it waits for answer this takes some time..
|
||||
Realm.Sync.User.register('http://fake_host.local', username, 'password', (error, user) => {
|
||||
assertIsError(error, 'ECONNRESET');
|
||||
TestCase.assertUndefined(user);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ const Realm = require('realm');
|
|||
|
||||
const userTests = require('../js/user-tests');
|
||||
describe('SyncTests', () => {
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 30000;
|
||||
beforeEach(() => Realm.clearTestState());
|
||||
afterEach(() => Realm.clearTestState());
|
||||
|
||||
|
|
Loading…
Reference in New Issue