From 4c2be0c4c638b59dd026f0e4d63ffa18e18beeb2 Mon Sep 17 00:00:00 2001 From: Ilya Baldin Date: Tue, 21 Feb 2023 12:07:28 -0500 Subject: [PATCH] Added acceptance tests for persistent storage (3.1.3) --- .../functional_test_3.1.3.ipynb | 276 ++++++++++++++++++ 1 file changed, 276 insertions(+) create mode 100644 fabric_examples/acceptance_testing/Acceptance Tests 3.1.3/functional_test_3.1.3.ipynb diff --git a/fabric_examples/acceptance_testing/Acceptance Tests 3.1.3/functional_test_3.1.3.ipynb b/fabric_examples/acceptance_testing/Acceptance Tests 3.1.3/functional_test_3.1.3.ipynb new file mode 100644 index 00000000..4860df17 --- /dev/null +++ b/fabric_examples/acceptance_testing/Acceptance Tests 3.1.3/functional_test_3.1.3.ipynb @@ -0,0 +1,276 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Functional Test 3.1.2 - Attached Storage\n", + "\n", + "This Jupyter notebook will allow you to create VMs on different sites and worker nodes consistent with requirements for test 3.1.3 for testing persistent storage attachment.\n", + "\n", + "## Step 1: Configure the Environment\n", + "\n", + "Before running this notebook, you will need to configure your environment using the [Configure Environment](../../fablib_api/configure_environment/configure_environment.ipynb) notebook. Please stop here, open and run that notebook, then return to this notebook.\n", + "\n", + "**This only needs to be done once.**\n", + "\n", + "## Step 2: Request persistent storage at testing site\n", + "\n", + "Through the portal project view click 'Request Storage' button (or ask Project Owner to do that). In the Jira ticket view request a single 10GB volume for the site that is being tested. Set `Needed until` 3 months forward. Name it the volume `acceptance-testing`. \n", + "\n", + "*Remember* that the storage must be requested on behalf of the 'FABRIC Maintenance' project. You must also be executing this notebook on behalf of this project." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Step 3: Import the FABlib Library" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from fabrictestbed_extensions.fablib.fablib import FablibManager as fablib_manager\n", + "\n", + "fablib = fablib_manager()\n", + "\n", + "fablib.show_config()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Step 4: Check your existing slices\n", + "\n", + "Since testing can get confusing, check what slices you actually have. It may print nothing if you have no active slices." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "try:\n", + " for slice in fablib.get_slices():\n", + " print(f\"{slice}\")\n", + "except Exception as e:\n", + " print(f\"Exception: {e}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Step 5: Create the test Slice\n", + "\n", + "This creates a VM with a single attached volume on a specific worker at a specific site. \n", + "\n", + "**The code to create the slice will auto-refresh until the slice is created or it fails**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "from datetime import datetime\n", + "from dateutil import tz\n", + "\n", + "name='Node1'\n", + "storage_name = 'acceptance-testing'\n", + "site='MICH'\n", + "# since all workers have a standard naming scheme, you can just change the worker\n", + "# to move from worker to worker\n", + "worker=f'{site.lower()}-w1.fabric-testbed.net'\n", + "cores=10\n", + "ram=20\n", + "disk=50\n", + "slice_name=f\"Slice Test 3.1.2-Storage {site} on {worker} on {datetime.now()}\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "try:\n", + " #Create Slice\n", + " print(f'Creating slice {slice_name}')\n", + " slice = fablib.new_slice(name=slice_name)\n", + "\n", + " # Add node\n", + " node = slice.add_node(name=name, site=site, host=worker, cores=cores, ram=ram, disk=disk)\n", + " \n", + " node.add_storage(name=storage_name)\n", + "\n", + " #Submit Slice Request\n", + " slice.submit()\n", + "except Exception as e:\n", + " print(f\"Exception: {e}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Step 6: Observe the Slice's Attributes\n", + "\n", + "### Print the slice " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "try:\n", + " slice.show()\n", + " slice.list_nodes()\n", + "except Exception as e:\n", + " print(f\"Exception: {e}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Step 7: Format and mount the volume\n", + "\n", + "The first time you use your persistent volume it will be a raw block device that needs to be formated." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "try:\n", + " node = slice.get_node('Node1')\n", + " \n", + " storage = node.get_storage(storage_name)\n", + " \n", + " print(f\"Storage Device Name: {storage.get_device_name()}\") \n", + " \n", + " stdout,stderr = node.execute(f\"sudo mkfs.ext4 {storage.get_device_name()}\")\n", + " \n", + "except Exception as e:\n", + " print(f\"Exception: {e}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Mount the volume\n", + "\n", + "Now the volume can be mounted." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "try:\n", + " \n", + " stdout,stderr = node.execute(f\"sudo mkdir /mnt/fabric_storage; \"\n", + " f\"sudo mount {storage.get_device_name()} /mnt/fabric_storage; \"\n", + " f\"df -h\")\n", + " \n", + " \n", + "except Exception as e:\n", + " print(f\"Exception: {e}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Step 8: Verify access\n", + "\n", + "Verify that volume is read/writable." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "try:\n", + " # create 1M file made of zeros\n", + " stdout,stderr = node.execute(f\"sudo dd if=/dev/zero of=/mnt/fabric_storage/zero-file bs=1024 count=1024\")\n", + " # check the file exists\n", + " stdout,stderr = node.execute(f\"ls -lh /mnt/fabric_storage\")\n", + "\n", + "except Exception as e:\n", + " print(f\"Exception: {e}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Step 9: Cleanup Your Slice" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "try:\n", + " slice = fablib.get_slice(name=slice_name)\n", + " slice.delete()\n", + "except Exception as e:\n", + " print(f\"Exception: {e}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +}