From e0defb4226e035b41a1295a73a0da843056a6406 Mon Sep 17 00:00:00 2001
From: Liora Milbaum <lmilbaum@redhat.com>
Date: Sun, 31 Mar 2024 14:32:28 +0300
Subject: [PATCH] Spin Model Server in chatbot recipe

Signed-off-by: Liora Milbaum <lmilbaum@redhat.com>
---
 .github/workflows/chatbot.yaml                | 15 ++++---
 .github/workflows/model_servers.yaml          |  6 ---
 .../chatbot/Makefile                          |  9 +++-
 .../chatbot/tests/conftest.py                 | 42 +++++++++++++++++++
 .../tests/{test_alive.py => test_app.py}      |  5 +++
 requirements-test.txt                         |  2 +
 6 files changed, 66 insertions(+), 13 deletions(-)
 rename recipes/natural_language_processing/chatbot/tests/{test_alive.py => test_app.py} (71%)

diff --git a/.github/workflows/chatbot.yaml b/.github/workflows/chatbot.yaml
index 23ed2a473..ea30d0870 100644
--- a/.github/workflows/chatbot.yaml
+++ b/.github/workflows/chatbot.yaml
@@ -4,15 +4,9 @@ on:
   pull_request:
     branches:
       - main
-    paths:
-      - ./recipes/natural_language_processing/chatbot/**
-      - .github/workflows/chatbot.yaml
   push:
     branches:
       - main
-    paths:
-      - ./recipes/natural_language_processing/chatbot/**
-      - .github/workflows/chatbot.yaml
 
 env:
   REGISTRY: ghcr.io
@@ -49,6 +43,8 @@ jobs:
 
       - name: Set up Python
         uses: actions/setup-python@v5.0.0
+        with:
+          python-version: '3.11'
 
       - name: Install python dependencies
         working-directory: ./recipes/natural_language_processing/chatbot
@@ -57,3 +53,10 @@ jobs:
       - name: Run tests
         working-directory: ./recipes/natural_language_processing/chatbot
         run: make test
+
+      - name: Upload logs
+        uses: actions/upload-artifact@v4.3.1
+        if: always()
+        with:
+          name: test-logs
+          path: /tmp/driver.log
diff --git a/.github/workflows/model_servers.yaml b/.github/workflows/model_servers.yaml
index 76381c16f..f27e7d26e 100644
--- a/.github/workflows/model_servers.yaml
+++ b/.github/workflows/model_servers.yaml
@@ -4,15 +4,9 @@ on:
   pull_request:
     branches:
       - main
-    paths:
-      - ./model_servers/llamacpp_python/**
-      - .github/workflows/model_servers.yaml
   push:
     branches:
       - main
-    paths:
-      - ./model_servers/llamacpp_python/**
-      - .github/workflows/model_servers.yaml
 
 env:
   REGISTRY: ghcr.io
diff --git a/recipes/natural_language_processing/chatbot/Makefile b/recipes/natural_language_processing/chatbot/Makefile
index 043c09ab6..8dec81d36 100644
--- a/recipes/natural_language_processing/chatbot/Makefile
+++ b/recipes/natural_language_processing/chatbot/Makefile
@@ -29,6 +29,13 @@ quadlet:
 
 .PHONY: install
 install:
+	wget -qO- https://github.com/mozilla/geckodriver/releases/download/v0.34.0/geckodriver-v0.34.0-linux64.tar.gz | tar xvz
+	sudo apt update
+	sudo apt upgrade
+	wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
+	sudo dpkg -i google-chrome-stable_current_amd64.deb
+	wget https://chromedriver.storage.googleapis.com/114.0.5735.90/chromedriver_linux64.zip
+	unzip chromedriver_linux64.zip
 	pip install -r tests/requirements-test.txt
 
 .PHONY: run
@@ -37,4 +44,4 @@ run:
 
 .PHONY: test
 test:
-	pytest --log-cli-level NOTSET
+	python3 -m pytest -vvv --driver=Chrome --driver-path=./chromedriver tests
diff --git a/recipes/natural_language_processing/chatbot/tests/conftest.py b/recipes/natural_language_processing/chatbot/tests/conftest.py
index 6242ebbe4..6002d715c 100644
--- a/recipes/natural_language_processing/chatbot/tests/conftest.py
+++ b/recipes/natural_language_processing/chatbot/tests/conftest.py
@@ -1,7 +1,32 @@
 import pytest_container
 import os
+import pytest
+from selenium import webdriver
 
 
+MS = pytest_container.Container(
+        url=f"containers-storage:{os.environ['REGISTRY']}/model_servers",
+        volume_mounts=[
+            pytest_container.container.BindMount(
+                container_path="/locallm/models",
+                host_path="./",
+                flags=["ro"]
+            )
+        ],
+        extra_environment_variables={
+            "MODEL_PATH": "models/mistral-7b-instruct-v0.1.Q4_K_M.gguf",
+            "HOST": "0.0.0.0",
+            "PORT": "8001"
+        },
+        forwarded_ports=[
+            pytest_container.PortForwarding(
+                container_port=8001,
+                host_port=8001
+            )
+        ],
+        extra_launch_args=["--net=host"]
+    )
+
 CB = pytest_container.Container(
         url=f"containers-storage:{os.environ['REGISTRY']}/{os.environ['IMAGE_NAME']}",
         extra_environment_variables={
@@ -21,3 +46,20 @@ def pytest_generate_tests(metafunc):
 
 def pytest_addoption(parser):
     pytest_container.add_logging_level_options(parser)
+
+@pytest.fixture
+def firefox_options(firefox_options):
+    firefox_options.headless = True
+    firefox_options.set_preference("webdriver.log.file", "/tmp/driver.log")
+    return firefox_options
+
+@pytest.fixture
+def custom_selenium(selenium, firefox_options):
+    selenium.webdriver = webdriver.Firefox(firefox_options=firefox_options)
+    yield selenium
+    selenium.webdriver.quit()
+
+@pytest.fixture
+def chrome_options(chrome_options):
+    chrome_options.add_argument("--headless")
+    return chrome_options
diff --git a/recipes/natural_language_processing/chatbot/tests/test_alive.py b/recipes/natural_language_processing/chatbot/tests/test_app.py
similarity index 71%
rename from recipes/natural_language_processing/chatbot/tests/test_alive.py
rename to recipes/natural_language_processing/chatbot/tests/test_app.py
index a9a7e52bc..4103f50a7 100644
--- a/recipes/natural_language_processing/chatbot/tests/test_alive.py
+++ b/recipes/natural_language_processing/chatbot/tests/test_app.py
@@ -10,3 +10,8 @@ def test_etc_os_release_present(auto_container: pytest_container.container.Conta
 @tenacity.retry(stop=tenacity.stop_after_attempt(5), wait=tenacity.wait_exponential())
 def test_alive(auto_container: pytest_container.container.ContainerData, host):
     host.run_expect([0],f"curl http://localhost:{auto_container.forwarded_ports[0].host_port}",).stdout.strip()
+
+def test_title(auto_container: pytest_container.container.ContainerData, selenium):
+    selenium.get(f"http://localhost:{auto_container.forwarded_ports[0].host_port}")
+    assert selenium.title == "chatbot"
+
diff --git a/requirements-test.txt b/requirements-test.txt
index 751d336dc..22fc97f27 100644
--- a/requirements-test.txt
+++ b/requirements-test.txt
@@ -1,6 +1,8 @@
 pip==24.0
 pytest-container==0.4.0
+pytest-selenium==4.1.0
 pytest-testinfra==10.1.0
 pytest==8.1.1
 requests==2.31.0
+selenium==4.19.0
 tenacity==8.2.3