Skip to content

Commit

Permalink
Merge pull request #8 from riskfuel/feature/add-tests-and-better-exam…
Browse files Browse the repository at this point in the history
…ples

adding initial test & updating example spec
  • Loading branch information
Addyvan authored Aug 26, 2020
2 parents 4dc63db + 96b1077 commit 6d4f5b3
Show file tree
Hide file tree
Showing 10 changed files with 341 additions and 70 deletions.
46 changes: 46 additions & 0 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: run test suite
on:
push:
paths:
- 'tests/**'
- 'src/**'
- '.github/workflows/run-tests.yml'
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2

- name: Set up Docker Buildx
id: buildx
uses: crazy-max/ghaction-docker-buildx@v3
with:
buildx-version: latest

- name: Cache Docker layers
uses: actions/cache@v2
id: cache
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Build image
run: |
version=$(cat version)
DOCKER_IMAGE=riskfuel/k8s-mig-operator:$version
docker buildx build \
--cache-from "type=local,src=/tmp/.buildx-cache" \
--cache-to "type=local,dest=/tmp/.buildx-cache" \
--platform linux/amd64 \
--tag ${DOCKER_IMAGE} \
--output "type=docker" \
.
- name: Run tests
run: |
version=$(cat version)
DOCKER_IMAGE=riskfuel/k8s-mig-operator:$version
docker tag ${DOCKER_IMAGE} mig-operator-ci-shell
docker-compose run test
24 changes: 10 additions & 14 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
.PHONY: build_shell
build_shell:
docker build \
--tag ansible-operator-shell \
--file ./Dockerfile.dev \
.

.PHONY: shell
shell:
docker run -it \
-w /home/app_user/app \
-v ${PWD}:/home/app_user/app \
-v ${PWD}:/home/app_user/app \
-v /var/run/docker.sock:/var/run/docker.sock \
--name ansible-operator-shell \
--rm ansible-operator-shell
docker-compose run shell

.PHONY: build
build:
docker-compose build shell

.PHONY: test
test:
@echo "==> Running Main Tests\n"
docker-compose run test

.PHONY: deploy
deploy:
Expand Down
75 changes: 60 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,22 +57,67 @@ metadata:
spec:
nodes:
# hostname of node
- hostname: dl13
nodehostname:

remote_user: remote-user

# if not specified, features like toggling mig
# or switching strategies wont be available
secretName: migoperator-secret

