vault backup: 2026-07-16 03:52:12

This commit is contained in:
Nikola
2026-07-16 03:52:12 +02:00
parent bcaf276380
commit d66b16cfe0
6 changed files with 216 additions and 55 deletions
+3
View File
@@ -0,0 +1,3 @@
{
"chat.disableAIFeatures": true
}
+1 -2
View File
@@ -42,8 +42,7 @@ white-space: pre-wrap !important; /* Forces text to wrap if it's still too long,
.markdown-rendered h3,
.markdown-rendered h4,
.markdown-rendered h5,
.markdown-rendered h6,
.markdown-rendered p {
.markdown-rendered h6 {
break-after: avoid !important;
page-break-after: avoid !important;
}
+1 -1
View File
@@ -14,7 +14,7 @@
"type": "markdown",
"state": {
"file": "Semester 2/EIST/EIST CHEATSHEET.md",
"mode": "source",
"mode": "preview",
"source": false
},
"icon": "lucide-file",
+7 -7
View File
@@ -4,18 +4,18 @@
"type": "split",
"children": [
{
"id": "844a1764731992eb",
"id": "a54102d9f9827d40",
"type": "tabs",
"children": [
{
"id": "3ba46ad009838dd8",
"id": "d315e70358bc75ab",
"type": "leaf",
"state": {
"type": "markdown",
"state": {
"file": "Semester 2/EIST/EIST CHEATSHEET.md",
"mode": "source",
"source": true
"source": false
},
"icon": "lucide-file",
"title": "EIST CHEATSHEET"
@@ -157,7 +157,7 @@
"type": "outline",
"state": {
"file": "Semester 2/EIST/EIST CHEATSHEET.md",
"followCursor": false,
"followCursor": true,
"showSearch": false,
"searchQuery": ""
},
@@ -206,10 +206,11 @@
"bases:Create new base": false
}
},
"active": "3ba46ad009838dd8",
"active": "1221778bf93051e6",
"lastOpenFiles": [
"Semester 2/EIST/Progress.md",
"Semester 2/EIST/EIST CHEATSHEET.md",
"Semester 2/EIST CHEATSHEET.pdf",
"Semester 2/EIST/Progress.md",
"Semester 2/EIST/EIST CHEATSHEET.pdf",
"2026-07-10.md",
"Semester 2/EIST/lu280859klubr.tmp",
@@ -223,7 +224,6 @@
"Excalidraw/Drawing 2026-07-09 18.02.06.excalidraw.md",
"Excalidraw",
"home/nikola/Documents/EIST/eist26l09p01-go38coz.md",
"home/nikola/Documents/EIST",
"file/home/nikola/Documents/EIST/eist26l09p01-go38coz 3.md",
"file/home/nikola/Documents/EIST/eist26l09p01-go38coz 2.md",
"file/home/nikola/Documents/EIST/eist26l09p01-go38coz 1.md",
Binary file not shown.
+204 -45
View File
@@ -1,9 +1,10 @@
# List of contents
1. [[#REST API with Spring]]
2. [[#Flask API in Python]]
3. [[#DOCKER]]
4. [[#gRPC]]
5.
3. [[#gRPC]]
4. [[#JUnit]]
5. [[#EasyMock]]
6. [[#DOCKER]]
<div class="page-break"></div>
@@ -450,48 +451,6 @@ for x, y in thisdict.items(): # Looping over key-value pairs as tuples
| setdefault() | Returns the value of the specified key. If the key does not exist: insert the key, with the specified value |
| update() | Updates the dictionary with the specified key-value pairs |
| values() | Returns a list of all the values in the dictionary |
<div class="page-break"></div>
# DOCKER
**Docker reference: https://docs.docker.com/**
### Dockerfiles
https://docs.docker.com/get-started/docker-concepts/building-images/writing-a-dockerfile/
https://docs.docker.com/reference/dockerfile/
```dockerfile
FROM python:3.13
WORKDIR /usr/local/app
# Install the application dependencies
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
# Copy in the source code
COPY src ./src
EXPOSE 8080
# Setup an app user so the container doesn't run as the root user
RUN useradd app
USER app
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8080"]
```
### Building docker
```bash
docker build -t <tag>
```
### Docker processes
```bash
docker ps
```
#### Exercises
- [L09P01 - Registry Office Service Deployment](file:///home/nikola/Documents/EIST/eist26l09p01-go38coz)
- [L09P02 - Garching Best Software](file:///home/nikola/Documents/EIST/eist26l09p02-go38coz)
- [L08PE04 - Spaceship](file:///home/nikola/Documents/EIST/eist26l0pe04-go38coz)
<div class="page-break"></div>
@@ -768,7 +727,162 @@ public String displayPlaylist(int[] playlist) throws SpotifyClientException {
- L02PB01 Weather Reporter
- L02P01 Spotify gRPC
- L03PE03 Gobblemaps
# JUnit
## assertThrows()
```java
@Test
public void testSetOnlineCourseUrlWithInvalidUrl() {
OnlineCourse course = new OnlineCourse("test");
// You need to pass the CLASS of the exception and a runnable which calls the function
// then the test will pass if EXACTLY this exception is throwed
// If you want to test for any exception pass Exception.class however, that is usually discouraged and not needed
assertThrows(MalformedURLException.class,() -> course.setUrl("hjdahjsd"));
}
```
## assertDoesNotThrow()
```java
@Test
public void testSetOnlineCourseUrlWithValidUrl(){
OnlineCourse course = new OnlineCourse("test");
// Simply assertDoesNotThrow with a runnable
assertDoesNotThrow(() -> course.setUrl("https://test"));
// We need to handle constructor of URL throwing an exception despite knowing that it won't as we are passing it a correct URL
try {
assertEquals(new URL("https://test"),course.getUrl());
} catch (MalformedURLException e) {
}
}
```
# EasyMock
`@TestSubject` annotations automatically calls the constructor with the mockObjects. However it is not applicable for constructors with other parameters that are not mocked(for example primitive types). In such cases you can call the constructor of the **test subject** as usual inside the test or in a @Before method or wherever you want.
**Second example contains how to expect *void* method calls**
## Example with TestSubject
```java
// Needs to extend the tests with EasyMock
@ExtendWith(EasyMockExtension.class)
class DiscussionTest {
// TestSubject annotations automatically calls the constructor with the mockObjects
// However it is not applicable for constructors with other parameters
@TestSubject
private Discussion discussion;
// Mock objects need to be annotated with @Mock
@Mock
private Course courseMock;
@Mock
private Comment commentMock;
// TODO implement the tests
@Test
public void testComment() {
// First we need to record
// Expect a function call and set a predetermined return value
// This expects the method to be called exactly once
expect(commentMock.save()).andReturn(true);
// After setting all expectations we need to replay the mock - e.g set it so it behaves the way we recorded
replay(commentMock);
// Test your objects as usual
discussion = new Discussion();
assertEquals(0,discussion.getNumberOfComments());
assertTrue(discussion.addComment(commentMock));
assertEquals(1,discussion.getNumberOfComments());
// At the end you need to verify the mock - this checks whether the expected methods were actually called
verify(commentMock);
}
// The methods below show the same usage
@Test
public void testCommentIfSavingFails() {
expect(commentMock.save()).andReturn(false);
replay(commentMock);
discussion = new Discussion();
assertEquals(0,discussion.getNumberOfComments());
assertFalse(discussion.addComment(commentMock));
assertEquals(0,discussion.getNumberOfComments());
verify(commentMock);
}
@Test
public void testStartCourseDiscussion() {
Person person = new Lecturer("","",LocalDate.now());
String testTopic = "testTopic";
expect(courseMock.isDiscussionAllowed(person)).andReturn(true);
replay(courseMock);
assertTrue(discussion.startCourseDiscussion(courseMock,person,testTopic));
assertEquals(courseMock,discussion.getCourse());
assertEquals(testTopic,discussion.getTopic());
verify(courseMock);
}
```
## Example with custom Constructor (also contains expecting *void* call)
```java
@Mock
Platform platformMock;
...
@Test
public void addNoteGetsURIFromPlatform() throws URISyntaxException {
URI uri = URI.create("https://notes.tum.de/examplePath"); // An example uri your mock can return
String expectedWriteDataPath = uri.getPath(); // The path that the NotesServer should write to
// Set the mock to expect the call and return the set URI
expect(platformMock.nextURI()).andReturn(uri);
// To expect a void method call you can just call the method like usual before **replaying** the mock
platformMock.writeData(expectedWriteDataPath,"Some text");
// Replay the mock
replay(platformMock);
// Instead of annotating with @TestSubject we instantiate the testServer(System Under Test) inside the Test
NotesServer testServer = new NotesServer(platformMock, false, false);
// Test like usual
URI testUri = testServer.addNote("alice", "Some text");
assertEquals(expectedWriteDataPath,testUri.getPath());
// At the end you need to verify the mock - this checks whether the expected methods were actually called
verify(platformMock);
}
```
## If you want multiple method invocations
| Method | Behaviour |
| ---------------- | -------------------------------------------------------------------------------------- |
| `.times(3)` | Expects the method to be called **exactly** 3 times. |
| `.times(2,5)` | Expects the method to be called between **2 and 5** times (inclusive). |
| `.atLeastOnce()` | Expects the method to be called **1 or more** times. |
| `.anyTimes()` | The method can be called **0 or more** times (it will never cause `verify()` to fail). |
For *void* methods:
```java
commentMock.update(); // Call the void method
expectLastCall().times(3); // Set the invocation count
```
<div class="page-break"></div>
## ALL RESOURCE LINKS:
@@ -794,3 +908,48 @@ public String displayPlaylist(int[] playlist) throws SpotifyClientException {
- **man pages (command line, not online)**
<div class="page-break"></div>
# DOCKER
**Docker reference: https://docs.docker.com/**
### Dockerfiles
https://docs.docker.com/get-started/docker-concepts/building-images/writing-a-dockerfile/
https://docs.docker.com/reference/dockerfile/
```dockerfile
FROM python:3.13
WORKDIR /usr/local/app
# Install the application dependencies
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
# Copy in the source code
COPY src ./src
EXPOSE 8080
# Setup an app user so the container doesn't run as the root user
RUN useradd app
USER app
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8080"]
```
### Building docker
```bash
docker build -t <tag>
```
### Docker processes
```bash
docker ps
```
#### Exercises
- [L09P01 - Registry Office Service Deployment](file:///home/nikola/Documents/EIST/eist26l09p01-go38coz)
- [L09P02 - Garching Best Software](file:///home/nikola/Documents/EIST/eist26l09p02-go38coz)
- [L08PE04 - Spaceship](file:///home/nikola/Documents/EIST/eist26l0pe04-go38coz)
<div class="page-break"></div>