Betrachtet man die Meldung bezüglich des „falschen Befehls“ der an Voyager 2 versendet wurde, so hätte man das in einer entsprechenden Emulation eigentlich feststellen müssen, dass eben dieser Befehl klar falsch ist. Bisher bin ich immer davon ausgegangen, dass so etwas in einer Emulation auf einem Environment stattfindet. Denn wie bei allen uns bekannten Sprachen, die man entsprechend einsetzt, gibt es entsprechende Testframeworks, die entsprechende Emulationen ausführen.
Die Antenne von »Voyager 2« zeigt nicht mehr exakt zur Erde, der Kontakt ist dadurch unterbrochen. Der Grund: ein falscher Befehl. Doch im Oktober könnte die Kommunikation wieder aufgenommen werden.
Hier eine weitere Meldung:
Der Kontakt zu der Sonde war am 21. Juli 2023 abgebrochen, nachdem "eine Serie geplanter Befehle" an sie gesendet worden war. Die hatten dazu geführt, dass sich die Antenne um 2 Grad von der Erde wegdrehte, weshalb kein Kontakt mehr möglich war.
Quelle: https://www.golem.de/news/raumfahrt-nasa-empfaengt-signal-von-voyager-2-2308-176370.html
Fortran spielte in den frühen Jahren der Raumfahrt und insbesondere bei der Entwicklung von Raumsonden eine wichtige Rolle. Das Voyager-Programm wurde in den 1970er Jahren gestartet, als Fortran immer noch eine der vorherrschenden Programmiersprachen für wissenschaftliche und technische Anwendungen war. Und Fortan wird bis heute gerade auch im wissenschaftlichen Umfeld immer noch genutzt!
Welche Fortran Versionen gibt es?
- Fortran I (1957): Die erste Version von Fortran wurde 1957 von IBM entwickelt. Sie wurde für den IBM 704 Computer entwickelt und war die erste höhere Programmiersprache überhaupt. Fortran I unterstützte die grundlegenden Konzepte der Programmierung, aber es gab noch keine Unterprogramme (keine Unterstützung für Unterprogramme wie Funktionen oder Subroutinen).
- Fortran II (1958): Fortran II wurde 1958 veröffentlicht und fügte einige neue Funktionen hinzu, darunter Unterprogramme und die Möglichkeit, Unterprogramme in anderen Unterprogrammen aufzurufen. Es war eine verbesserte Version von Fortran I.
- Fortran IV (1962): Fortran IV war eine weiter verbesserte Version von Fortran und wurde 1962 veröffentlicht. Es führte neue Funktionen wie logische Variablen, DO-Schleifen und FORMAT-Anweisungen ein, um die Ausgabe zu formatieren.
- Fortran 66: Fortran 66, auch bekannt als Fortran IV oder Fortran 66 Standard, wurde 1966 eingeführt. Es war die erste offizielle Version der Sprache mit einem standardisierten Sprachumfang. Fortran 66 führte neue Funktionen wie das IF-THEN-ELSE-Konstrukt ein und standardisierte einige vorhandene Sprachkonstrukte.
- Fortran 77: Fortran 77, auch bekannt als Fortran 1977 Standard, wurde 1977 veröffentlicht. Es war eine bedeutende Aktualisierung und erweiterte den Funktionsumfang von Fortran erheblich. Fortran 77 führte Zeichenkettenverarbeitung, dynamische Speicherzuweisung (mit der ALLOCATE-Anweisung) und verbesserte Array-Funktionen ein.
- Fortran 90: Fortran 90 wurde 1991 veröffentlicht und brachte wichtige Erweiterungen in die Sprache. Es führte den freien Formatierungsstil ein, verbesserte die Array-Unterstützung (einschließlich dynamischer Arrays und Array-Schnittoperationen), fügte neue Sprachkonstrukte wie MODULES, POINTERs und DO WHILE-Schleifen hinzu und ermöglichte rekursive Unterprogramme.
- Fortran 95: Fortran 95 wurde 1997 als geringfügige Aktualisierung von Fortran 90 veröffentlicht. Es behebt einige Unklarheiten und Fehler in Fortran 90 und fügt einige neue Funktionen hinzu, wie beispielsweise Verbesserungen bei der ALLOCATE-Anweisung und Unterstützung für den CHARACTER-Datentyp mit variabler Länge.
- Fortran 2003, Fortran 2008, Fortran 2018: Diese Versionen sind weitere Erweiterungen von Fortran, die neue Funktionen und Verbesserungen in die Sprache einbringen, wie z. B. Verbesserungen bei der Behandlung von Zeichenketten, Verbesserungen bei der parallelen Programmierung (Fortran 2008) und viele andere Funktionen.
Testframeworks für Fortran
In der Welt von Fortran gibt es mehrere Testframeworks, die verwendet werden können, um Unit-Tests für Fortran-Code durchzuführen. Wobei man sagen muss das Voyger 2 in Teilen noch auf Fortran 77 beruht aber auch Fortran 90.
Hier sind einige beliebte Testframeworks, es gibt aber weitaus mehr unter anderem entwickelt durch NASA Mitarbeiter:
Testframework | Details | Weiterführende Informationen | Alternative |
FRUIT (Fortran Unit Tester): | FRUIT ist eines der ältesten Testframeworks für Fortran und wird häufig verwendet, um Unit-Tests für Fortran-77-Code zu schreiben. Es unterstützt die Erstellung von Testsuiten und Assertions, um die Funktionalität von Fortran-Routinen zu überprüfen. | ||
FUnit | FUnit ist ein moderneres Testframework für Fortran, das speziell für die Erstellung von Unit-Tests in Fortran entwickelt wurde. Es unterstützt Fortran 90 und höher und bietet eine Vielzahl von Testfunktionen und Assertions.
https://fortranwiki.org/fortran/show/FUnit
|
||
Fortran Unit Test (FUT): | FUT ist ein weiteres Testframework für Fortran, das es ermöglicht, Unit-Tests für Fortran-Code zu schreiben. Es bietet Funktionen wie Assertions und die Möglichkeit, Testergebnisse zu protokollieren.
https://github.com/dongli/fortran-unit-test
|
||
PFUnit (Parallel Fortran Unit Test): | PFUnit ist ein Testframework, das speziell für den Test paralleler Fortran-Code entwickelt wurde. Es ermöglicht die Durchführung von Tests für parallele Funktionen und Routinen. | ||
Fortran Test Framework (FTF): | Das Fortran Test Framework ist ein einfaches und leichtgewichtiges Testframework für Fortran. Es unterstützt die Erstellung von Unit-Tests und Assertions.
|
Ein Flussdiagramm zur Beschreibung der Laufzeit:
|
|
ForFUnit: | ForFUnit ist ein weiteres Testframework für Fortran, das es ermöglicht, Unit-Tests für Fortran-Code zu schreiben. Es bietet Funktionen wie Assertions und die Möglichkeit, Testergebnisse zu protokollieren.
|
||
Fortuno |
Benutzerfreundliches, flexibles und erweiterbares objektorientiertes Fortran-Unit-Testing-Framework zum Testen von seriellen, MPI-parallelisierten und Coarray-parallelisierten Anwendungen.
https://github.com/aradi/fortuno
|
Aufbau von Testszenarien in Fortran
In Fortran gibt es keine eingebauten Testframeworks oder Assertions wie in einigen modernen Programmiersprachen. Daher müssen Entwickler Testroutinen und Assertions oft manuell implementieren. Hier ist ein einfaches Beispiel, wie ihr eine Testroutine mit Assertions in Fortran erstellen könnt:
PROGRAM TestExample IMPLICIT NONE ! Function to be tested REAL FUNCTION Square(x) REAL, INTENT(IN) :: x Square = x * x END FUNCTION Square ! Test routine SUBROUTINE RunTests INTEGER :: numTests, i REAL :: input, result, expected ! Array of test cases: (input, expected result) REAL, DIMENSION(3, 2) :: testCases testCases = RESHAPE([1.0, 1.0, & 2.0, 4.0, & 3.5, 12.25], [3, 2]) numTests = SIZE(testCases, 1) DO i = 1, numTests input = testCases(i, 1) expected = testCases(i, 2) result = Square(input) ! Assertion IF (result == expected) THEN WRITE(*, '(A, F6.2, A, F6.2)') 'Test ', input, ': Passed. Result = ', result ELSE WRITE(*, '(A, F6.2, A, F6.2, A, F6.2)') 'Test ', input, ': Failed. Expected = ', expected, ', Got = ', result END IF END DO END SUBROUTINE RunTests ! Run the tests CALL RunTests() END PROGRAM TestExample
Aufbau einer Testsuite in Fortran
In Fortran gibt es keine eingebaute Testsuit-Struktur wie in einigen modernen Programmiersprachen. Daher müssen Entwickler Testsuiten manuell implementieren. Eine Testsuite in Fortran ist eine Sammlung von mehreren Testroutinen, die verschiedene Funktionen oder Teile des Fortran-Codes testen. Hier ist ein einfaches Beispiel, wie Sie eine Testsuite in Fortran erstellen können:
Angenommen, ihr habt eine Fortran-Datei my_functions.f90
, die einige Funktionen enthält, die ihr testen möchtet. Ihr könnt eine separate Testdatei test_my_functions.f90
erstellen, die eure Testsuite enthält.
! Datei: my_functions.f90 MODULE MyFunctions IMPLICIT NONE CONTAINS ! Funktion 1: Berechne das Quadrat einer Zahl REAL FUNCTION Square(x) REAL, INTENT(IN) :: x Square = x * x END FUNCTION Square ! Funktion 2: Berechne die Fakultät einer ganzen Zahl INTEGER FUNCTION Factorial(n) INTEGER, INTENT(IN) :: n INTEGER :: i, result result = 1 DO i = 1, n result = result * i END DO Factorial = result END FUNCTION Factorial END MODULE MyFunctions
! Datei: test_my_functions.f90 PROGRAM TestSuite USE MyFunctions IMPLICIT NONE ! Testroutine für Square SUBROUTINE TestSquare REAL :: input, result, expected ! Testfälle: (input, erwartetes Ergebnis) REAL, DIMENSION(3, 2) :: testCases testCases = RESHAPE([1.0, 1.0, & 2.0, 4.0, & 3.5, 12.25], [3, 2]) WRITE(*, '(A)') 'Testing Square' DO i = 1, SIZE(testCases, 1) input = testCases(i, 1) expected = testCases(i, 2) result = Square(input) ! Assertion IF (result == expected) THEN WRITE(*, '(A, F6.2, A, F6.2)') 'Test ', input, ': Passed. Result = ', result ELSE WRITE(*, '(A, F6.2, A, F6.2, A, F6.2)') 'Test ', input, ': Failed. Expected = ', expected, ', Got = ', result END IF END DO END SUBROUTINE TestSquare ! Testroutine für Factorial SUBROUTINE TestFactorial INTEGER :: input, result, expected ! Testfälle: (input, erwartetes Ergebnis) INTEGER, DIMENSION(3, 2) :: testCases testCases = RESHAPE([0, 1, & 3, 6, & 5, 120], [3, 2]) WRITE(*, '(A)') 'Testing Factorial' DO i = 1, SIZE(testCases, 1) input = testCases(i, 1) expected = testCases(i, 2) result = Factorial(input) ! Assertion IF (result == expected) THEN WRITE(*, '(A, I3, A, I6)') 'Test ', input, ': Passed. Result = ', result ELSE WRITE(*, '(A, I3, A, I6, A, I6)') 'Test ', input, ': Failed. Expected = ', expected, ', Got = ', result END IF END DO END SUBROUTINE TestFactorial ! Hauptprogramm der Testsuite CALL TestSquare() CALL TestFactorial() END PROGRAM TestSuite
Wie man den Fehler hätte verhindern können?
Grundsätzlich gehe ich davom aus das die NASA solche Testmethoden einsetzt und auch entsprechende Emulationen laufen hat? Trotzdem wundert es das man hier eben doch falsche Befehle versendet hat. Entweder ist es menschliches Versagen, oder die Befehle wurden nicht ausreichend geprüft?
Das Testen von falschen oder fehlerhaften Befehlen in Fortran kann schwierig sein, da der Fortran-Compiler normalerweise während der Kompilierung Fehler in ungültigen Befehlen erkennt und den Kompilationsprozess beendet. Dennoch könnt ihr in einigen Fällen Testfälle erstellen, um zu überprüfen, wie Ihr Code mit fehlerhaften Befehlen umgeht.
Hier sind einige Möglichkeiten, wie ihr falsche Befehle in Fortran testen könntet:
- Ungültige Variablennamen: Erstellt Testfälle mit ungültigen oder nicht deklarierten Variablennamen, um zu überprüfen, wie euer Code auf solche Fehler reagiert.
- Syntaxfehler: Erstellt Testfälle mit fehlerhaften Syntaxkonstruktionen, wie beispielsweise fehlenden Klammern, falschen Zeichenketten oder fehlenden Semikolons.
- Falsche Datentypen: Überprüft, wie euer Code auf ungültige Datentypen reagiert, z. B. wenn ihr versucht, eine Zeichenkette in eine ganze Zahl umzuwandeln oder umgekehrt.
- Ungültige Compilerdirektiven: Testet, wie euer Code auf ungültige oder nicht unterstützte Compilerdirektiven reagiert.
- Fehlerhafte Ein-/Ausgabeoperationen: Testet, wie euer Code auf fehlerhafte Ein-/Ausgabeoperationen reagiert, z. B. wenn ihr versucht, in eine geschlossene Datei zu schreiben oder von einer nicht vorhandenen Datei zu lesen.
Die folgenden Beispiele zeigen, wie einige der oben genannten Szenarien in einer Testumgebung aussehen könnten:
FUNCTION Divide(a, b) REAL, INTENT(IN) :: a, b REAL :: Divide IF (b == 0.0) THEN WRITE(*, '(A)') 'Error: Division by zero.' STOP END IF Divide = a / b END FUNCTION Divide SUBROUTINE TestNegativeDivision REAL :: result ! Negative Test: Division durch Null result = Divide(5.0, 0.0) ! Erwartung: Fehlermeldung "Error: Division by zero." END SUBROUTINE TestNegativeDivision
FUNCTION GetStringLength(str) CHARACTER(*), INTENT(IN) :: str INTEGER :: GetStringLength GetStringLength = LEN_TRIM(str) END FUNCTION GetStringLength SUBROUTINE TestInvalidStringLength INTEGER :: length CHARACTER(5) :: myString = "Hello" ! Negative Test: Zuweisen eines zu langen Strings zu einer begrenzten Zeichenkette length = GetStringLength(myString) ! Erwartung: Compilerfehler oder Laufzeitfehler END SUBROUTINE TestInvalidStringLength
Diese Beispiele zeigen, wie ihr Testfälle erstellen könnt, die fehlerhafte Befehle in eurem Fortran-Code auslösen, um sicherzustellen, dass euer Code angemessen auf solche Fehler reagiert.
Wie in jeder anderen Sprache sollte man auch die entsprecchenden Workflows einhalten. Es geht immer um den Test von Schwachstellen, daher ergeben sich auch immer die gleichen Szenarieren im Test.
Statische Code-Analyse: Statische Code-Analysetools durchsuchen euren Quellcode, um mögliche Schwachstellen und Fehler zu erkennen, ohne den Code tatsächlich auszuführen. Diese Tools können beispielsweise potenzielle Speicherzugriffsfehler, uninitialisierte Variablen oder unsichere Aufrufe von Funktionen erkennen. Einige gängige statische Analysetools für Fortran sind:
- Frama-C: Ein Framework für die statische Analyse von C- und Fortran-Code.
- FortranLint: Ein kommerzielles statisches Analysetool für Fortran.
Dynamische Code-Analyse: Dynamische Code-Analysetools führen Ihren Code aus und überwachen sein Verhalten zur Laufzeit. Diese Tools können Laufzeitfehler, Speicherlecks und andere potenzielle Probleme erkennen. Beim Testen von Fortran ist es wichtig, Ihre Tests mit verschiedenen Eingabewerten und Grenzfallbedingungen durchzuführen. Mit selbst ist nur ein Tool bekannt welches Entsprechend ab Fortran 77 eingesetzt werden kann:
Code-Reviews: Peer-Reviews und Sicherheitsüberprüfungen sind ebenfalls wichtige Schritte, um potenzielle Schwachstellen im Code zu entdecken. Lassen Sie andere Entwickler Ihren Code überprüfen und Feedback geben, um mögliche Sicherheitslücken zu identifizieren.
Kann man diesen Testcode automatisieren?
Ja, ihr könnt den Testcode in Jenkins oder GitHub in einer Pipeline automatisieren, um eine kontinuierliche Integration und automatisierte Testabläufe zu ermöglichen. Beide Plattformen bieten Möglichkeiten, Skripte und Tests in einer Pipeline zu definieren und auszuführen, um sicherzustellen, dass euer Code kontinuierlich getestet wird. Es wundert mich das dieser fehler gerade der NASA passiert ist, denn einige der oben genannten Testframeworks sind eigene Entwicklungen von NASA Mitarbeitern.
Beispiel Jenkins:
In Jenkins könnt ihr eine Pipeline erstellen, um eure Fortran-Tests zu automatisieren.
Ein einfacher Jenkins-Pipeline-Code könnte wie folgt aussehen:
pipeline { agent any stages { stage('Build') { steps { // Hier den Code aus dem Repository klonen und den Fortran-Compiler ausführen, um den Code zu kompilieren } } stage('Test') { steps { sh 'gfortran -o test_my_functions test_my_functions.f90 my_functions.f90' // Kompilieren des Testcodes sh './test_my_functions' // Ausführen der Testsuite } } } }
Beispiel Github Actions;
In GitHub können Sie eine ähnliche Pipeline in Form von GitHub Actions erstellen. GitHub Actions ermöglicht es Ihnen, den Testcode in einer YAML-Datei zu definieren, die im Repository gespeichert wird.
Ein einfacher GitHub Actions-Pipeline-Code könnte wie folgt aussehen:
name: Fortran CI on: [push] jobs: test: runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v2 - name: Install gfortran run: sudo apt-get update && sudo apt-get install gfortran - name: Compile and run tests run: | gfortran -o test_my_functions test_my_functions.f90 my_functions.f90 ./test_my_functions
Neueste Kommentare