# Options for MIG instance profiles: 7g.40gb, 4g.20gb, 3g.20gb, 2g.10gb, 1g.5gb
# Options for compute instance profiles: 7g.40gb, 4c.xg.ygb, 3c.xg.ygb, 2c.xg.ygb, 1c.xg.ygb
# NOTE: nvidia-device-plugin does not support non default compute sizes, however
# we still currently support creating these instances.
devices:
- id: 0
gpu_instances:
# Options: 7g.40gb, 4g.20gb, 3g.20gb, 2g.10gb, 1g.5gb
- gpu_instance_profile: 3g.20gb
compute_instances:
- 1c.3g.20gb
- 2c.3g.20gb
- gpu_instance_profile: 2g.10gb
compute_instances:
- 2c.2g.10gb
- gpu_instance_profile: 1g.5gb
compute_instances:
- 1c.1g.5gb
...
- gpu: 0
migEnabled: True
gpuInstances:
- profile: 7g.40gb
computeInstances:
- 7g.40gb
- gpu: 1
migEnabled: True
gpuInstances:
- profile: 7g.40gb
computeInstances:
- 7g.40gb
- gpu: 2
migEnabled: True
gpuInstances:
- profile: 7g.40gb
computeInstances:
- 7g.40gb
- gpu: 3
migEnabled: True
gpuInstances:
- profile: 7g.40gb
computeInstances:
- 7g.40gb
- gpu: 4
migEnabled: True
gpuInstances:
- profile: 7g.40gb
computeInstances:
- 7g.40gb
- gpu: 5
migEnabled: True
gpuInstances:
- profile: 7g.40gb
computeInstances:
- 7g.40gb
- gpu: 6
migEnabled: True
gpuInstances:
- profile: 7g.40gb
computeInstances:
- 7g.40gb
- gpu: 7
migEnabled: True
gpuInstances:
- profile: 7g.40gb
computeInstances:
- 7g.40gb
```
## Capabilities
Expand Down
58 changes: 17 additions & 41 deletions deployments/examples/migoperator.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ apiVersion: operators.riskfuel.com/v1alpha1
kind: MigOperator
metadata:
name: example-mig-operator
namespace: kube-system # set to namespace specified when installing
namespace: default # set to namespace specified when installing
spec:
nodes:
# hostname of node
Expand All @@ -20,73 +20,49 @@ spec:
devices:
- gpu: 0
migEnabled: True
# Options: 7g.40gb, 4g.20gb, 3g.20gb, 2g.10gb, 1g.5gb
# Test multiple CI single GI
gpuInstances:
- profile: 4g.20gb
- profile: 7g.40gb
computeInstances:
- 1c.4g.20gb
- 1c.4g.20gb
- 7g.40gb
- gpu: 1
migEnabled: True
# Options: 7g.40gb, 4g.20gb, 3g.20gb, 2g.10gb, 1g.5gb
# Test multiple CI single GI
gpuInstances:
- profile: 4g.20gb
- profile: 7g.40gb
computeInstances:
- 1c.4g.20gb
- 1c.4g.20gb
- 7g.40gb
- gpu: 2
migEnabled: True
# Options: 7g.40gb, 4g.20gb, 3g.20gb, 2g.10gb, 1g.5gb
# Test multiple CI single GI
gpuInstances:
- profile: 4g.20gb
- profile: 7g.40gb
computeInstances:
- 1c.4g.20gb
- 1c.4g.20gb
- 7g.40gb
- gpu: 3
migEnabled: True
# Options: 7g.40gb, 4g.20gb, 3g.20gb, 2g.10gb, 1g.5gb
# Test multiple CI single GI
gpuInstances:
- profile: 4g.20gb
- profile: 7g.40gb
computeInstances:
- 1c.4g.20gb
- 1c.4g.20gb
- 7g.40gb
- gpu: 4
migEnabled: True
# Options: 7g.40gb, 4g.20gb, 3g.20gb, 2g.10gb, 1g.5gb
# Test multiple CI single GI
gpuInstances:
- profile: 4g.20gb
- profile: 7g.40gb
computeInstances:
- 1c.4g.20gb
- 1c.4g.20gb
- 7g.40gb
- gpu: 5
migEnabled: True
# Options: 7g.40gb, 4g.20gb, 3g.20gb, 2g.10gb, 1g.5gb
# Test multiple CI single GI
gpuInstances:
- profile: 4g.20gb
- profile: 7g.40gb
computeInstances:
- 1c.4g.20gb
- 1c.4g.20gb
- 7g.40gb
- gpu: 6
migEnabled: True
# Options: 7g.40gb, 4g.20gb, 3g.20gb, 2g.10gb, 1g.5gb
# Test multiple CI single GI
gpuInstances:
- profile: 4g.20gb
- profile: 7g.40gb
computeInstances:
- 1c.4g.20gb
- 1c.4g.20gb
- 7g.40gb
- gpu: 7
migEnabled: True
# Options: 7g.40gb, 4g.20gb, 3g.20gb, 2g.10gb, 1g.5gb
# Test multiple CI single GI
gpuInstances:
- profile: 4g.20gb
- profile: 7g.40gb
computeInstances:
- 1c.4g.20gb
- 1c.4g.20gb
- 7g.40gb
19 changes: 19 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
version: '3.5'

services:

shell: &basic
container_name: mig-operator-ci-shell
image: mig-operator-ci-shell
build:
context: .
working_dir: /home/app_user/app
volumes:
- .:/home/app_user/app
entrypoint: bash
stdin_open: true
tty: true

test: &test
<<: *basic
entrypoint: ["pytest", "-vv", "tests/"]
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
ansible==2.9.12
pyyaml==5.3.1
python-dotenv==0.14.0
pytest==6.0.1
9 changes: 9 additions & 0 deletions tests/load_context.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

def load_context():
"""
Add the src dir to sys.path so we can
import code in the test folder as expected
"""
import sys, os
current_path = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, current_path + '/../src')
47 changes: 47 additions & 0 deletions tests/test_actions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import pytest
from load_context import load_context
load_context()

from actions import get_required_actions
from test_case_1 import \
desired_spec, \
current_state, \
expected_actions

testdata = [
(current_state, desired_spec, expected_actions),
]

def get_actions(current_state, desired_spec, expected_actions):
actions = []
for i in range(8):
gpu_instance_profiles = current_state[f"gpu-{i}"]["gpu_instance_profiles"]
compute_instance_profiles = current_state[f"gpu-{i}"]["compute_instance_profiles"]
gpu_instances = current_state[f"gpu-{i}"]["gpu_instances"]
comp_instances = current_state[f"gpu-{i}"]["comp_instances"]

actions += get_required_actions(
i,
desired_spec[f"gpu-{i}"],
gpu_instances,
comp_instances,
gpu_instance_profiles,
compute_instance_profiles,
True,
False
)

return actions

@pytest.mark.parametrize("current_state,desired_spec,expected_actions", testdata)
def test_action_selection(current_state, desired_spec, expected_actions):
"""
Ensure correct actions are being triggered
:param: current_state
:param: desired_spec
:param: expected_actions
"""

actions = get_actions(*testdata[0])
for i, desired_action in enumerate(expected_actions):
assert desired_action == actions[i]
48 changes: 48 additions & 0 deletions tests/test_case_1/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
"""
TEST CASE 1
-----------
Tests creating instances for the example spec defined
in the README.md from a state with no instances.
"""

import os, yaml

# DESIRED SPEC

dir_path = os.path.dirname(os.path.realpath(__file__))
with open(f"{dir_path}/migoperator.yml") as f:
manifest = yaml.load(f, Loader=yaml.SafeLoader)

desired_spec = {}
for device in manifest["spec"]["nodes"]["nodehostname"]["devices"]:
desired_spec[f"gpu-{device['gpu']}"] = {
"migEnabled": device["migEnabled"],
"gpuInstances": device["gpuInstances"]
}

# CURRENT STATE

gpu_instance_profiles = {'1g.5gb': '19', '2g.10gb': '14', '3g.20gb': '9', '4g.20gb': '5', '7g.40gb': '0'}
compute_instance_profiles = {'1c.7g.40gb': '0', '2c.7g.40gb': '1', '3c.7g.40gb': '2', '4c.7g.40gb': '3', '7g.40gb': '4'}

current_state = {}
for i, gpu in enumerate(desired_spec):
current_state[gpu] = {
"gpu_instance_profiles": gpu_instance_profiles,
"compute_instance_profiles": compute_instance_profiles,
"gpu_instances": [{'gpu': i, 'profile_id': '0', 'instance_id': '0', 'placement': '0:8'}],
"comp_instances": []
}

# EXPECTED ACTIONS

expected_actions = [
{
"type": "CREATE_COMP_INSTANCE",
"gpu": i,
"gpu_instance_id": "0",
"profile_id": "4"
}
for i in range(8)
]
Loading

0 comments on commit 6d4f5b3

Please sign in to comment.