diff --git a/website/container-ci-cd.html b/website/container-ci-cd.html new file mode 100644 index 0000000000000000000000000000000000000000..3af18de9e74a331a05ead1a85c1ffce8947881e9 --- /dev/null +++ b/website/container-ci-cd.html @@ -0,0 +1,381 @@ +<!DOCTYPE html> +<html> + <head> + <title>Container, CI/CD</title> + <meta charset="utf-8"> + <link href="css/hdm.css" rel="stylesheet"></link> + <style> + /* yanone-kaffeesatz-regular - latin */ + @font-face { + font-family: 'Yanone Kaffeesatz'; + font-style: normal; + font-weight: 400; + src: url('fonts/yanone-kaffeesatz-v22-latin-regular.eot'); /* IE9 Compat Modes */ + src: local(''), + url('fonts/yanone-kaffeesatz-v22-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ + url('fonts/yanone-kaffeesatz-v22-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */ + url('fonts/yanone-kaffeesatz-v22-latin-regular.woff') format('woff'), /* Modern Browsers */ + url('fonts/yanone-kaffeesatz-v22-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */ + url('fonts/yanone-kaffeesatz-v22-latin-regular.svg#YanoneKaffeesatz') format('svg'); /* Legacy iOS */ + } + /* noto-serif-regular - latin */ + @font-face { + font-family: 'Noto Serif'; + font-style: normal; + font-weight: 400; + src: url('fonts/noto-serif-v20-latin-regular.eot'); /* IE9 Compat Modes */ + src: local(''), + url('fonts/noto-serif-v20-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ + url('fonts/noto-serif-v20-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */ + url('fonts/noto-serif-v20-latin-regular.woff') format('woff'), /* Modern Browsers */ + url('fonts/noto-serif-v20-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */ + url('fonts/noto-serif-v20-latin-regular.svg#NotoSerif') format('svg'); /* Legacy iOS */ + } + /* ubuntu-mono-regular - latin */ + @font-face { + font-family: 'Ubuntu Mono'; + font-style: normal; + font-weight: 400; + src: url('fonts/ubuntu-mono-v14-latin-regular.eot'); /* IE9 Compat Modes */ + src: local(''), + url('fonts/ubuntu-mono-v14-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ + url('fonts/ubuntu-mono-v14-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */ + url('fonts/ubuntu-mono-v14-latin-regular.woff') format('woff'), /* Modern Browsers */ + url('fonts/ubuntu-mono-v14-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */ + url('fonts/ubuntu-mono-v14-latin-regular.svg#UbuntuMono') format('svg'); /* Legacy iOS */ + } + /* ubuntu-mono-italic - latin */ + @font-face { + font-family: 'Ubuntu Mono'; + font-style: italic; + font-weight: 400; + src: url('fonts/ubuntu-mono-v14-latin-italic.eot'); /* IE9 Compat Modes */ + src: local(''), + url('fonts/ubuntu-mono-v14-latin-italic.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ + url('fonts/ubuntu-mono-v14-latin-italic.woff2') format('woff2'), /* Super Modern Browsers */ + url('fonts/ubuntu-mono-v14-latin-italic.woff') format('woff'), /* Modern Browsers */ + url('fonts/ubuntu-mono-v14-latin-italic.ttf') format('truetype'), /* Safari, Android, iOS */ + url('fonts/ubuntu-mono-v14-latin-italic.svg#UbuntuMono') format('svg'); /* Legacy iOS */ + } + /* ubuntu-mono-700 - latin */ + @font-face { + font-family: 'Ubuntu Mono'; + font-style: normal; + font-weight: 700; + src: url('fonts/ubuntu-mono-v14-latin-700.eot'); /* IE9 Compat Modes */ + src: local(''), + url('fonts/ubuntu-mono-v14-latin-700.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ + url('fonts/ubuntu-mono-v14-latin-700.woff2') format('woff2'), /* Super Modern Browsers */ + url('fonts/ubuntu-mono-v14-latin-700.woff') format('woff'), /* Modern Browsers */ + url('fonts/ubuntu-mono-v14-latin-700.ttf') format('truetype'), /* Safari, Android, iOS */ + url('fonts/ubuntu-mono-v14-latin-700.svg#UbuntuMono') format('svg'); /* Legacy iOS */ + } + + body { font-family: 'Noto Serif'; } + h1, h2, h3 { + font-family: 'Yanone Kaffeesatz'; + font-weight: normal; + } + .remark-code, .remark-inline-code { font-family: 'Ubuntu Mono'; } + </style> + </head> + <body> + <textarea id="source"> + +class: center, middle, first + +# Software-Entwicklung 3 + +## Container, CI/CD + +--- + +# Agenda + +1. Recap +2. Container +3. CI/CD + +Container +* Was sind die Probleme? +* Was sind die Alternativen? Z.B. VM +* Warum keine VM? +* Lösung der Probleme mit Containern +* Wie unterscheiden sich Container von VMs? + * "Anwendungsvirtualisierung" + * Kernel des Hosts wird durchgereicht +* Container-Grundprinzipien + * Keine Daten im Container speichern + * Persistente Daten werden außerhalb des Containers abgelegt +* Container mit Docker + * Kurze Historie + * Probleme (root, Lizenz für Desktop-Client in Unternehmen) + * Alternativen (z.B. Podman) +* Demo: Aufruf von CLI-Tools per Docker-Container +* Wie wird ein Container definiert? `Dockerfile`, `docker-compose.yml` +* Demo: Start von `node`-Server inkl. Mounts des working-dir +* Wie kommen Daten in und aus den Container? + * Volume-Mounts + * Bind Mounts + * Port-Tunneling +* Ausblick: + * Microservices + * Containerregistry + +CI/CD +* Was ist CI? +* Was ist CD? +* Warum ist CI/CD sinnvoll? Was ist die Konsequenz wenn man darauf verzichtet? + +--- + +# Recap: Was haben wir letzte Woche besprochen? + +* Build Management mit Maven +* Testing mit JUnit + +> Blick ins [Repository](https://gitlab.mi.hdm-stuttgart.de/jordine/se3sose2022projekt) + +--- +class: center, middle +# Was muss getan werden um eine (Server-)Anwendung zu starten? Was sind die Probleme? + +??? + +* Umgebung einrichten +* Unterschiedliche Versionen (Libraries, OS) +* Kompatibilitätsprobleme + +--- +# Build Management Tools + +* Unterstützung bei Projekterstellung +* Standardisierung: Reproduzierbare Builds +* Automatisierung +* Verwaltung von Abhängigkeiten +* Durchführen von Tests +* Bündeln der Software +* Bereitstellung + +> Unterstützung des Entwicklungszyklus +--- +# Beispiele +* Java: Maven, Gradle +* NodeJS: `npm`, `yarn` (Packagemanager) +* Unix: `make` +* Python: `pip` (Packagemanger), PyBuilder +* ... + +--- +# Build Management Tool: Maven + +* Grundprinzipien: Phasenmodell/Build Lifecycle & Konvention über Konfiguration & DRY +* Template-basierte (Java-)Projekterstellung mit **Archetypes** +* Dependeny Management +* Erweiterbar durch Plugins +* Unterstützung durch IDEs + +## Standardverzeichnisstruktur +```bash +. project-root +├── pom.xml # Projektkonfiguration +├── src # Source Code +│ ├── main +│ │ ├── java # Java Code und Packages +│ │ └── resources # Dateien, die zur Laufzeit benötigt werden +│ └── test # Test Code +│ └── java +└── target +``` +--- +# Maven: Build Lifecycle + +Werden bis zur angegebenen Phase durchgeführt. + +1. `validate`: Überprüfen, ob alle Informationen vorhanden sind. +2. `compile`: Kompilieren der in `src` vorhandenen Dateien +3. `test`: Durchführen der in `test` vorhandenen Tests +4. `package`: Erstellen von z.B. `jar`-Dateien +5. `verify`: Nutzbar z.B. für statische Codeanalyse +6. `install`: Kopieren der `jar` nach `~/.m2/repository` +7. `deploy`: Veröffentlichen der `jar` in ein öffentliches Repo + +Beispielaufruf: `mvn package` + +Weitere Informationen: [Maven Build Lifecycle](https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html) + +--- +# `pom.xml` Beispiel - General + +```xml +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>de.hdm.jordine</groupId> + <artifactId>musicmanager</artifactId> + <version>0.1.0-SNAPSHOT</version> + + <properties> + <maven.compiler.source>17</maven.compiler.source> + <maven.compiler.target>17</maven.compiler.target> + </properties> +``` +--- +# `pom.xml` Beispiel - Dependencies + +```xml + <dependencies> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter-engine</artifactId> + <version>5.8.2</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <version>4.4.0</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-api</artifactId> + <version>2.17.2</version> + </dependency> + + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-core</artifactId> + <version>2.17.2</version> + </dependency> + </dependencies> +``` +--- +# `pom.xml` Beispiel - Plugins + +```xml + <build> + <plugins> + <plugin> + <!-- https://stackoverflow.com/a/27168770 --> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + <version>3.2.2</version> + <configuration> + <archive> + <manifest> + <addClasspath>true</addClasspath> + <mainClass>de.hdm.jordine.musicmanager.app.MusicManagerApp</mainClass> + </manifest> + </archive> + </configuration> + </plugin> + </plugins> + </build> + +</project> +``` +--- +class: center, middle +# Warum ist Testing wichtig? + +--- +class: center, middle +# Welche Testarten kennen Sie? + +--- +# Testarten + +* Usabilitytests +* **Softwaretests** +* Hardwaretests +* Securitytests +* ... + +--- +# Testebenen + +* **Unittests**: Test einzelner Funktionen und Methoden +* **Integrationtests**: Test des Zusammenspiels mehrerer Module +* **Funktionstests**: Überprüfen der Geschäftslogik + +* **End-to-End-Tests**: Testen echter Benutzungsszenarien (bspw. von UI bis DB) +* **Leistungstests**: Überprüfung der Performance +* **Reggressionstests**: Sicherstellung nach Änderungen, dass Bestandsfunktionen weiterhin funktionieren +* **Smoketests**: Grundlegende Funktionsüberprüfung, z.B. nach Release + +_nach: https://www.atlassian.com/de/continuous-delivery/software-testing/types-of-software-testing_ + +--- +# Testprinzip F.I.R.S.T + +* **F**ast: Tests sollen schnell durchlaufen, damit diese häufig durchgeführt werden. +* **I**solated: Jeder Test sollte unabhängig sein und sein eigenes Enviroment mitbringen. +* **R**epeatable: Auch nach mehrfachen Durchläufen soll das Ergebnis identisch sein. +* **S**elf-validating: Automatische Überprüfung, ob Test erfolgreich war. +* **T**imely: Test sollte beim Entwickeln der Funktionalität geschrieben werden. + +> Blick auf Demo-Projekt + +--- +# Unittests mit JUnit + +* Nutzen der `assert`-Methoden, zum Überprüfen von erwarteten und tatsächlichen Werten +* Nutzen der Test-Annotations, z.B. + * `@Test` + * [`@RepeatedTest`](https://junit.org/junit5/docs/current/user-guide/#writing-tests-repeated-tests) + * [`@ParameterizedTest`](https://junit.org/junit5/docs/current/user-guide/#writing-tests-parameterized-tests) + * `@BeforeEach`/`@AfterEach` + * `@BeforeAll`/`@AfterAll` + * [`@DisplayName`](https://junit.org/junit5/docs/current/user-guide/#writing-tests-display-names) +* Integration in CI/CD-Prozesse + +Dokumentation: https://junit.org/junit5/docs/current/user-guide/ + +--- +# Was sollte getestet werden? + +* "Happy path" - der einfachste Fall +* Randbedingungen +* Fehlerfälle + +--- +# Testing: Begrifflichkeiten + +## Mock +* Objekt, dass ein bestimmtes Verhalten simuliert +* Erlaubt schnelleres Testen -> **F**.I.R.S.T +* Framework-Beispiel: [Mockito](https://site.mockito.org) + +## Code coverage +* Gibt an, wieviel Prozent des Codes durch Tests abgedeckt sind +* Je höher der Wert, umso besser + +--- +# Testdriven Development (TDD) + +* Entwicklungsmethode +* Tests werden vor dem eigentlichen Code entwickelt +* Mögliches Vorgehen (_nach: [it-agile.de](https://www.it-agile.de/agiles-wissen/agile-entwicklung/was-ist-testgetriebene-entwicklung/)): + * **Test "rot"**: Test erstellen, der auf einfachste Art und Weise die gewünschte Funktionalität erfüllt. Da kein Code besteht, der die Funktion abdeckt, schlagen die Tests fehl. + * Einfachste Umsetzung der Funktionalität bis der **Test "grün"** wird. + * **Refactoring** des Codes. Tests werden weiterhin regelmäßig durchgeführt und müssen grün bleiben. + +--- +# Projektdemo + + + + </textarea> + <script src="js/remark.min.js"> + </script> + <script> + var slideshow = remark.create(); + </script> + </body> +</html> \ No newline at end of file