Heute ist Serverless eine Sache. Obwohl jeder einen Blogbeitrag darüber schreiben kann, wie Serverless auf Servern läuft, teile ich die gleichen Visionen wie Mathias Verraes: twitter.com/mathiasverraes/status/995317295072382976 Angesichts dessen habe ich beschlossen, meine Erfahrungen als Entwickler beim Erstellen, Testen und Bereitstellen von AWS Lambda-Funktionen in der .NET-Welt zu teilen. Dabei handelt es sich nicht um ein "Hello World"-Beispiel, sondern um ein reales Szenario, bei dem einige Dienste miteinander integriert werden. Da eine Serverless-Funktion ein winziges Stück Code in einem viel größeren Prozess ist, wie kann ich den Ablauf auf meinem Entwicklungsrechner testen?
Herausforderung
In diesem Beispiel haben wir einen AWS Lambda, der eine Benachrichtigung von der Webanwendung empfängt und eine SMS über einenDrittanbieter sendet. Die Anfragen und Antworten an die AWS Lambda-Funktion werden über AWS API Gateway mit allen Vorzügen von HTTP weitergeleitet.
[caption id="attachment_1865" align="aligncenter" width="1280"]
Darstellung der Interaktion zwischen den Komponenten[/caption]
Der SMS-Anbieter verfügt jedoch nicht über eine Sandbox, die wir für unsere Akzeptanztests verwenden können, und wir möchten nicht unser gesamtes Guthaben ausgeben. Da wir sicher sein wollen, dass unser Geschäftscode alle Anwendungsfälle abdeckt, müssen wir das Verhalten des SMS-Anbieters selbst entwickeln. Wenigstens ist die Dokumentation auf einem guten Stand. :)
[caption id="attachment_1864" align="aligncenter" width="546"]
Credits an www.quickmeme.com[/caption]
Anwendungsfälle
Wir haben mehrere Anwendungsfälle identifiziert, die unser Geschäftscode (AWS Lambda) verarbeiten muss:
- Die Anmeldedaten des Kontos sind falsch. Die Authentifizierung beim SMS-Anbieter schlägt fehl, und die SMS wird nicht gesendet.
- Das Konto verfügt nicht über genügend Guthaben. Um die Operation auszuführen, werden einige Credits verbraucht
- Die SMS wird gesendet. Alles gut, SMS gesendet, Guthaben abgezogen, glückliche Tage
- Regentag. Aus irgendeinem Grund liefert der SMS-Anbieter nicht das erwartete Ergebnis (wie in den vorherigen Punkten beschrieben). Daher müssen wir es abfangen und behandeln
Strategie testen
Wir möchten das Feedback so schnell wie möglich erhalten, mit verschiedenen Teststufen. Wir haben Unit-Tests, um sicherzustellen, dass sich die Geschäftslogik auf der Grundlage der Anwendungsfälle verhält. Wir haben jedoch auch Akzeptanztests im Format Geben/Wenn/Dann, die einen breiteren Umfang haben als die Unit-Tests.
Implementierung
In Anbetracht der oben beschriebenen Einschränkungen und um das Niveau der Tests zu erreichen, müssen wir eine Test-API mit demselben Verhalten wie der SMS-Anbieter erstellen.
Testen der API
Die Testing API muss so instrumentiert werden, dass sie sich entsprechend dem Anwendungsfall verhält. Am einfachsten geht das mit einer Umgebungsvariablen:
switch (Environment.GetEnvironmentVariable("API_BEHAVIOUR"))
{
case "ok":
return new OkResult();
case "invalid_credentials":
return new UnauthorizedResult();
case "insufficient_credits":
return new StatusCodeResult((int) HttpStatusCode.Forbidden);;
default:
return new StatusCodeResult((int) HttpStatusCode.InternalServerError);
}
Mit diesem Ansatz können wir die Antwort der Testing API kontrollieren und so das korrekte Verhalten der Lambda-Funktion sicherstellen.
Die Testing API wird in einem Docker-Container bereitgestellt, der gleichen Technologie, die auch von SAM Local verwendet wird. Die Wiederverwendung der gleichen Technologie verringert das Risiko von Reibungsverlusten in unserer Entwicklungsumgebung. Es ist jedoch auch möglich, die Testing API in anderen Hosting-Technologien einzusetzen.
SAM Lokal
AWS hat das Serverless Application Model (SAM) Local Tooling entwickelt und veröffentlicht."sam" ist das AWS CLI-Tool zur Verwaltung von Serverless-Anwendungen, die mit AWS Serverless Application Model (SAM) geschrieben wurden. SAM CLI kann verwendet werden, um Funktionen lokal zu testen, ein lokales API-Gateway aus einer SAM-Vorlage zu starten, eine SAM-Vorlage zu validieren, Beispiel-Payloads für verschiedene Ereignisquellen zu generieren und ein SAM-Projekt in Ihrer bevorzugten Lambda Runtime zu erzeugen." [1]
Die AWS Lambda-Funktion wird durch ein API-Gateway-Ereignis ausgelöst und sendet die Benachrichtigung als SMS an den SMS-Anbieter.
Die Vorlage enthält alle erforderlichen Komponenten:
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Description: AWS SAM Local blog example
Resources:
Lambda:
Type: AWS::Serverless::Function
Properties:
Handler: Lambda::Lambda.Function::Handler
CodeUri: ./Lambda.zip
Runtime: dotnetcore2.0
Environment:
Variables:
SMS_API_URL: https://testing-api:80/
SMS_API_USERNAME: foo
SMS_API_PASSWORD: bar
Events:
PostEvent:
Type: Api
Properties:
Path: /
Method: post
Wie in der Vorlage beschrieben, leitet das API Gateway eine POST-Anfrage an AWS Lambda weiter, das für die Ausführung des Geschäftscodes verantwortlich ist.
Abnahmetests
Die Akzeptanztests zielen darauf ab, das Systemverhalten auf der Grundlage der Spezifikationen zu testen. Die Spezifikationen wurden auf der Grundlage von Geben/Wenn/Dann kodiert, wobei die Tests in einer Blackbox-Methode ausgeführt werden (d. h. das System wird ohne Kenntnis der Interna getestet).
Für jeden Testlauf wird ein Bericht erstellt. Dies ist das Standardverhalten des Testing Frameworks(LightBDD). Sie können es jedoch mit Ihrem bevorzugten Gift implementieren :)
Die Akzeptanztests sind für den Start der Test-API mit dem erforderlichen Verhalten für das getestete Szenario verantwortlich und starten auch das SAM Local, indem sie den API Gateway-Befehl aufrufen:
sam local start-api --docker-network testing
Alles zusammenfügen
Da wir uns in der .NET-Welt bewegen, verwenden wir Cake, um unsere lokalen Tests zu skripten. Das Skript ermöglicht das Erstellen, Bereitstellen und Testen der beteiligten Komponenten auf die gleiche Weise lokal und auf dem CI-Server. In diesem Fall das Skript:
- Bereinigt die Dateien des vorherigen Builds (Binärdateien, Artefakte, usw.)
- Stellt die Abhängigkeiten wieder her (NuGet)
- Baut die Lösung
- Führen Sie die Unit-Tests aus
- Veröffentlichen Sie die AWS Lambda und die Testing API
- Verpacken Sie den AWS Lambda in eine Zip-Datei
- Setzt den zuvor komprimierten AWS Lambda und die SAM-Vorlage ein
- Erzeugt das Docker-Container-Image für die Testing API
- Erzeugt das Docker-Netzwerk für die Komponenten
- Führen Sie die Akzeptanztests durch
- Entfernt das Docker-Netzwerk
- Entfernt das Docker-Container-Image
Die Schritte können lokal oder auf dem CI-Server ausgeführt werden (siehe hier für TravisCI. Wir haben einige Einschränkungen bei der Ausführung in AppVeyor). Sie finden den Code hier: Beispiel für ein AWS SAM Local in C#
Abschließende Gedanken
Serverless ist eine großartige Technologie, die die notwendige Wartung der Cloud-Komponenten verringert. Wie jede Technologie sollten wir sie jedoch pragmatisch einsetzen. Da es einfach ist, unseren Code in eine Funktion (oder Lambda, je nach Anbieter) zu packen, können wir mit mehreren asynchronen Triggern in der Cloud enden. Erinnern Sie sich noch an die Verwendung von Triggern in Datenbanken in früheren Zeiten? Einfach zu entwickeln, mühsam zu warten. Das Gleiche gilt für serverlosen Code...
Referenzen
Hinweis: SAM Local befindet sich noch in der Beta-Phase. Verfolgen Sie die Fortschritte auf GitHub AWS SAM Cli Dieser Beitrag wurde auch in meinem persönlichen Blog veröffentlicht.
Verfasst von

João Rosa
Unsere Ideen
Weitere Blogs
Contact



