Skip to content

Commit

Permalink
Merge branch 'develop' into feature/course-details-show-llm-usage
Browse files Browse the repository at this point in the history
  • Loading branch information
krusche authored Dec 22, 2024
2 parents 8bd072a + 35d113e commit 402b567
Show file tree
Hide file tree
Showing 235 changed files with 5,993 additions and 1,429 deletions.
13 changes: 7 additions & 6 deletions .github/workflows/testserver.yml
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,13 @@ jobs:
folder: /opt/artemis
host_keys: |
#- environment: artemis-test7.artemis.cit.tum.de
# label-identifier: artemis-test7
# url: https://artemis-test7.artemis.cit.tum.de
# user: deployment
# hosts: artemis-test7.artemis.cit.tum.de
# folder: /opt/artemis
- environment: artemis-test7.artemis.cit.tum.de
label-identifier: artemis-test7
url: https://artemis-test7.artemis.cit.tum.de
user: deployment
hosts: artemis-test7.artemis.cit.tum.de
folder: /opt/artemis
host_keys: |
#- environment: artemis-test8.artemis.cit.tum.de
# label-identifier: artemis-test8
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ data-exports/
######################
/src/test/playwright/test-reports/
/src/test/playwright/test-results/*
/src/test/playwright/ssh-keys/known_hosts

#################################
# Files generated by prebuild.mjs
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2024 TUM Applied Software Engineering
Copyright (c) 2024 TUM Applied Education Technologies

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
19 changes: 13 additions & 6 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ plugins {
id "idea"
id "jacoco"
id "org.springframework.boot" version "${spring_boot_version}"
id "io.spring.dependency-management" version "1.1.6"
id "io.spring.dependency-management" version "1.1.7"
id "com.google.cloud.tools.jib" version "3.4.4"
id "com.github.node-gradle.node" version "${gradle_node_plugin_version}"
id "com.diffplug.spotless" version "6.25.0"
Expand Down Expand Up @@ -257,7 +257,7 @@ dependencies {
implementation "org.apache.lucene:lucene-queryparser:${lucene_version}"
implementation "org.apache.lucene:lucene-core:${lucene_version}"
implementation "org.apache.lucene:lucene-analyzers-common:${lucene_version}"
implementation "com.google.protobuf:protobuf-java:4.29.1"
implementation "com.google.protobuf:protobuf-java:4.29.2"

// we have to override those values to use the latest version
implementation "org.slf4j:jcl-over-slf4j:${slf4j_version}"
Expand Down Expand Up @@ -384,6 +384,13 @@ dependencies {
exclude module: "spring-boot-starter-undertow"
}
implementation "org.springframework.boot:spring-boot-starter-tomcat:${spring_boot_version}"

// Avoid security issues in Tomcat 10.1.33
implementation "org.apache.tomcat.embed:tomcat-embed-core:${tomcat_version}"
implementation "org.apache.tomcat.embed:tomcat-embed-el:${tomcat_version}"
implementation "org.apache.tomcat.embed:tomcat-embed-websocket:${tomcat_version}"
implementation "org.apache.tomcat:tomcat-annotations-api:${tomcat_version}"

implementation "org.springframework.boot:spring-boot-starter-websocket:${spring_boot_version}"
implementation "org.springframework.boot:spring-boot-starter-thymeleaf:${spring_boot_version}"
implementation "org.springframework.boot:spring-boot-starter-oauth2-resource-server:${spring_boot_version}"
Expand All @@ -400,7 +407,7 @@ dependencies {
implementation "org.springframework.cloud:spring-cloud-starter-config:${spring_cloud_version}"
implementation "org.springframework.cloud:spring-cloud-commons:${spring_cloud_version}"

implementation "io.netty:netty-all:4.1.115.Final"
implementation "io.netty:netty-all:4.1.116.Final"
implementation "io.projectreactor.netty:reactor-netty:1.2.1"
implementation "org.springframework:spring-messaging:${spring_framework_version}"
implementation "org.springframework.retry:spring-retry:2.0.11"
Expand Down Expand Up @@ -451,7 +458,7 @@ dependencies {
implementation "org.apfloat:apfloat:1.14.0"

// use newest version of guava to avoid security issues through outdated dependencies
implementation "com.google.guava:guava:33.3.1-jre"
implementation "com.google.guava:guava:33.4.0-jre"
implementation "com.sun.activation:jakarta.activation:2.0.1"

// use newest version of gson to avoid security issues through outdated dependencies
Expand Down Expand Up @@ -518,7 +525,7 @@ dependencies {
}
testImplementation "org.springframework.security:spring-security-test:${spring_security_version}"
testImplementation "org.springframework.boot:spring-boot-test:${spring_boot_version}"
testImplementation "org.assertj:assertj-core:3.26.3"
testImplementation "org.assertj:assertj-core:3.27.0"
testImplementation "org.mockito:mockito-core:${mockito_version}"
testImplementation "org.mockito:mockito-junit-jupiter:${mockito_version}"

Expand Down Expand Up @@ -607,7 +614,7 @@ tasks.withType(Test).configureEach {
}

wrapper {
gradleVersion = "8.12-rc-1"
gradleVersion = "8.12"
}

tasks.register("stage") {
Expand Down
4 changes: 3 additions & 1 deletion docker/artemis/config/playwright-local.env
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# ----------------------------------------------------------------------------------------------------------------------
# Artemis configuration overrides for the Playwright E2E Postgres setups
# Artemis configuration overrides for the Playwright E2E Local CI/VC setups
# ----------------------------------------------------------------------------------------------------------------------

SPRING_PROFILES_ACTIVE="artemis,scheduling,localvc,localci,buildagent,core,prod,docker"
Expand All @@ -12,3 +12,5 @@ ARTEMIS_CONTINUOUSINTEGRATION_ARTEMISAUTHENTICATIONTOKENVALUE='demo'
ARTEMIS_CONTINUOUSINTEGRATION_DOCKERCONNECTIONURI='unix:///var/run/docker.sock'
ARTEMIS_GIT_NAME='artemis'
ARTEMIS_GIT_EMAIL='[email protected]'
ARTEMIS_VERSIONCONTROL_SSHHOSTKEYPATH='/app/artemis/src/test/playwright/ssh-keys'
ARTEMIS_VERSIONCONTROL_SSHPORT='7921'
2 changes: 2 additions & 0 deletions docker/playwright-E2E-tests-mysql-localci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ services:
condition: service_healthy
environment:
PLAYWRIGHT_DB_TYPE: 'MySQL'
network_mode: service:artemis-app
networks: !reset []

networks:
artemis:
Expand Down
5 changes: 3 additions & 2 deletions docs/.readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
version: 2

build:
os: ubuntu-22.04
os: ubuntu-24.04
tools:
python: "3.12"
python: "3.13"
sphinx:
fail_on_warning: true
configuration: docs/conf.py
python:
install:
- requirements: docs/requirements.txt
2 changes: 1 addition & 1 deletion docs/admin/setup/distributed.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Setup with multiple instances
There are certain scenarios, where a setup with multiple instances of the application server is required.
This can e.g. be due to special requirements regarding fault tolerance or performance.

Artemis also supports this setup (which is also used at the Chair for Applied Software Engineering at TUM).
Artemis also supports this setup (which is also used at TUM).

Multiple instances of the application server are used to distribute the load:

Expand Down
4 changes: 2 additions & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
# -- Project information -----------------------------------------------------

project = 'Artemis'
copyright = '2024, Technical University of Munich, Applied Software Engineering'
author = 'Technical University of Munich, Applied Software Engineering'
copyright = '2024, Applied Education Technologies, Technical University of Munich'
author = 'Applied Education Technologies, Technical University of Munich'


# -- General configuration ---------------------------------------------------
Expand Down
Binary file removed docs/dev/cypress/cypress-open-screenshot.png
Binary file not shown.
4 changes: 0 additions & 4 deletions docs/dev/cypress/cypress_bamboo_deployment_diagram.svg

This file was deleted.

This file was deleted.

Binary file removed docs/dev/cypress/sorry-cypress-dashboard.png
Binary file not shown.
Binary file removed docs/dev/cypress/sorry-cypress-run.png
Binary file not shown.
Binary file removed docs/dev/cypress/sorry-cypress-runs.png
Binary file not shown.
Binary file removed docs/dev/cypress/sorry-cypress-test.png
Binary file not shown.
184 changes: 182 additions & 2 deletions docs/dev/playwright.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,23 @@
E2E Testing with Playwright
===========================

**Background**

The Playwright test suite contains system tests verifying the most important features of Artemis.
System tests test the whole system and therefore require a complete deployment of Artemis first.
In order to prevent as many faults (bugs) as possible from being introduced into the develop branch,
we want to execute the Playwright test suite whenever new commits are pushed to a Git branch
(just like the unit and integration test suites).

To accomplish this we need to be able to dynamically deploy multiple different instances of Artemis at the same time.
An ideal setup would be to deploy the whole Artemis system using Kubernetes.
However, this setup is too complex at the moment.
The main reason for the complexity is that it is very hard to automatically setup Docker containers for
the external services (e.g. Gitlab, Jenkins) and connect them directly with Artemis.

Therefore, the current setup only dynamically deploys the Artemis server and configures it to connect to
the prelive system, which is already properly setup in the university data center.

Set up Playwright locally
-------------------------

Expand Down Expand Up @@ -137,8 +154,72 @@ To run tests sequentially (one after another), set the ``workers`` option to ``1
sequentially, while running test files in parallel, set the ``fullyParallel`` option to ``false``.


Best practices for writing tests in Playwright
----------------------------------------------
Best practices when writing new E2E tests
-----------------------------------------

**Understanding the System and Requirements**

Before writing tests, a deep understanding of the system and its requirements is crucial.
This understanding guides determining what needs testing and what defines a successful test.
The best way to understand is to consolidate the original system`s developer or a person actively working on this
component.

**Identify Main Test Scenarios**

Identify what are the main ways the component is supposed to be used. Try
the action with all involved user roles and test as many different inputs as
feasible.

**Identify Edge Test Scenarios**

Next to the main test scenarios, there are also edge case scenarios. These
tests include inputs/actions that are not supposed to be performed (e.g. enter
a too-long input into a field) and test the error-handling capabilities of the
platform.

**Write Tests as Development Progresses**

Rather than leaving testing until the end, write tests alongside each piece of
functionality. This approach ensures the code remains testable and makes
identifying and fixing issues as they arise easier.

**Keep Tests Focused**

Keep each test focused on one specific aspect of the code. If a test fails, it is
easier to identify the issue when it does not check multiple functionalities at
the same time.

**Make Tests Independent**

Tests should operate independently from each other and external factors like
the current date or time. Each test should be isolated. Use API calls for unrelated tasks, such as creating a
course, and UI interaction for the appropriate testing steps. This also involves
setting up a clean environment for every test suite.

**Use Descriptive Test Names**

Ensure each test name clearly describes what the test does. This strategy
makes the test suite easier to understand and quickly identifies which test
has failed.

**Use Similar Test Setups**

Avoid using different setups for each test suit. For example, always check
for the same HTTP response when deleting a course.

**Do Not Ignore Failing Tests**

If a test consistently fails, pay attention to it. Investigate as soon as possible
and fx the issue, or update the test if the requirements have changed.

**Regularly Review and Refactor Your Tests**

Tests, like code, can accumulate technical debt. Regular reviews for duplication,
unnecessary complexity, and other issues help maintain tests and enhance reliability.


Playwright testing best practices
---------------------------------

1. **Use page objects for common interactions**:

Expand Down Expand Up @@ -230,3 +311,102 @@ Best practices for writing tests in Playwright
Waiting for the page load state is not recommended if we are only interested in specific elements appearing on
the page - use ``waitFor()`` function of a locator instead.
Artemis Deployment on Bamboo Build Agent
----------------------------------------
Every execution of the Playwright test suite requires its own deployment of Artemis.
The easiest way to accomplish this is to deploy Artemis locally on the build agent, which executes the Playwright tests.
Using ``docker compose`` we can start a MySQL database and the Artemis server locally on the build agent and
connect it to the prelive system in the university data center.

.. figure:: playwright/playwright_bamboo_deployment_diagram.svg
:align: center
:alt: Artemis Deployment on Bamboo Build Agent for Playwright

Artemis Deployment on Bamboo Build Agent for Playwright

In total there are three Docker containers started in the Bamboo build agent:

1. MySQL

This container starts a MySQL database and exposes it on port 3306.
The container automatically creates a new database 'Artemis' and configures it
with the recommended settings for Artemis.
The Playwright setup reuses the already existing
`MySQL docker image <https://github.com/ls1intum/Artemis/blob/develop/docker/mysql.yml>`__
from the standard Artemis Docker setup.

2. Artemis Application

The Docker image for the Artemis container is created from the already existing
`Dockerfile <https://github.com/ls1intum/Artemis/blob/develop/docker/artemis/Dockerfile>`__.
When the Bamboo build of the Playwright test suite starts, it retrieves the Artemis executable (.war file)
from the `Artemis build plan <https://bamboo.ase.in.tum.de/browse/ARTEMIS-WEBAPP>`_.
Upon creation of the Artemis Docker image the executable is copied into the image together with configuration files
for the Artemis server.

The main configuration of the Artemis server are contained in the
`Playwright environment configuration files <https://github.com/ls1intum/Artemis/tree/develop/docker/artemis/config>`__.
However, those files do not contain any security relevant information.
Security relevant settings are instead passed to the Docker container via environment variables. This information is
accessible to the Bamboo build agent via
`Bamboo plan variables <https://confluence.atlassian.com/bamboo/bamboo-variables-289277087.html>`__.

The Artemis container is also configured to
`depend on <https://docs.docker.com/compose/compose-file/compose-file-v2/#depends_on>`__
the MySQL container and uses
`health checks <https://docs.docker.com/compose/compose-file/compose-file-v2/#healthcheck>`__
to wait until the MySQL container is up and running.

3. Playwright

Playwright offers a test environment `docker image <https://hub.docker.com/r/microsoft/playwright>`__
to execute Playwright tests.
The image contains Playwright browsers and browser system dependencies.
However, Playwright itself is not included in the image.
This is convenient for us because the image is smaller and the Artemis Playwright project requires
additional dependencies to fully function.
Therefore, the Artemis Playwright Docker container is configured to install all dependencies
(using :code:`npm ci`) upon start. This will also install Playwright itself.
Afterwards the Artemis Playwright test suite is executed.

The necessary configuration for the Playwright test suite is also passed in via environment variables.
Furthermore, the Playwright container depends on the Artemis container and is only started
once Artemis has been fully booted.

**Bamboo webhook**

The Artemis instance deployed on the build agent is not publicly available to improve the security of this setup.
However, in order to get the build results for programming exercise submissions Artemis relies on a webhook from Bamboo
to send POST requests to Artemis.
To allow this, an extra rule has been added to the firewall allowing only the Bamboo instance in the prelive system
to connect to the Artemis instance in the build agent.

**Timing**

As mentioned above, we want the Playwright test suite to be executed whenever new commits are pushed to a Git branch.
This has been achieved by adding the
`Playwright build plan <https://bamboo.ase.in.tum.de/browse/ARTEMIS-AEPTMA1132>`__
as a `child dependency <https://confluence.atlassian.com/bamboo/setting-up-plan-build-dependencies-289276887.html>`__
to the `Artemis Build build plan <https://bamboo.ase.in.tum.de/browse/ARTEMIS-WEBAPP>`__.
The *Artemis Build* build plan is triggered whenever a new commit has been pushed to a branch.

The Playwright build plan is only triggered after a successful build of the Artemis executable.
This does imply a delay (about 10 minutes on average) between the push of new commits and the execution
of the Playwright test suite, since the new Artemis executable first has to be built.

**NOTE:** The Playwright test suite is only automatically executed for internal branches and pull requests
(requires access to this GitHub repository), **not** for external ones.
In case you need access rights, please contact the maintainer `Stephan Krusche <https://github.com/krusche>`__.

Maintenance
-----------
The Artemis Dockerfile as well as the MySQL image are already maintained because they are used in
other Artemis Docker setups.
Therefore, only Playwright and the Playwright Docker image require active maintenance.
Since the Playwright test suite simulates a real user, it makes sense to execute the test suite with
the latest browser versions.
The Playwright Docker image we use always has browsers with specific versions installed.
Therefore, the
`docker-compose file <https://github.com/ls1intum/Artemis/blob/develop/docker/playwright.yml>`__
should be updated every month to make sure that the latest Playwright image is used.
4 changes: 4 additions & 0 deletions docs/dev/playwright/playwright_bamboo_deployment_diagram.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 402b567

Please sign in to comment.