summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLingxian Kong <anlin.kong@gmail.com>2019-06-12 20:35:29 +1200
committerLingxian Kong <anlin.kong@gmail.com>2019-08-25 23:11:54 +1200
commitdfa5ce93d5f7caa49950d4565bab12fe2dc56ffb (patch)
tree43cab6ca3da72c55d4d1975c7d46d95b4432a106
parentc247e4842eb424214da55ca751535d107d87ceab (diff)
downloadtrove-dfa5ce93d5f7caa49950d4565bab12fe2dc56ffb.tar.gz
Improve devmode=flase when building the image
During debugging, the following changes are also included: - Support to specify an image ID to run the integration test. - Fix the reboot function bug. - Remove the unsuccessful restart test. How to run integration test with dev_mode=false: ADMIN_PASSWORD=password \ SERVICE_PASSWORD=password \ DEV_MODE=false \ /opt/stack/trove/integration/scripts/trovestack gate-tests mysql mysql Change-Id: I31d4ee579a554f4c98f9facb9fd4b7779665a3dd
-rw-r--r--devstack/plugin.sh2
-rw-r--r--doc/source/admin/building_guest_images.rst26
-rw-r--r--doc/source/admin/guest_cloud_init.rst74
-rw-r--r--doc/source/admin/index.rst1
-rw-r--r--doc/source/admin/trovestack.rst21
-rw-r--r--integration/scripts/files/elements/guest-agent/README.rst4
-rwxr-xr-xintegration/scripts/files/elements/guest-agent/extra-data.d/11-ssh-key28
-rwxr-xr-xintegration/scripts/files/elements/guest-agent/install.d/50-user22
-rwxr-xr-xintegration/scripts/files/elements/guest-agent/install.d/guest-agent-source-install/75-guest-agent-install33
-rw-r--r--integration/scripts/files/elements/guest-agent/install.d/guest-agent-source-install/guest-agent.service5
-rw-r--r--integration/scripts/files/elements/guest-agent/package-installs.yaml12
-rw-r--r--integration/scripts/files/elements/guest-agent/pkg-map2
-rwxr-xr-xintegration/scripts/files/elements/guest-agent/post-install.d/12-ssh-key39
-rwxr-xr-xintegration/scripts/files/elements/guest-agent/post-install.d/99-clean-apt2
-rw-r--r--integration/scripts/files/elements/no-resolvconf/README.rst7
-rwxr-xr-xintegration/scripts/files/elements/ubuntu-mysql/pre-install.d/20-apparmor-mysql-local1
-rw-r--r--integration/scripts/functions_qemu8
-rwxr-xr-xintegration/scripts/trovestack35
-rw-r--r--integration/scripts/trovestack.rc3
-rw-r--r--integration/tests/integration/int_tests.py1
-rw-r--r--integration/tests/integration/tests/api/instances_quotas.py47
-rw-r--r--run_tests.py1
-rw-r--r--trove/common/notification.py9
-rw-r--r--trove/extensions/mgmt/instances/service.py9
-rw-r--r--trove/instance/service.py6
-rwxr-xr-xtrove/taskmanager/models.py28
-rw-r--r--trove/tests/api/backups.py4
-rw-r--r--trove/tests/api/flavors.py265
-rw-r--r--trove/tests/api/instances.py138
-rw-r--r--trove/tests/api/instances_actions.py162
-rw-r--r--trove/tests/api/instances_mysql_down.py1
-rw-r--r--trove/tests/int_tests.py4
-rw-r--r--trove/tests/scenario/runners/instance_create_runners.py4
-rw-r--r--trove/tests/scenario/runners/test_runners.py4
-rw-r--r--trove/tests/unittests/mgmt/test_datastores.py2
-rw-r--r--trove/tests/unittests/taskmanager/test_models.py10
36 files changed, 204 insertions, 816 deletions
diff --git a/devstack/plugin.sh b/devstack/plugin.sh
index 09c2121e..a54d9480 100644
--- a/devstack/plugin.sh
+++ b/devstack/plugin.sh
@@ -404,7 +404,7 @@ function create_mgmt_subnet_v4 {
local name=$3
local ip_range=$4
- subnet_id=$(openstack subnet create --project ${project_id} --ip-version 4 --subnet-range ${ip_range} --gateway none --network ${net_id} $name -c id -f value)
+ subnet_id=$(openstack subnet create --project ${project_id} --ip-version 4 --subnet-range ${ip_range} --gateway none --dns-nameserver 8.8.8.8 --network ${net_id} $name -c id -f value)
die_if_not_set $LINENO subnet_id "Failed to create private IPv4 subnet for network: ${net_id}, project: ${project_id}"
echo $subnet_id
}
diff --git a/doc/source/admin/building_guest_images.rst b/doc/source/admin/building_guest_images.rst
index 389325cc..5b017470 100644
--- a/doc/source/admin/building_guest_images.rst
+++ b/doc/source/admin/building_guest_images.rst
@@ -55,9 +55,9 @@ Operating System and Database
A Trove Guest Instance contains at least a functioning Operating
System and the database software that the instance wishes to provide
(as a Service). For example, if your chosen operating system is Ubuntu
-and you wish to deliver MySQL version 5.5, then your guest instance is
+and you wish to deliver MySQL version 5.7, then your guest instance is
a Nova instance running the Ubuntu operating system and will have
-MySQL version 5.5 installed on it.
+MySQL version 5.7 installed on it.
-----------------
Trove Guest Agent
@@ -77,7 +77,7 @@ Guest Agent API is the common API used by Trove to communicate with
any guest database, and the Guest Agent is the implementation of that
API for the specific database.
-The Trove Guest Agent runs on the Trove Guest Instance.
+The Trove Guest Agent runs inside the Trove Guest Instance.
------------------------------------------
Injected Configuration for the Guest Agent
@@ -87,11 +87,11 @@ When TaskManager launches the guest VM it injects the specific settings
for the guest into the VM, into the file /etc/trove/conf.d/guest_info.conf.
The file is injected one of three ways.
-If use_nova_server_config_drive=True, it is injected via ConfigDrive. Otherwise
-it is passed to the nova create call as the 'files' parameter and will be
-injected based on the configuration of Nova; the Nova default is to discard the
-files. If the settings in guest_info.conf are not present on the guest
-Guest Agent will fail to start up.
+If ``use_nova_server_config_drive=True``, it is injected via ConfigDrive.
+Otherwise it is passed to the nova create call as the 'files' parameter and
+will be injected based on the configuration of Nova; the Nova default is to
+discard the files. If the settings in guest_info.conf are not present on the
+guest Guest Agent will fail to start up.
------------------------------
Persistent Storage, Networking
@@ -99,9 +99,13 @@ Persistent Storage, Networking
The database stores data on persistent storage on Cinder (if
configured, see trove.conf and the volume_support parameter) or
-ephemeral storage on the Nova instance. The database is accessible
-over the network and the Guest Instance is configured for network
-access by client applications.
+ephemeral storage on the Nova instance. The database service is accessible
+over the tenant network provided when creating the database instance.
+
+The cloud administrator is able to config a management
+networks(``CONF.management_networks``) that is invisible to the cloud tenants,
+database instance can talk to the control plane services(e.g. the message
+queue) via that network.
Building Guest Images using DIB
===============================
diff --git a/doc/source/admin/guest_cloud_init.rst b/doc/source/admin/guest_cloud_init.rst
deleted file mode 100644
index 183743fe..00000000
--- a/doc/source/admin/guest_cloud_init.rst
+++ /dev/null
@@ -1,74 +0,0 @@
-.. _guest_cloud_init:
-
-.. role:: bash(code)
- :language: bash
-
-===========================
-Guest Images via Cloud-Init
-===========================
-
-.. If section numbers are desired, unindent this
- .. sectnum::
-
-.. If a TOC is desired, unindent this
- .. contents::
-
-Overview
-========
-
-While creating an image is the preferred method for providing a base
-for the Guest Instance, there may be cases where creating an image
-is impractical. In those cases a Guest instance can be based on
-an available Cloud Image and configured at boot via cloud-init.
-
-Currently the most tested Guest image is Ubunutu 14.04 (trusty).
-
-Setting up the Image
-====================
-
-* Visit the `Ubuntu Cloud Archive <https://cloud-images.ubuntu.com/releases/trusty/release>`_ and download ``ubuntu-14.04-server-cloudimg-amd64-disk1.img``.
-
-* Upload that image to glance, and note the glance ID for the image.
-
-* Cloud-Init files go into the directory set by the ``cloudinit_location``
- configuration parameter, usually ``/etc/trove/cloudinit``. Files in
- that directory are of the format ``[datastore].cloudinit``, for
- example ``mysql.cloudinit``.
-
-* Create a cloud-init file for your datastore and put it into place.
- For this example, it is assumed you are using Ubuntu 16.04, with
- the MySQL database and a Trove Agent from the Pike release. You
- would put this into ``/etc/trove/cloudinit/mysql.cloudinit``.
-
-.. code-block:: console
-
- #cloud-config
- # For Ubuntu-16.04 cloudimage
- apt_sources:
- - source: "cloud-archive:pike"
- packages:
- - trove-guestagent
- - mysql-server-5.7
- write_files:
- - path: /etc/sudoers.d/trove
- content: |
- Defaults:trove !requiretty
- trove ALL=(ALL) NOPASSWD:ALL
- runcmd:
- - stop trove-guestagent
- - cat /etc/trove/trove-guestagent.conf /etc/trove/conf.d/guest_info.conf >/etc/trove/trove.conf
- - start trove-guestagent
-
-
-* If you need to debug guests failing to launch simply append
- the cloud-init to add a user to allow you to login and
- debug the instance.
-
-* When using ``trove-manage datastore_version_update`` to
- define your datastore simply use the Glance ID you have for
- the Trusty Cloud image.
-
-When trove launches the Guest Instance, the cloud-init will install
-the Pike Trove Guest Agent and MySQL database, and then adjust
-the configuration files and launch the Guest Agent.
-
diff --git a/doc/source/admin/index.rst b/doc/source/admin/index.rst
index 0c3be723..14054207 100644
--- a/doc/source/admin/index.rst
+++ b/doc/source/admin/index.rst
@@ -8,6 +8,5 @@
basics
building_guest_images
database_module_usage
- guest_cloud_init
secure_oslo_messaging
trovestack
diff --git a/doc/source/admin/trovestack.rst b/doc/source/admin/trovestack.rst
index 3096450d..824a60e2 100644
--- a/doc/source/admin/trovestack.rst
+++ b/doc/source/admin/trovestack.rst
@@ -34,23 +34,21 @@ The trove guest agent image could be created by running the following command:
.. code-block:: console
- $ CONTROLLER_IP=10.0.17.132 \
- ./trovestack build-image \
+ $ ./trovestack build-image \
${datastore_type} \
${guest_os} \
${guest_os_release} \
${dev_mode}
* Currently, only ``guest_os=ubuntu`` and ``guest_os_release=xenial`` are fully
- tested.
+ tested and supported.
-* ``dev_mode=true`` is mainly for testing purpose for trove developers. When
- ``dev_mode=true``, ``CONTROLLER_IP`` could be ignored. You need to build the
- image on the trove controller service host, because the host and the guest VM
- need to ssh into each other without password. In this mode, when the trove
- guest agent code is changed, the image doesn't need to be rebuilt which is
- convenient for debugging. Trove guest agent will ssh into the host and
- download trove code when the service is initialized.
+* ``dev_mode=true`` is mainly for testing purpose for trove developers and it's
+ necessary to build the image on the trove controller host, because the host
+ and the guest VM need to ssh into each other without password. In this mode,
+ when the trove guest agent code is changed, the image doesn't need to be
+ rebuilt which is convenient for debugging. Trove guest agent will ssh into
+ the host and download trove code during the service initialization.
* if ``dev_mode=false``, the trove code for guest agent is injected into the
image at the building time. Now ``dev_mode=false`` is still in experimental
@@ -62,7 +60,8 @@ The trove guest agent image could be created by running the following command:
also need to create a Nova keypair and set ``nova_keypair`` option in Trove
config file in order to ssh into the guest agent.
-For example, build a MySQL image for Ubuntu Xenial operating system:
+For example, in order to build a MySQL image for Ubuntu Xenial operating
+system:
.. code-block:: console
diff --git a/integration/scripts/files/elements/guest-agent/README.rst b/integration/scripts/files/elements/guest-agent/README.rst
index e1cc7f0e..a5ff0e74 100644
--- a/integration/scripts/files/elements/guest-agent/README.rst
+++ b/integration/scripts/files/elements/guest-agent/README.rst
@@ -1,6 +1,4 @@
Element to install an Trove guest agent.
-Note: this requires a system base image modified to include OpenStack
+Note: this requires a system base image modified to include Trove source code
repositories
-
-the ubuntu-guest element could be removed.
diff --git a/integration/scripts/files/elements/guest-agent/extra-data.d/11-ssh-key b/integration/scripts/files/elements/guest-agent/extra-data.d/11-ssh-key
deleted file mode 100755
index fceae3f7..00000000
--- a/integration/scripts/files/elements/guest-agent/extra-data.d/11-ssh-key
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/bash
-
-set -e
-set -o xtrace
-
-# CONTEXT: HOST prior to IMAGE BUILD as SCRIPT USER
-# PURPOSE: creates the SSH key on the host if it doesn't exist. Then this copies the keys over to a staging area where
-# they will be duplicated in the guest VM.
-# This process allows the host to log into the guest but more importantly the guest phones home to get the trove
-# source
-
-source $_LIB/die
-
-HOST_USERNAME=${HOST_USERNAME:-"ubuntu"}
-SSH_DIR=${SSH_DIR:-"/home/${HOST_USERNAME}/.ssh"}
-
-[ -n "${TMP_HOOKS_PATH}" ] || die "Temp hook path not set"
-
-# copy files over the "staging" area for the guest image (they'll later be put in the correct location by the guest user
-# not these keys should not be overridden otherwise a) you won't be able to ssh in and b) the guest won't be able to
-# rsync the files
-if [ -f ${SSH_DIR}/id_rsa ]; then
- dd if=${SSH_DIR}/authorized_keys of=${TMP_HOOKS_PATH}/ssh-authorized-keys
- dd if=${SSH_DIR}/id_rsa of=${TMP_HOOKS_PATH}/ssh-id_rsa
- dd if=${SSH_DIR}/id_rsa.pub of=${TMP_HOOKS_PATH}/ssh-id_rsa.pub
-else
- die "SSH Authorized Keys file must exist along with pub and private key"
-fi
diff --git a/integration/scripts/files/elements/guest-agent/install.d/50-user b/integration/scripts/files/elements/guest-agent/install.d/50-user
new file mode 100755
index 00000000..8a2b145f
--- /dev/null
+++ b/integration/scripts/files/elements/guest-agent/install.d/50-user
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+# PURPOSE: Add the guest image user that will own the trove agent source if the
+# user does not already exist
+
+if [ ${DIB_DEBUG_TRACE:-1} -gt 0 ]; then
+ set -x
+fi
+set -e
+set -o pipefail
+
+GUEST_USERNAME=${GUEST_USERNAME:-"ubuntu"}
+
+if ! id -u ${GUEST_USERNAME} >/dev/null 2>&1; then
+ echo "Adding ${GUEST_USERNAME} user"
+ useradd -G sudo -m ${GUEST_USERNAME} -s /bin/bash
+ chown ${GUEST_USERNAME}:${GUEST_USERNAME} /home/${GUEST_USERNAME}
+ passwd ${GUEST_USERNAME} <<_EOF_
+${GUEST_USERNAME}
+${GUEST_USERNAME}
+_EOF_
+fi
diff --git a/integration/scripts/files/elements/guest-agent/install.d/guest-agent-source-install/75-guest-agent-install b/integration/scripts/files/elements/guest-agent/install.d/guest-agent-source-install/75-guest-agent-install
index 377a2006..87a11958 100755
--- a/integration/scripts/files/elements/guest-agent/install.d/guest-agent-source-install/75-guest-agent-install
+++ b/integration/scripts/files/elements/guest-agent/install.d/guest-agent-source-install/75-guest-agent-install
@@ -8,28 +8,35 @@ set -o pipefail
SCRIPTDIR=$(dirname $0)
GUEST_VENV=/opt/guest-agent-venv
+GUEST_USERNAME=${GUEST_USERNAME:-"ubuntu"}
-# Create a virtual environment to contain the guest agent
-${DIB_PYTHON} -m virtualenv $GUEST_VENV
-$GUEST_VENV/bin/pip install pip --upgrade
-$GUEST_VENV/bin/pip install -U -c /opt/upper-constraints.txt /opt/guest-agent
+# Create a virtual environment for guest agent
+${DIB_PYTHON} -m virtualenv ${GUEST_VENV}
+${GUEST_VENV}/bin/pip install pip --upgrade
+${GUEST_VENV}/bin/pip install -U -c /opt/upper-constraints.txt /opt/guest-agent
+chown -R ${GUEST_USERNAME}:root ${GUEST_VENV}
-# Link the trove-guestagent out to /usr/local/bin where the startup scripts look
-ln -s $GUEST_VENV/bin/trove-guestagent /usr/local/bin/guest-agent || true
+# Link the trove-guestagent out to /usr/local/bin where the startup scripts look for
+ln -s ${GUEST_VENV}/bin/trove-guestagent /usr/local/bin/guest-agent || true
-mkdir -p /var/lib/trove /etc/trove/certs /var/log/trove
+for folder in "/var/lib/trove" "/etc/trove" "/etc/trove/certs" "/etc/trove/conf.d" "/var/log/trove"; do
+ mkdir -p ${folder}
+ chown -R ${GUEST_USERNAME}:root ${folder}
+done
-install -D -g root -o root -m 0644 ${SCRIPTDIR}/guest-agent.logrotate /etc/logrotate.d/guest-agent
+install -D -g root -o ${GUEST_USERNAME} -m 0644 ${SCRIPTDIR}/guest-agent.logrotate /etc/logrotate.d/guest-agent
case "$DIB_INIT_SYSTEM" in
- upstart)
- install -D -g root -o root -m 0644 ${SCRIPTDIR}/guest-agent.conf /etc/init/guest-agent.conf
- ;;
systemd)
- install -D -g root -o root -m 0644 ${SCRIPTDIR}/guest-agent.service /usr/lib/systemd/system/guest-agent.service
+ mkdir -p /usr/lib/systemd/system
+ touch /usr/lib/systemd/system/guest-agent.service
+ sed "s/GUEST_USERNAME/${GUEST_USERNAME}/g" ${SCRIPTDIR}/guest-agent.service > /usr/lib/systemd/system/guest-agent.service
+ ;;
+ upstart)
+ install -D -g root -o ${GUEST_USERNAME} -m 0644 ${SCRIPTDIR}/guest-agent.conf /etc/init/guest-agent.conf
;;
sysv)
- install -D -g root -o root -m 0644 ${SCRIPTDIR}/guest-agent.init /etc/init.d/guest-agent.init
+ install -D -g root -o ${GUEST_USERNAME} -m 0644 ${SCRIPTDIR}/guest-agent.init /etc/init.d/guest-agent.init
;;
*)
echo "Unsupported init system"
diff --git a/integration/scripts/files/elements/guest-agent/install.d/guest-agent-source-install/guest-agent.service b/integration/scripts/files/elements/guest-agent/install.d/guest-agent-source-install/guest-agent.service
index 047553f4..788bebc9 100644
--- a/integration/scripts/files/elements/guest-agent/install.d/guest-agent-source-install/guest-agent.service
+++ b/integration/scripts/files/elements/guest-agent/install.d/guest-agent-source-install/guest-agent.service
@@ -4,11 +4,12 @@ After=network.target syslog.service
Wants=syslog.service
[Service]
+User=GUEST_USERNAME
+Group=GUEST_USERNAME
+ExecStartPre=/bin/bash -c "sudo chown -R GUEST_USERNAME:root /etc/trove/conf.d"
ExecStart=/usr/local/bin/guest-agent --config-dir=/etc/trove/conf.d
KillMode=mixed
Restart=always
-ExecStartPost=/bin/sh -c "echo $MAINPID > /var/run/guest-agent.pid"
-PIDFile=/var/run/guest-agent.pid
[Install]
WantedBy=multi-user.target
diff --git a/integration/scripts/files/elements/guest-agent/package-installs.yaml b/integration/scripts/files/elements/guest-agent/package-installs.yaml
index b8baae1e..ff870104 100644
--- a/integration/scripts/files/elements/guest-agent/package-installs.yaml
+++ b/integration/scripts/files/elements/guest-agent/package-installs.yaml
@@ -9,15 +9,6 @@ libssl-dev:
python-dev:
installtype: source
-python-sqlalchemy:
-python-lxml:
-python-eventlet:
-python-webob:
-python-httplib2:
-python-iso8601:
-python-pexpect:
-python-mysqldb:
-python-migrate:
acl:
acpid:
apparmor:
@@ -46,13 +37,14 @@ lsof:
net-tools:
netbase:
netcat-openbsd:
+network-scripts:
open-vm-tools:
+ arch: i386, amd64
openssh-client:
openssh-server:
pollinate:
psmisc:
rsyslog:
-screen:
socat:
tcpdump:
ubuntu-cloudimage-keyring:
diff --git a/integration/scripts/files/elements/guest-agent/pkg-map b/integration/scripts/files/elements/guest-agent/pkg-map
index ad53fb64..69c07900 100644
--- a/integration/scripts/files/elements/guest-agent/pkg-map
+++ b/integration/scripts/files/elements/guest-agent/pkg-map
@@ -10,7 +10,7 @@
"cloud-guest-utils": "",
"apparmor": "",
"dmeventd": "",
- "isc-dhcp-client": "",
+ "isc-dhcp-client": "dhcp-client",
"uuid-runtime": "",
"ubuntu-cloudimage-keyring": "",
"vim-tiny": "",
diff --git a/integration/scripts/files/elements/guest-agent/post-install.d/12-ssh-key b/integration/scripts/files/elements/guest-agent/post-install.d/12-ssh-key
deleted file mode 100755
index f0f64e6f..00000000
--- a/integration/scripts/files/elements/guest-agent/post-install.d/12-ssh-key
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/bin/bash
-
-# CONTEXT: GUEST during CONSTRUCTION as ROOT
-# PURPOSE: take "staged" ssh keys (see extra-data.d/62-ssh-key) and put them in the GUEST_USERS home directory
-
-set -e
-set -o xtrace
-
-SSH_DIR="/home/${GUEST_USERNAME}/.ssh"
-TMP_HOOKS_DIR="/tmp/in_target.d"
-
-if ! id -u ${GUEST_USERNAME} >/dev/null 2>&1; then
- echo "Adding ${GUEST_USERNAME} user"
- useradd -G sudo -m ${GUEST_USERNAME} -s /bin/bash
- chown ${GUEST_USERNAME}:${GUEST_USERNAME} /home/${GUEST_USERNAME}
- passwd ${GUEST_USERNAME} <<_EOF_
-${GUEST_USERNAME}
-${GUEST_USERNAME}
-_EOF_
-fi
-
-if [ -f "${TMP_HOOKS_DIR}/ssh-authorized-keys" ]; then
- if [ ! -d ${SSH_DIR} ]; then
- # this method worked more reliable in vmware fusion over doing sudo -Hiu ${GUEST_USERNAME}
- mkdir ${SSH_DIR}
- chown ${GUEST_USERNAME}:${GUEST_USERNAME} ${SSH_DIR}
- fi
-
- sudo -Hiu ${GUEST_USERNAME} dd of=${SSH_DIR}/authorized_keys conv=notrunc if=${TMP_HOOKS_DIR}/ssh-authorized-keys
- if [ ! -f "${SSH_DIR}/id_rsa" ]; then
- sudo -Hiu ${GUEST_USERNAME} dd of=${SSH_DIR}/id_rsa if=${TMP_HOOKS_DIR}/ssh-id_rsa
- # perms have to be right on this file for ssh to work
- sudo -Hiu ${GUEST_USERNAME} chmod 600 ${SSH_DIR}/id_rsa
- sudo -Hiu ${GUEST_USERNAME} dd of=${SSH_DIR}/id_rsa.pub if=${TMP_HOOKS_DIR}/ssh-id_rsa.pub
- fi
-else
- echo "SSH Keys were not staged by host"
- exit -1
-fi
diff --git a/integration/scripts/files/elements/guest-agent/post-install.d/99-clean-apt b/integration/scripts/files/elements/guest-agent/post-install.d/99-clean-apt
index cc348c5c..227c508d 100755
--- a/integration/scripts/files/elements/guest-agent/post-install.d/99-clean-apt
+++ b/integration/scripts/files/elements/guest-agent/post-install.d/99-clean-apt
@@ -7,5 +7,3 @@ set -e
set -o xtrace
apt-get clean
-
-
diff --git a/integration/scripts/files/elements/no-resolvconf/README.rst b/integration/scripts/files/elements/no-resolvconf/README.rst
index d08b658e..8a3dfc7d 100644
--- a/integration/scripts/files/elements/no-resolvconf/README.rst
+++ b/integration/scripts/files/elements/no-resolvconf/README.rst
@@ -1,11 +1,8 @@
This element clears out /etc/resolv.conf and prevents dhclient from populating
it with data from DHCP. This means that DNS resolution will not work from the
-amphora. This is OK because all outbound connections from the guest will
+guest. This is OK because all outbound connections from the guest will
be based using raw IP addresses.
In addition we remove dns from the nsswitch.conf hosts setting.
-This has the real benefit of speeding up host boot and configutation times.
-This is especially helpful when running tempest tests in a devstack environment
-where DNS resolution from the guest usually doesn't work anyway. This means
-that the guest never waits for DNS timeouts to occur.
+This means that the guest never waits for DNS timeouts to occur.
diff --git a/integration/scripts/files/elements/ubuntu-mysql/pre-install.d/20-apparmor-mysql-local b/integration/scripts/files/elements/ubuntu-mysql/pre-install.d/20-apparmor-mysql-local
index a3e1dc7c..90bd85b1 100755
--- a/integration/scripts/files/elements/ubuntu-mysql/pre-install.d/20-apparmor-mysql-local
+++ b/integration/scripts/files/elements/ubuntu-mysql/pre-install.d/20-apparmor-mysql-local
@@ -5,6 +5,7 @@ set -e
#CONTEXT: chroot on host
#PURPOSE: Allows mysqld to create temporary files when restoring backups
+mkdir -p /etc/apparmor.d/local/
cat <<EOF >>/etc/apparmor.d/local/usr.sbin.mysqld
/tmp/ rw,
/tmp/** rwk,
diff --git a/integration/scripts/functions_qemu b/integration/scripts/functions_qemu
index 67426bd6..cf839248 100644
--- a/integration/scripts/functions_qemu
+++ b/integration/scripts/functions_qemu
@@ -21,6 +21,8 @@ function build_vm() {
GUEST_CACHEDIR=${GUEST_CACHEDIR:-"$HOME/.cache/image-create"}
GUEST_WORKING_DIR=${GUEST_WORKING_DIR:-"$HOME/images"}
+ export GUEST_USERNAME=${guest_username}
+
# In dev mode, the trove guest agent needs to download trove code from
# trove-taskmanager host during service initialization.
if [[ "${dev_mode}" == "true" ]]; then
@@ -34,7 +36,6 @@ function build_vm() {
export HOST_SCP_USERNAME=$(whoami)
export HOST_USERNAME=${HOST_SCP_USERNAME}
export SSH_DIR=${SSH_DIR:-"$HOME/.ssh"}
- export GUEST_USERNAME=${guest_username}
manage_ssh_keys
fi
@@ -68,7 +69,6 @@ function build_vm() {
if [[ "${dev_mode}" == "false" ]]; then
elementes="$elementes pip-and-virtualenv"
elementes="$elementes pip-cache"
- elementes="$elementes no-resolvconf"
elementes="$elementes guest-agent"
else
elementes="$elementes ${guest_os}-guest"
@@ -101,7 +101,7 @@ function build_guest_image() {
dev_mode=${4:-"true"}
guest_username=${5:-"ubuntu"}
- exclaim "Building a ${datastore_type} image of trove guest agent for ${guest_os} ${guest_release}."
+ exclaim "Building a ${datastore_type} image of trove guest agent for ${guest_os} ${guest_release}, dev_mode=${dev_mode}"
VALID_SERVICES='mysql percona mariadb redis cassandra couchbase mongodb postgresql couchdb vertica db2 pxc'
if ! [[ " $VALID_SERVICES " =~ " $datastore_type " ]]; then
@@ -109,7 +109,7 @@ function build_guest_image() {
exit 1
fi
- image_name=${guest_os}_${datastore_type}
+ image_name=${guest_os}-${datastore_type}
image_folder=$HOME/images
mkdir -p $image_folder
image_path=${image_folder}/${image_name}
diff --git a/integration/scripts/trovestack b/integration/scripts/trovestack
index 1ac4d7bf..f629cab4 100755
--- a/integration/scripts/trovestack
+++ b/integration/scripts/trovestack
@@ -850,19 +850,27 @@ function cmd_build_and_upload_image() {
exit 1
fi
- glance_imageid=$(openstack $CLOUD_ADMIN_ARG image list | grep "$datastore_type" | get_field 1)
- echo "IMAGEID: $glance_imageid"
+ image_var="${datastore_type^^}_IMAGE_ID"
+ glance_imageid=`eval echo '$'"$image_var"`
+
if [[ -z $glance_imageid ]]; then
- build_guest_image ${datastore_type} ${guest_os} ${guest_release} ${dev_mode} ${guest_username}
-
- image_folder=$HOME/images
- qcow_image=`find $image_folder -name '*.qcow2'`
- image_url="file://$qcow_image"
- glance_imageid=`get_glance_id upload_image $image_url`
- [[ -z "$glance_imageid" ]] && echo "Glance upload failed!" && exit 1
- echo "IMAGE ID: $glance_imageid"
+ # Find the first image id with the name contains datastore_type.
+ glance_imageid=$(openstack $CLOUD_ADMIN_ARG image list | grep "$datastore_type" | awk 'NR==1 {print}' | awk '{print $2}')
+
+ if [[ -z $glance_imageid ]]; then
+ build_guest_image ${datastore_type} ${guest_os} ${guest_release} ${dev_mode} ${guest_username}
+
+ image_folder=$HOME/images
+ qcow_image=`find $image_folder -name '*.qcow2'`
+ image_url="file://$qcow_image"
+ glance_imageid=`get_glance_id upload_image $image_url`
+ [[ -z "$glance_imageid" ]] && echo "Glance upload failed!" && exit 1
+ echo "IMAGE ID: $glance_imageid"
+ fi
fi
+ echo "IMAGEID: $glance_imageid"
+
exclaim "Updating Datastores"
cmd_set_datastore "${glance_imageid}" "${datastore_type}" "${restart_trove}"
}
@@ -1257,7 +1265,12 @@ function cmd_kick_start() {
exclaim "Running kick-start for $DATASTORE_TYPE (restart trove: $RESTART_TROVE)"
dump_env
cmd_test_init "${DATASTORE_TYPE}"
- cmd_build_and_upload_image "${DATASTORE_TYPE}" "${RESTART_TROVE}"
+
+ export GUEST_OS=${GUEST_OS:-"ubuntu"}
+ export GUEST_OS_RELEASE=${GUEST_OS_RELEASE:-"xenial"}
+ export GUEST_OS_USERNAME=${GUEST_OS_USERNAME:-"ubuntu"}
+ export DEV_MOEE=${DEV_MODE:-"true"}
+ cmd_build_and_upload_image "${DATASTORE_TYPE}" "${RESTART_TROVE}" "${GUEST_OS}" "${GUEST_OS_RELEASE}" "${DEV_MOEE}" "${GUEST_OS_USERNAME}"
}
function cmd_gate_tests() {
diff --git a/integration/scripts/trovestack.rc b/integration/scripts/trovestack.rc
index 165c27a5..b97b3813 100644
--- a/integration/scripts/trovestack.rc
+++ b/integration/scripts/trovestack.rc
@@ -108,3 +108,6 @@ SWIFT_DISK_IMAGE=${SWIFT_DATA_DIR}/drives/images/swift.img
#export TROVE_RESIZE_TIME_OUT=3600
#export TROVE_USAGE_TIMEOUT=1500
#export TROVE_STATE_CHANGE_WAIT_TIME=180
+
+# Image
+MYSQL_IMAGE_ID=${MYSQL_IMAGE_ID:-""}
diff --git a/integration/tests/integration/int_tests.py b/integration/tests/integration/int_tests.py
index de5417ef..d988b723 100644
--- a/integration/tests/integration/int_tests.py
+++ b/integration/tests/integration/int_tests.py
@@ -125,7 +125,6 @@ def import_tests():
if not ADD_DOMAINS:
from tests.api import delete_all
from tests.api import instances_pagination
- from tests.api import instances_quotas
from tests.api import instances_states
from tests.dns import dns
from tests import initialize
diff --git a/integration/tests/integration/tests/api/instances_quotas.py b/integration/tests/integration/tests/api/instances_quotas.py
deleted file mode 100644
index 3a1c2de6..00000000
--- a/integration/tests/integration/tests/api/instances_quotas.py
+++ /dev/null
@@ -1,47 +0,0 @@
-from proboscis import before_class
-from proboscis import test
-from proboscis.asserts import assert_raises
-
-from troveclient.compat import exceptions
-from trove.tests.config import CONFIG
-from trove.tests.util import create_client
-
-
-@test(groups=['dbaas.api.instances.quotas'])
-class InstanceQuotas(object):
-
- created_instances = []
-
- @before_class
- def setup(self):
- self.client = create_client(is_admin=False)
-
- @test
- def test_too_many_instances(self):
- self.created_instances = []
- if 'trove_max_instances_per_user' in CONFIG.values:
- too_many = CONFIG.values['trove_max_instances_per_user']
- already_there = len(self.client.instances.list())
- flavor = 1
- for i in range(too_many - already_there):
- response = self.client.instances.create('too_many_%d' % i,
- flavor,
- {'size': 1})
- self.created_instances.append(response)
- # This one better fail, because we just reached our quota.
- assert_raises(exceptions.OverLimit,
- self.client.instances.create,
- "too_many", flavor,
- {'size': 1})
-
- @test(runs_after=[test_too_many_instances])
- def delete_excessive_entries(self):
- # Delete all the instances called too_many*.
- for id in self.created_instances:
- while True:
- try:
- self.client.instances.delete(id)
- except exceptions.UnprocessableEntity:
- continue
- except exceptions.NotFound:
- break
diff --git a/run_tests.py b/run_tests.py
index 95c2f3b8..bc1006dc 100644
--- a/run_tests.py
+++ b/run_tests.py
@@ -206,7 +206,6 @@ def import_tests():
from trove.tests.api import configurations # noqa
from trove.tests.api import databases # noqa
from trove.tests.api import datastores # noqa
- from trove.tests.api import flavors # noqa
from trove.tests.api import header # noqa
from trove.tests.api import instances as rd_instances # noqa
from trove.tests.api import instances_actions as rd_actions # noqa
diff --git a/trove/common/notification.py b/trove/common/notification.py
index 70d2071f..0ceddf83 100644
--- a/trove/common/notification.py
+++ b/trove/common/notification.py
@@ -447,6 +447,15 @@ class DBaaSInstanceCreate(DBaaSAPINotification):
return ['instance_id']
+class DBaaSInstanceReboot(DBaaSAPINotification):
+
+ def event_type(self):
+ return 'instance_reboot'
+
+ def required_start_traits(self):
+ return ['instance_id']
+
+
class DBaaSInstanceRestart(DBaaSAPINotification):
def event_type(self):
diff --git a/trove/extensions/mgmt/instances/service.py b/trove/extensions/mgmt/instances/service.py
index 914dc9a6..7c4f95dc 100644
--- a/trove/extensions/mgmt/instances/service.py
+++ b/trove/extensions/mgmt/instances/service.py
@@ -131,7 +131,14 @@ class MgmtInstanceController(InstanceController):
def _action_reboot(self, context, instance, req, body):
LOG.debug("Rebooting instance %s.", instance.id)
- instance.reboot()
+
+ context.notification = notification.DBaaSInstanceReboot(
+ context,
+ request=req
+ )
+ with StartNotification(context, instance_id=instance.id):
+ instance.reboot()
+
return wsgi.Result(None, 202)
def _action_migrate(self, context, instance, req, body):
diff --git a/trove/instance/service.py b/trove/instance/service.py
index 1e558f5f..d8007dd8 100644
--- a/trove/instance/service.py
+++ b/trove/instance/service.py
@@ -36,13 +36,11 @@ from trove.instance import models, views
from trove.module import models as module_models
from trove.module import views as module_views
-
CONF = cfg.CONF
LOG = logging.getLogger(__name__)
class InstanceController(wsgi.Controller):
-
"""Controller for instance functionality."""
schemas = apischema.instance.copy()
@@ -86,7 +84,7 @@ class InstanceController(wsgi.Controller):
'restart': self._action_restart,
'resize': self._action_resize,
'promote_to_replica_source':
- self._action_promote_to_replica_source,
+ self._action_promote_to_replica_source,
'eject_replica_source': self._action_eject_replica_source,
'reset_status': self._action_reset_status,
}
@@ -478,7 +476,7 @@ class InstanceController(wsgi.Controller):
LOG.debug("Default config for instance %(instance_id)s is %(config)s",
{'instance_id': id, 'config': config})
return wsgi.Result(views.DefaultConfigurationView(
- config).data(), 200)
+ config).data(), 200)
def guest_log_list(self, req, tenant_id, id):
"""Return all information about all logs for an instance."""
diff --git a/trove/taskmanager/models.py b/trove/taskmanager/models.py
index 3b855e35..f4c8b8bc 100755
--- a/trove/taskmanager/models.py
+++ b/trove/taskmanager/models.py
@@ -1259,7 +1259,6 @@ class BuiltInstanceTasks(BuiltInstance, NotifyMixin, ConfigurationMixin):
def reboot(self):
try:
- # Issue a guest stop db call to shutdown the db if running
LOG.debug("Stopping datastore on instance %s.", self.id)
try:
self.guest.stop_db()
@@ -1268,15 +1267,27 @@ class BuiltInstanceTasks(BuiltInstance, NotifyMixin, ConfigurationMixin):
# Also we check guest state before issuing reboot
LOG.debug(str(e))
- self._refresh_datastore_status()
- if not (self.datastore_status_matches(
- rd_instance.ServiceStatuses.SHUTDOWN) or
+ # Wait for the mysql stopped.
+ def _datastore_is_offline():
+ self._refresh_datastore_status()
+ return (
self.datastore_status_matches(
- rd_instance.ServiceStatuses.CRASHED)):
- # We will bail if db did not get stopped or is blocked
- LOG.error("Cannot reboot instance. DB status is %s.",
+ rd_instance.ServiceStatuses.SHUTDOWN) or
+ self.datastore_status_matches(
+ rd_instance.ServiceStatuses.CRASHED)
+ )
+
+ try:
+ utils.poll_until(
+ _datastore_is_offline,
+ sleep_time=3,
+ time_out=CONF.reboot_time_out
+ )
+ except exception.PollTimeOut:
+ LOG.error("Cannot reboot instance, DB status is %s",
self.datastore_status.status)
return
+
LOG.debug("The guest service status is %s.",
self.datastore_status.status)
@@ -1291,7 +1302,7 @@ class BuiltInstanceTasks(BuiltInstance, NotifyMixin, ConfigurationMixin):
utils.poll_until(
update_server_info,
- sleep_time=2,
+ sleep_time=3,
time_out=reboot_time_out)
# Set the status to PAUSED. The guest agent will reset the status
@@ -1302,7 +1313,6 @@ class BuiltInstanceTasks(BuiltInstance, NotifyMixin, ConfigurationMixin):
LOG.error("Failed to reboot instance %(id)s: %(e)s",
{'id': self.id, 'e': str(e)})
finally:
- LOG.debug("Rebooting FINALLY %s", self.id)
self.reset_task_status()
def restart(self):
diff --git a/trove/tests/api/backups.py b/trove/tests/api/backups.py
index dd0e9cb4..8504d2fd 100644
--- a/trove/tests/api/backups.py
+++ b/trove/tests/api/backups.py
@@ -52,7 +52,7 @@ backup_count_prior_to_create = 0
backup_count_for_instance_prior_to_create = 0
-@test(depends_on_groups=[instances_actions.GROUP_STOP_MYSQL],
+@test(depends_on_groups=[instances_actions.GROUP_RESIZE],
groups=[BACKUP_GROUP, tests.INSTANCES],
enabled=CONFIG.swift_enabled)
class CreateBackups(object):
@@ -379,7 +379,7 @@ class DeleteRestoreInstance(object):
assert_raises(exceptions.NotFound, instance_info.dbaas.instances.get,
instance_id)
- @test(runs_after=[VerifyRestore.test_database_restored_incremental])
+ @test(depends_on=[VerifyRestore.test_database_restored_incremental])
def test_delete_restored_instance_incremental(self):
try:
self._delete(incremental_restore_instance_id)
diff --git a/trove/tests/api/flavors.py b/trove/tests/api/flavors.py
deleted file mode 100644
index c5f34234..00000000
--- a/trove/tests/api/flavors.py
+++ /dev/null
@@ -1,265 +0,0 @@
-# Copyright (c) 2011 OpenStack Foundation
-# All Rights Reserved.
-#
-# 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.
-
-import os
-
-from nose.tools import assert_equal
-from nose.tools import assert_false
-from nose.tools import assert_true
-from proboscis.asserts import assert_raises
-from proboscis import before_class
-from proboscis.decorators import time_out
-from proboscis import test
-from trove.common.utils import poll_until
-from trove import tests
-from trove.tests.api.instances import TIMEOUT_INSTANCE_CREATE
-from trove.tests.config import CONFIG
-from trove.tests.util.check import AttrCheck
-from trove.tests.util import create_dbaas_client
-from trove.tests.util import create_nova_client
-from trove.tests.util import test_config
-from trove.tests.util.users import Requirements
-from troveclient.compat import exceptions
-from troveclient.v1.flavors import Flavor
-
-GROUP = "dbaas.api.flavors"
-GROUP_DS = "dbaas.api.datastores"
-FAKE_MODE = test_config.values['fake_mode']
-
-servers_flavors = None
-dbaas_flavors = None
-user = None
-
-
-def assert_attributes_equal(name, os_flavor, dbaas_flavor):
- """Given an attribute name and two objects,
- ensures the attribute is equal.
- """
- assert_true(hasattr(os_flavor, name),
- "open stack flavor did not have attribute %s" % name)
- assert_true(hasattr(dbaas_flavor, name),
- "dbaas flavor did not have attribute %s" % name)
- expected = getattr(os_flavor, name)
- actual = getattr(dbaas_flavor, name)
- assert_equal(expected, actual,
- 'DBaas flavor differs from Open Stack on attribute ' + name)
-
-
-def assert_flavors_roughly_equivalent(os_flavor, dbaas_flavor):
- assert_attributes_equal('name', os_flavor, dbaas_flavor)
- assert_attributes_equal('ram', os_flavor, dbaas_flavor)
-
-
-def assert_link_list_is_equal(flavor):
- assert_true(hasattr(flavor, 'links'))
- assert_true(flavor.links)
-
- if flavor.id:
- flavor_id = str(flavor.id)
- else:
- flavor_id = flavor.str_id
-
- for link in flavor.links:
- href = link['href']
-
- if "self" in link['rel']:
- expected_href = os.path.join(test_config.dbaas_url, "flavors",
- str(flavor.id))
- url = test_config.dbaas_url.replace('http:', 'https:', 1)
- msg = ("REL HREF %s doesn't start with %s" %
- (href, test_config.dbaas_url))
- assert_true(href.startswith(url), msg)
- url = os.path.join("flavors", flavor_id)
- msg = "REL HREF %s doesn't end in '%s'" % (href, url)
- assert_true(href.endswith(url), msg)
- elif "bookmark" in link['rel']:
- base_url = test_config.version_url.replace('http:', 'https:', 1)
- expected_href = os.path.join(base_url, "flavors", flavor_id)
- msg = 'bookmark "href" must be %s, not %s' % (expected_href, href)
- assert_equal(href, expected_href, msg)
- else:
- assert_false(True, "Unexpected rel - %s" % link['rel'])
-
-
-@test(groups=[tests.DBAAS_API, GROUP, GROUP_DS, tests.PRE_INSTANCES],
- depends_on_groups=["services.initialize"])
-class Flavors(object):
- @before_class
- def setUp(self):
- rd_user = test_config.users.find_user(
- Requirements(is_admin=False, services=["trove"]))
- self.rd_client = create_dbaas_client(rd_user)
-
- if test_config.nova_client is not None:
- nova_user = test_config.users.find_user(
- Requirements(services=["nova"]))
- self.nova_client = create_nova_client(nova_user)
-
- def get_expected_flavors(self):
- # If we have access to the client, great! Let's use that as the flavors
- # returned by Trove should be identical.
- if test_config.nova_client is not None:
- return self.nova_client.flavors.list()
- # If we don't have access to the client the flavors need to be spelled
- # out in the config file.
- flavors = [Flavor(Flavors, flavor_dict, loaded=True)
- for flavor_dict in test_config.flavors]
- return flavors
-
- @test
- def confirm_flavors_lists_nearly_identical(self):
- os_flavors = self.get_expected_flavors()
- dbaas_flavors = self.rd_client.flavors.list()
-
- print("Open Stack Flavors:")
- print(os_flavors)
- print("DBaaS Flavors:")
- print(dbaas_flavors)
- # Length of both flavors list should be identical.
- assert_equal(len(os_flavors), len(dbaas_flavors))
- for os_flavor in os_flavors:
- found_index = None
- for index, dbaas_flavor in enumerate(dbaas_flavors):
- if os_flavor.name == dbaas_flavor.name:
- msg = ("Flavor ID '%s' appears in elements #%s and #%d." %
- (dbaas_flavor.id, str(found_index), index))
- assert_true(found_index is None, msg)
- assert_flavors_roughly_equivalent(os_flavor, dbaas_flavor)
- found_index = index
- msg = "Some flavors from OS list were missing in DBAAS list."
- assert_false(found_index is None, msg)
- for flavor in dbaas_flavors:
- assert_link_list_is_equal(flavor)
-
- @test
- def test_flavor_list_attrs(self):
- allowed_attrs = ['id', 'name', 'ram', 'vcpus', 'disk', 'links',
- 'ephemeral', 'local_storage', 'str_id']
- flavors = self.rd_client.flavors.list()
- attrcheck = AttrCheck()
- for flavor in flavors:
- flavor_dict = flavor._info
- attrcheck.contains_allowed_attrs(
- flavor_dict, allowed_attrs,
- msg="Flavors list")
- attrcheck.links(flavor_dict['links'])
-
- @test
- def test_flavor_get_attrs(self):
- allowed_attrs = ['id', 'name', 'ram', 'vcpus', 'disk', 'links',
- 'ephemeral', 'local_storage', 'str_id']
- flavor = self.rd_client.flavors.get(1)
- attrcheck = AttrCheck()
- flavor_dict = flavor._info
- attrcheck.contains_allowed_attrs(
- flavor_dict, allowed_attrs,
- msg="Flavor Get 1")
- attrcheck.links(flavor_dict['links'])
-
- @test
- def test_flavor_not_found(self):
- assert_raises(exceptions.NotFound,
- self.rd_client.flavors.get, "foo")
-
- @test
- def test_flavor_list_datastore_version_associated_flavors(self):
- datastore = self.rd_client.datastores.get(
- test_config.dbaas_datastore)
- dbaas_flavors = (self.rd_client.flavors.
- list_datastore_version_associated_flavors(
- datastore=test_config.dbaas_datastore,
- version_id=datastore.default_version))
- os_flavors = self.get_expected_flavors()
- assert_equal(len(dbaas_flavors), len(os_flavors))
- # verify flavor lists are identical
- for os_flavor in os_flavors:
- found_index = None
- for index, dbaas_flavor in enumerate(dbaas_flavors):
- if os_flavor.name == dbaas_flavor.name:
- msg = ("Flavor ID '%s' appears in elements #%s and #%d." %
- (dbaas_flavor.id, str(found_index), index))
- assert_true(found_index is None, msg)
- assert_flavors_roughly_equivalent(os_flavor, dbaas_flavor)
- found_index = index
- msg = "Some flavors from OS list were missing in DBAAS list."
- assert_false(found_index is None, msg)
- for flavor in dbaas_flavors:
- assert_link_list_is_equal(flavor)
-
-
-@test(runs_after=[Flavors],
- groups=[tests.DBAAS_API, GROUP, GROUP_DS],
- depends_on_groups=["services.initialize"],
- enabled=FAKE_MODE)
-class DatastoreFlavorAssociation(object):
- @before_class
- def setUp(self):
- rd_user = test_config.users.find_user(
- Requirements(is_admin=False, services=["trove"]))
- self.rd_client = create_dbaas_client(rd_user)
-
- self.datastore = self.rd_client.datastores.get(
- test_config.dbaas_datastore)
- self.name1 = "test_instance1"
- self.name2 = "test_instance2"
- self.volume = {'size': 2}
- self.instance_id = None
- self.nics = None
- shared_network = CONFIG.get('shared_network', None)
- if shared_network:
- self.nics = [{'net-id': shared_network}]
-
- @test
- @time_out(TIMEOUT_INSTANCE_CREATE)
- def test_create_instance_with_valid_flavor_association(self):
- # all the nova flavors are associated with the default datastore
- result = self.rd_client.instances.create(
- name=self.name1, flavor_id='1', volume=self.volume,
- datastore=self.datastore.id,
- nics=self.nics)
- self.instance_id = result.id
- assert_equal(200, self.rd_client.last_http_code)
-
- def result_is_active():
- instance = self.rd_client.instances.get(self.instance_id)
- if instance.status == "ACTIVE":
- return True
- else:
- # If its not ACTIVE, anything but BUILD must be
- # an error.
- assert_equal("BUILD", instance.status)
- return False
-
- poll_until(result_is_active)
- self.rd_client.instances.delete(self.instance_id)
-
- @test(runs_after=[test_create_instance_with_valid_flavor_association])
- def test_create_instance_with_invalid_flavor_association(self):
- dbaas_flavors = (self.rd_client.flavors.
- list_datastore_version_associated_flavors(
- datastore=test_config.dbaas_datastore,
- version_id=self.datastore.default_version))
- self.flavor_not_associated = None
- os_flavors = Flavors().get_expected_flavors()
- for os_flavor in os_flavors:
- if os_flavor not in dbaas_flavors:
- self.flavor_not_associated = os_flavor.id
- break
- if self.flavor_not_associated is not None:
- assert_raises(exceptions.BadRequest,
- self.rd_client.instances.create, self.name2,
- flavor_not_associated, self.volume,
- datastore=self.datastore.id,
- nics=self.nics)
diff --git a/trove/tests/api/instances.py b/trove/tests/api/instances.py
index e8ef0468..e48ce668 100644
--- a/trove/tests/api/instances.py
+++ b/trove/tests/api/instances.py
@@ -16,11 +16,9 @@
import netaddr
import os
import time
-from time import sleep
import unittest
import uuid
-from proboscis import after_class
from proboscis.asserts import assert_equal
from proboscis.asserts import assert_false
from proboscis.asserts import assert_is_not_none
@@ -35,7 +33,6 @@ from proboscis import test
from troveclient.compat import exceptions
from trove.common import cfg
-from trove.common import exception as rd_exceptions
from trove.common.utils import poll_until
from trove.datastore import models as datastore_models
from trove import tests
@@ -116,15 +113,17 @@ class InstanceTestInfo(object):
'eph.rd-tiny')
else:
flavor_name = CONFIG.values.get('instance_flavor_name', 'm1.tiny')
+
flavors = self.dbaas.find_flavors_by_name(flavor_name)
assert_equal(len(flavors), 1,
"Number of flavors with name '%s' "
"found was '%d'." % (flavor_name, len(flavors)))
+
flavor = flavors[0]
- assert_true(flavor is not None, "Flavor '%s' not found!" % flavor_name)
flavor_href = self.dbaas.find_flavor_self_href(flavor)
assert_true(flavor_href is not None,
"Flavor href '%s' not found!" % flavor_name)
+
return flavor, flavor_href
def get_address(self, mgmt=False):
@@ -255,17 +254,10 @@ def test_delete_instance_not_found():
groups=[GROUP, GROUP_QUOTAS],
runs_after_groups=[tests.PRE_INSTANCES])
class CreateInstanceQuotaTest(unittest.TestCase):
-
- def setUp(self):
- import copy
-
- self.test_info = copy.deepcopy(instance_info)
- self.test_info.dbaas_datastore = CONFIG.dbaas_datastore
-
def tearDown(self):
quota_dict = {'instances': CONFIG.trove_max_instances_per_tenant,
'volumes': CONFIG.trove_max_volumes_per_tenant}
- dbaas_admin.quota.update(self.test_info.user.tenant_id,
+ dbaas_admin.quota.update(instance_info.user.tenant_id,
quota_dict)
def test_instance_size_too_big(self):
@@ -273,52 +265,48 @@ class CreateInstanceQuotaTest(unittest.TestCase):
VOLUME_SUPPORT):
too_big = CONFIG.trove_max_accepted_volume_size
- self.test_info.volume = {'size': too_big + 1}
- self.test_info.name = "way_too_large"
assert_raises(exceptions.OverLimit,
dbaas.instances.create,
- self.test_info.name,
- self.test_info.dbaas_flavor_href,
- self.test_info.volume,
+ "volume_size_too_large",
+ instance_info.dbaas_flavor_href,
+ {'size': too_big + 1},
nics=instance_info.nics)
def test_update_quota_invalid_resource_should_fail(self):
quota_dict = {'invalid_resource': 100}
assert_raises(exceptions.NotFound, dbaas_admin.quota.update,
- self.test_info.user.tenant_id, quota_dict)
+ instance_info.user.tenant_id, quota_dict)
def test_update_quota_volume_should_fail_volume_not_supported(self):
if VOLUME_SUPPORT:
raise SkipTest("Volume support needs to be disabled")
quota_dict = {'volumes': 100}
assert_raises(exceptions.NotFound, dbaas_admin.quota.update,
- self.test_info.user.tenant_id, quota_dict)
+ instance_info.user.tenant_id, quota_dict)
def test_create_too_many_instances(self):
instance_quota = 0
quota_dict = {'instances': instance_quota}
- new_quotas = dbaas_admin.quota.update(self.test_info.user.tenant_id,
+ new_quotas = dbaas_admin.quota.update(instance_info.user.tenant_id,
quota_dict)
- set_quota = dbaas_admin.quota.show(self.test_info.user.tenant_id)
+ set_quota = dbaas_admin.quota.show(instance_info.user.tenant_id)
verify_quota = {q.resource: q.limit for q in set_quota}
assert_equal(new_quotas['instances'], quota_dict['instances'])
assert_equal(0, verify_quota['instances'])
- self.test_info.volume = None
+ volume = None
if VOLUME_SUPPORT:
assert_equal(CONFIG.trove_max_volumes_per_tenant,
verify_quota['volumes'])
- self.test_info.volume = {'size':
- CONFIG.get('trove_volume_size', 1)}
+ volume = {'size': CONFIG.get('trove_volume_size', 1)}
- self.test_info.name = "too_many_instances"
assert_raises(exceptions.OverLimit,
dbaas.instances.create,
- self.test_info.name,
- self.test_info.dbaas_flavor_href,
- self.test_info.volume,
+ "too_many_instances",
+ instance_info.dbaas_flavor_href,
+ volume,
nics=instance_info.nics)
assert_equal(413, dbaas.last_http_code)
@@ -328,17 +316,15 @@ class CreateInstanceQuotaTest(unittest.TestCase):
raise SkipTest("Volume support not enabled")
volume_quota = 3
quota_dict = {'volumes': volume_quota}
- self.test_info.volume = {'size': volume_quota + 1}
- new_quotas = dbaas_admin.quota.update(self.test_info.user.tenant_id,
+ new_quotas = dbaas_admin.quota.update(instance_info.user.tenant_id,
quota_dict)
assert_equal(volume_quota, new_quotas['volumes'])
- self.test_info.name = "too_large_volume"
assert_raises(exceptions.OverLimit,
dbaas.instances.create,
- self.test_info.name,
- self.test_info.dbaas_flavor_href,
- self.test_info.volume,
+ "too_large_volume",
+ instance_info.dbaas_flavor_href,
+ {'size': volume_quota + 1},
nics=instance_info.nics)
assert_equal(413, dbaas.last_http_code)
@@ -474,6 +460,7 @@ class CreateInstanceFail(object):
databases = []
flavor_name = CONFIG.values.get('instance_flavor_name', 'm1.tiny')
flavors = dbaas.find_flavors_by_name(flavor_name)
+
assert_raises(exceptions.BadRequest, dbaas.instances.create,
instance_name, flavors[0].id, None, databases,
nics=instance_info.nics)
@@ -1508,86 +1495,3 @@ class CheckInstance(AttrCheck):
slave, allowed_attrs,
msg="Replica links not found")
self.links(slave['links'])
-
-
-@test(groups=[GROUP])
-class BadInstanceStatusBug(object):
-
- @before_class()
- def setUp(self):
- self.instances = []
- reqs = Requirements(is_admin=True)
- self.user = CONFIG.users.find_user(
- reqs, black_list=[])
- self.client = create_dbaas_client(self.user)
- self.mgmt = self.client.management
-
- @test
- def test_instance_status_after_double_migrate(self):
- """
- This test is to verify that instance status returned is more
- informative than 'Status is {}'. There are several ways to
- replicate this error. A double migration is just one of them but
- since this is a known way to recreate that error we will use it
- here to be sure that the error is fixed. The actual code lives
- in trove/instance/models.py in _validate_can_perform_action()
- """
- # TODO(imsplitbit): test other instances where this issue could be
- # replicated. Resizing a resized instance awaiting confirmation
- # can be used as another case. This all boils back to the same
- # piece of code so I'm not sure if it's relevant or not but could
- # be done.
- size = None
- if VOLUME_SUPPORT:
- size = {'size': 5}
-
- result = self.client.instances.create('testbox',
- instance_info.dbaas_flavor_href,
- size,
- nics=instance_info.nics)
- id = result.id
- self.instances.append(id)
-
- def verify_instance_is_active():
- result = self.client.instances.get(id)
- print(result.status)
- return result.status == 'ACTIVE'
-
- def attempt_migrate():
- print('attempting migration')
- try:
- self.mgmt.migrate(id)
- except exceptions.UnprocessableEntity:
- return False
- return True
-
- # Timing necessary to make the error occur
- poll_until(verify_instance_is_active, time_out=120, sleep_time=1)
-
- try:
- poll_until(attempt_migrate, time_out=10, sleep_time=1)
- except rd_exceptions.PollTimeOut:
- fail('Initial migration timed out')
-
- try:
- self.mgmt.migrate(id)
- except exceptions.UnprocessableEntity as err:
- assert('status was {}' not in err.message)
- else:
- # If we are trying to test what status is returned when an
- # instance is in a confirm_resize state and another
- # migration is attempted then we also need to
- # assert that an exception is raised when running migrate.
- # If one is not then we aren't able to test what the
- # returned status is in the exception message.
- fail('UnprocessableEntity was not thrown')
-
- @after_class(always_run=True)
- def tearDown(self):
- while len(self.instances) > 0:
- for id in self.instances:
- try:
- self.client.instances.delete(id)
- self.instances.remove(id)
- except exceptions.UnprocessableEntity:
- sleep(1.0)
diff --git a/trove/tests/api/instances_actions.py b/trove/tests/api/instances_actions.py
index 1ed36e90..1bcb40cf 100644
--- a/trove/tests/api/instances_actions.py
+++ b/trove/tests/api/instances_actions.py
@@ -45,6 +45,7 @@ GROUP_REBOOT = "dbaas.api.instances.actions.reboot"
GROUP_RESTART = "dbaas.api.instances.actions.restart"
GROUP_RESIZE = "dbaas.api.instances.actions.resize"
GROUP_STOP_MYSQL = "dbaas.api.instances.actions.stop"
+GROUP_UPDATE_GUEST = "dbaas.api.instances.actions.update_guest"
MYSQL_USERNAME = "test_user"
MYSQL_PASSWORD = "abcde"
# stored in test conf
@@ -104,7 +105,6 @@ def get_resize_timeout():
TIME_OUT_TIME = get_resize_timeout()
-USER_WAS_DELETED = False
class ActionTestBase(object):
@@ -223,23 +223,25 @@ class RebootTestBase(ActionTestBase):
def call_reboot(self):
raise NotImplementedError()
- def wait_for_broken_connection(self):
- """Wait until our connection breaks."""
- if not USE_IP:
- return
- if not hasattr(self, "connection"):
- return
- poll_until(self.connection.is_connected,
- lambda connected: not connected,
- time_out=TIME_OUT_TIME)
-
def wait_for_successful_restart(self):
- """Wait until status becomes running."""
- def is_finished_rebooting():
+ """Wait until status becomes running.
+
+ Reboot is an async operation, make sure the instance is rebooting
+ before active.
+ """
+ def _is_rebooting():
instance = self.instance
if instance.status == "REBOOT":
+ return True
+ return False
+
+ poll_until(_is_rebooting, time_out=TIME_OUT_TIME)
+
+ def is_finished_rebooting():
+ instance = self.instance
+ asserts.assert_not_equal(instance.status, "ERROR")
+ if instance.status != "ACTIVE":
return False
- asserts.assert_equal("ACTIVE", instance.status)
return True
poll_until(is_finished_rebooting, time_out=TIME_OUT_TIME)
@@ -253,45 +255,10 @@ class RebootTestBase(ActionTestBase):
def successful_restart(self):
"""Restart MySQL via the REST API successfully."""
- self.fix_mysql()
self.call_reboot()
- self.wait_for_broken_connection()
self.wait_for_successful_restart()
self.assert_mysql_proc_is_different()
- def mess_up_mysql(self):
- """Ruin MySQL's ability to restart."""
- server = create_server_connection(self.instance_id,
- self.instance_mgmt_address)
- cmd_template = "sudo cp /dev/null /var/lib/mysql/data/ib_logfile%d"
- instance_info.dbaas_admin.management.stop(self.instance_id)
-
- for index in range(2):
- cmd = cmd_template % index
- try:
- server.execute(cmd)
- except Exception as e:
- asserts.fail("Failed to execute command %s, error: %s" %
- (cmd, str(e)))
-
- def fix_mysql(self):
- """Fix MySQL's ability to restart."""
- if not FAKE_MODE:
- server = create_server_connection(self.instance_id,
- self.instance_mgmt_address)
- cmd_template = "sudo rm /var/lib/mysql/data/ib_logfile%d"
- # We want to stop mysql so that upstart does not keep trying to
- # respawn it and block the guest agent from accessing the logs.
- instance_info.dbaas_admin.management.stop(self.instance_id)
-
- for index in range(2):
- cmd = cmd_template % index
- try:
- server.execute(cmd)
- except Exception as e:
- asserts.fail("Failed to execute command %s, error: %s" %
- (cmd, str(e)))
-
def wait_for_failure_status(self):
"""Wait until status becomes running."""
def is_finished_rebooting():
@@ -306,19 +273,6 @@ class RebootTestBase(ActionTestBase):
poll_until(is_finished_rebooting, time_out=TIME_OUT_TIME)
- def unsuccessful_restart(self):
- """Restart MySQL via the REST when it should fail, assert it does."""
- assert not FAKE_MODE
- self.mess_up_mysql()
- self.call_reboot()
- self.wait_for_broken_connection()
- self.wait_for_failure_status()
-
- def restart_normally(self):
- """Fix iblogs and reboot normally."""
- self.fix_mysql()
- self.test_successful_restart()
-
@test(groups=[tests.INSTANCES, INSTANCE_GROUP, GROUP, GROUP_RESTART],
depends_on_groups=[GROUP_START], depends_on=[create_user])
@@ -338,22 +292,14 @@ class RestartTests(RebootTestBase):
"""Make sure MySQL is accessible before restarting."""
self.ensure_mysql_is_running()
- @test(depends_on=[test_ensure_mysql_is_running], enabled=not FAKE_MODE)
- def test_unsuccessful_restart(self):
- """Restart MySQL via the REST when it should fail, assert it does."""
- if FAKE_MODE:
- raise SkipTest("Cannot run this in fake mode.")
- self.unsuccessful_restart()
-
- @test(depends_on=[test_set_up],
- runs_after=[test_ensure_mysql_is_running, test_unsuccessful_restart])
+ @test(depends_on=[test_ensure_mysql_is_running])
def test_successful_restart(self):
"""Restart MySQL via the REST API successfully."""
self.successful_restart()
@test(groups=[tests.INSTANCES, INSTANCE_GROUP, GROUP, GROUP_STOP_MYSQL],
- depends_on_groups=[GROUP_START], depends_on=[create_user])
+ depends_on_groups=[GROUP_RESTART], depends_on=[create_user])
class StopTests(RebootTestBase):
"""Tests which involve stopping MySQL."""
@@ -373,11 +319,10 @@ class StopTests(RebootTestBase):
def test_stop_mysql(self):
"""Stops MySQL."""
instance_info.dbaas_admin.management.stop(self.instance_id)
- self.wait_for_broken_connection()
self.wait_for_failure_status()
@test(depends_on=[test_stop_mysql])
- def test_instance_get_shows_volume_info_while_mysql_is_down(self):
+ def test_volume_info_while_mysql_is_down(self):
"""
Confirms the get call behaves appropriately while an instance is
down.
@@ -392,15 +337,14 @@ class StopTests(RebootTestBase):
check.true(isinstance(instance.volume.get('size', None), int))
check.true(isinstance(instance.volume.get('used', None), float))
- @test(depends_on=[test_set_up],
- runs_after=[test_instance_get_shows_volume_info_while_mysql_is_down])
+ @test(depends_on=[test_volume_info_while_mysql_is_down])
def test_successful_restart_when_in_shutdown_state(self):
"""Restart MySQL via the REST API successfully when MySQL is down."""
self.successful_restart()
@test(groups=[tests.INSTANCES, INSTANCE_GROUP, GROUP, GROUP_REBOOT],
- depends_on_groups=[GROUP_START], depends_on=[RestartTests, create_user])
+ depends_on_groups=[GROUP_STOP_MYSQL])
class RebootTests(RebootTestBase):
"""Tests restarting instance."""
@@ -418,14 +362,7 @@ class RebootTests(RebootTestBase):
"""Make sure MySQL is accessible before restarting."""
self.ensure_mysql_is_running()
- @test(depends_on=[test_ensure_mysql_is_running])
- def test_unsuccessful_restart(self):
- """Restart MySQL via the REST when it should fail, assert it does."""
- if FAKE_MODE:
- raise SkipTest("Cannot run this in fake mode.")
- self.unsuccessful_restart()
-
- @after_class(depends_on=[test_set_up])
+ @after_class(depends_on=[test_ensure_mysql_is_running])
def test_successful_restart(self):
"""Restart MySQL via the REST API successfully."""
if FAKE_MODE:
@@ -434,8 +371,7 @@ class RebootTests(RebootTestBase):
@test(groups=[tests.INSTANCES, INSTANCE_GROUP, GROUP, GROUP_RESIZE],
- depends_on_groups=[GROUP_START], depends_on=[create_user],
- runs_after=[RebootTests])
+ depends_on_groups=[GROUP_REBOOT])
class ResizeInstanceTest(ActionTestBase):
"""
@@ -466,7 +402,6 @@ class ResizeInstanceTest(ActionTestBase):
self.connection.connect()
asserts.assert_true(self.connection.is_connected(),
"Should be able to connect before resize.")
- self.user_was_deleted = False
@test
def test_instance_resize_same_size_should_fail(self):
@@ -484,8 +419,6 @@ class ResizeInstanceTest(ActionTestBase):
poll_until(is_active, time_out=TIME_OUT_TIME)
asserts.assert_equal(self.instance.status, 'ACTIVE')
- self.get_flavor_href(
- flavor_id=self.expected_old_flavor_id)
asserts.assert_raises(HTTPNotImplemented,
self.dbaas.instances.resize_instance,
self.instance_id, flavors[0].id)
@@ -517,11 +450,6 @@ class ResizeInstanceTest(ActionTestBase):
flavor = flavors[0]
self.old_dbaas_flavor = instance_info.dbaas_flavor
instance_info.dbaas_flavor = flavor
- asserts.assert_true(flavor is not None,
- "Flavor '%s' not found!" % flavor_name)
- flavor_href = self.dbaas.find_flavor_self_href(flavor)
- asserts.assert_true(flavor_href is not None,
- "Flavor href '%s' not found!" % flavor_name)
self.expected_new_flavor_id = flavor.id
@test(depends_on=[test_instance_resize_same_size_should_fail])
@@ -579,45 +507,6 @@ class ResizeInstanceTest(ActionTestBase):
expected = self.get_flavor_href(flavor_id=self.expected_new_flavor_id)
asserts.assert_equal(actual, expected)
- @test(depends_on=[test_instance_has_new_flavor_after_resize])
- @time_out(TIME_OUT_TIME)
- def test_resize_down(self):
- expected_dbaas_flavor = self.expected_dbaas_flavor
-
- def is_active():
- return self.instance.status == 'ACTIVE'
- poll_until(is_active, time_out=TIME_OUT_TIME)
- asserts.assert_equal(self.instance.status, 'ACTIVE')
-
- old_flavor_href = self.get_flavor_href(
- flavor_id=self.expected_old_flavor_id)
-
- self.dbaas.instances.resize_instance(self.instance_id, old_flavor_href)
- asserts.assert_equal(202, self.dbaas.last_http_code)
- self.old_dbaas_flavor = instance_info.dbaas_flavor
- instance_info.dbaas_flavor = expected_dbaas_flavor
- self.wait_for_resize()
- asserts.assert_equal(str(self.instance.flavor['id']),
- str(self.expected_old_flavor_id))
-
- @test(depends_on=[test_resize_down],
- groups=["dbaas.usage"])
- def test_resize_instance_down_usage_event_sent(self):
- expected = self._build_expected_msg()
- expected['old_instance_size'] = self.old_dbaas_flavor.ram
- instance_info.consumer.check_message(instance_info.id,
- 'trove.instance.modify_flavor',
- **expected)
-
-
-@test(groups=[tests.INSTANCES, INSTANCE_GROUP, GROUP,
- GROUP + ".resize.instance"],
- depends_on_groups=[GROUP_START], depends_on=[create_user],
- runs_after=[RebootTests, ResizeInstanceTest])
-def resize_should_not_delete_users():
- if USER_WAS_DELETED:
- asserts.fail("Somehow, the resize made the test user disappear.")
-
@test(depends_on=[ResizeInstanceTest],
groups=[GROUP, tests.INSTANCES, INSTANCE_GROUP, GROUP_RESIZE],
@@ -708,9 +597,8 @@ class ResizeInstanceVolume(ActionTestBase):
UPDATE_GUEST_CONF = CONFIG.values.get("guest-update-test", None)
-@test(groups=[tests.INSTANCES, INSTANCE_GROUP, GROUP, GROUP + ".update_guest"],
- depends_on=[create_user],
- depends_on_groups=[GROUP_START])
+@test(groups=[tests.INSTANCES, INSTANCE_GROUP, GROUP, GROUP_UPDATE_GUEST],
+ depends_on_groups=[GROUP_RESIZE])
class UpdateGuest(object):
def get_version(self):
diff --git a/trove/tests/api/instances_mysql_down.py b/trove/tests/api/instances_mysql_down.py
index 18e08fde..7b160527 100644
--- a/trove/tests/api/instances_mysql_down.py
+++ b/trove/tests/api/instances_mysql_down.py
@@ -52,6 +52,7 @@ class TestBase(object):
'm1.tiny')
flavor2_name = test_config.values.get(
'instance_bigger_flavor_name', 'm1.small')
+
flavors = self.client.find_flavors_by_name(flavor_name)
self.flavor_id = flavors[0].id
self.name = "TEST_" + str(uuid.uuid4())
diff --git a/trove/tests/int_tests.py b/trove/tests/int_tests.py
index a3c19ef9..eea92315 100644
--- a/trove/tests/int_tests.py
+++ b/trove/tests/int_tests.py
@@ -18,7 +18,6 @@ from trove.tests.api import backups
from trove.tests.api import configurations
from trove.tests.api import databases
from trove.tests.api import datastores
-from trove.tests.api import flavors
from trove.tests.api import instances
from trove.tests.api import instances_actions
from trove.tests.api.mgmt import accounts
@@ -86,7 +85,6 @@ def register(group_names, *test_groups, **kwargs):
depends_on_groups=build_group(*test_groups))
black_box_groups = [
- flavors.GROUP,
users.GROUP,
user_access.GROUP,
databases.GROUP,
@@ -114,7 +112,6 @@ proboscis.register(groups=["blackbox", "mysql"],
simple_black_box_groups = [
GROUP_SERVICES_INITIALIZE,
- flavors.GROUP,
versions.GROUP,
instances.GROUP_START_SIMPLE,
admin_required.GROUP,
@@ -141,7 +138,6 @@ proboscis.register(groups=["blackbox_mgmt"],
# Base groups for all other groups
base_groups = [
GROUP_SERVICES_INITIALIZE,
- flavors.GROUP,
versions.GROUP,
GROUP_SETUP
]
diff --git a/trove/tests/scenario/runners/instance_create_runners.py b/trove/tests/scenario/runners/instance_create_runners.py
index 3e9e6484..371b0a88 100644
--- a/trove/tests/scenario/runners/instance_create_runners.py
+++ b/trove/tests/scenario/runners/instance_create_runners.py
@@ -199,8 +199,8 @@ class InstanceCreateRunner(TestRunner):
self.assert_equal(instance_info.name, instance._info['name'],
"Unexpected instance name")
- self.assert_equal(flavor.id,
- int(instance._info['flavor']['id']),
+ self.assert_equal(str(flavor.id),
+ str(instance._info['flavor']['id']),
"Unexpected instance flavor")
self.assert_equal(instance_info.dbaas_datastore,
instance._info['datastore']['type'],
diff --git a/trove/tests/scenario/runners/test_runners.py b/trove/tests/scenario/runners/test_runners.py
index be10dac4..221c7a60 100644
--- a/trove/tests/scenario/runners/test_runners.py
+++ b/trove/tests/scenario/runners/test_runners.py
@@ -802,10 +802,8 @@ class TestRunner(object):
self.assert_equal(
1, len(flavors),
"Unexpected number of flavors with name '%s' found." % flavor_name)
- flavor = flavors[0]
- self.assert_is_not_none(flavor, "Flavor '%s' not found." % flavor_name)
- return flavor
+ return flavors[0]
def get_instance_flavor(self, fault_num=None):
name_format = 'instance%s%s_flavor_name'
diff --git a/trove/tests/unittests/mgmt/test_datastores.py b/trove/tests/unittests/mgmt/test_datastores.py
index 94cf2e0b..d1721f39 100644
--- a/trove/tests/unittests/mgmt/test_datastores.py
+++ b/trove/tests/unittests/mgmt/test_datastores.py
@@ -52,7 +52,7 @@ class TestDatastoreVersion(trove_testtools.TestCase):
def test_version_create(self, mock_glance_client):
body = {"version": {
"datastore_name": "test_ds",
- "name": "test_vr",
+ "name": "test_version",
"datastore_manager": "mysql",
"image": "image-id",
"packages": "test-pkg",
diff --git a/trove/tests/unittests/taskmanager/test_models.py b/trove/tests/unittests/taskmanager/test_models.py
index 74fb9253..e91ef383 100644
--- a/trove/tests/unittests/taskmanager/test_models.py
+++ b/trove/tests/unittests/taskmanager/test_models.py
@@ -309,6 +309,7 @@ class FreshInstanceTasksTest(BaseFreshInstanceTasksTest):
new_callable=PropertyMock,
return_value='fake-hostname')
def test_servers_create_block_device_mapping_v2(self, mock_hostname):
+ self.freshinstancetasks._prepare_userdata = Mock(return_value=None)
mock_nova_client = self.freshinstancetasks.nova_client = Mock()
mock_servers_create = mock_nova_client.servers.create
self.freshinstancetasks._create_server('fake-flavor', 'fake-image',
@@ -867,26 +868,23 @@ class BuiltInstanceTasksTest(trove_testtools.TestCase):
@patch.object(utils, 'poll_until')
def test_reboot(self, mock_poll):
- self.instance_task.datastore_status_matches = Mock(return_value=True)
- self.instance_task._refresh_datastore_status = Mock()
self.instance_task.server.reboot = Mock()
self.instance_task.set_datastore_status_to_paused = Mock()
self.instance_task.reboot()
self.instance_task._guest.stop_db.assert_any_call()
- self.instance_task._refresh_datastore_status.assert_any_call()
self.instance_task.server.reboot.assert_any_call()
self.instance_task.set_datastore_status_to_paused.assert_any_call()
@patch.object(utils, 'poll_until')
@patch('trove.taskmanager.models.LOG')
def test_reboot_datastore_not_ready(self, mock_logging, mock_poll):
- self.instance_task.datastore_status_matches = Mock(return_value=False)
- self.instance_task._refresh_datastore_status = Mock()
+ mock_poll.side_effect = PollTimeOut
self.instance_task.server.reboot = Mock()
self.instance_task.set_datastore_status_to_paused = Mock()
+
self.instance_task.reboot()
+
self.instance_task._guest.stop_db.assert_any_call()
- self.instance_task._refresh_datastore_status.assert_any_call()
assert not self.instance_task.server.reboot.called
assert not self.instance_task.set_datastore_status_to_paused.called