<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.flightgear.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Callahanp</id>
	<title>FlightGear wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.flightgear.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Callahanp"/>
	<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/Special:Contributions/Callahanp"/>
	<updated>2026-05-30T00:03:39Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.6</generator>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=142775</id>
		<title>User:Callahanp</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=142775"/>
		<updated>2025-10-19T16:40:14Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: /* FlightGear's DataFlow Diagram */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Me ==&lt;br /&gt;
 &lt;br /&gt;
Hello, my name is Patrick Callahan. People call me Pat. I have a website, and you've found it.&lt;br /&gt;
&lt;br /&gt;
I've been a programmer since I was a teenager. I'm 74 years old and retired now. I have signed [https://agilemanifesto.org/the the Agile Manifesto].&lt;br /&gt;
&lt;br /&gt;
Programming was a fun job. We couldn't believe we got paid to have so much fun.&lt;br /&gt;
&lt;br /&gt;
My current expertise primarily lies in databases, bash scripting, and traditional procedural programming in various languages.&lt;br /&gt;
&lt;br /&gt;
C++ is a work in progress. I took a course in 1993, but never used it professionally.  &lt;br /&gt;
&lt;br /&gt;
I like gardening with my wife of 33 years, Ann. We have a daughter who has given us three very active grandchildren, who will visit us next week for four days. Did I say I kept busy? We reside in the state of Massachusetts in the United States.&lt;br /&gt;
&lt;br /&gt;
I hope to make regular code contributions to FlightGear. I want to gain the skills to address some FlightGear issues as they come up and participate in the discussions and programming for the various [FlightGear Epics |https://gitlab.com/groups/flightgear/-/epics?sort=created_date&amp;amp;state=opened&amp;amp;first_page_size=100]&lt;br /&gt;
&lt;br /&gt;
You are about to read a very personal document. I make statements there that I have not yet validated by discussing these ideas directly with others and trying to put them into practice. Go easy on me. Criticize my ideas, not me. I think this is ok, as the material is buried in a personal web page on a wiki.&lt;br /&gt;
&lt;br /&gt;
== FlightGear Development: ==&lt;br /&gt;
&lt;br /&gt;
I'm motivated to learn enough C++, Nasal, and whatever else it takes to start regularly contributing to the Flightgear Codebase.  &lt;br /&gt;
&lt;br /&gt;
Someone with practical experience writing, maintaining, and fixing problems in C++ can easily begin contributing to FlightGear's codebase.  They may find a few fine points, such as the internal scripting language and the property tree, but they should be able to navigate with little assistance.  That's not me.  I don't have the practical experience, and my  C++ experience consists mostly of a one-semester class.  Not only that, the class was in the previous century.  Move semantics?  What's That!?&lt;br /&gt;
&lt;br /&gt;
You get the idea:  &amp;quot;Nice goal, Pat.  Good luck with that. You do realize you are 75 years old, don't you?&amp;quot;&lt;br /&gt;
Heedless, I press on.&lt;br /&gt;
&lt;br /&gt;
It should be obvious to all that this endeavour requires a lot of work, and anyone undertaking it is going to need help at various points.  It's easy to get stuck on specific points, and stuck in ways that you don't know which question to ask first, and where to ask it.  You, kind reader, may be able to help.  &lt;br /&gt;
&lt;br /&gt;
== Flightgear - Study Group ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I'm continuing to think about the idea of organizing and participating in a study group for flightgear coding, I want to consider current work on Flightgear proceeding on [http://gitlab.com/flightgear Gitlab] as fodder for study.&lt;br /&gt;
&lt;br /&gt;
The study group idea was prompted by my thinking about the codebase itself and why I found it so difficult to understand.  I'm sure others have at least some of the same challenges if they share my goal of becoming a regular flightgear contributor. If so,  we are likely to find common ground in meeting those challenges.&lt;br /&gt;
&lt;br /&gt;
These points are personal challenges in learning how FlightGear works, writing code and documentation, and debugging. &lt;br /&gt;
&lt;br /&gt;
* Object-oriented programming - Don't get me started.  Based on secondary sources, I agree with Alan Kay's thoughts on messaging as the most important aspect of &amp;quot;object&amp;quot; thinking, which most of us seem to overlook.&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://wiki.c2.com/?AlanKaysDefinitionOfObjectOriented Alan Kays Definition Of Object Oriented]&amp;lt;/ref&amp;gt;  Alan appears to live nearby.  Maybe I'll get up the nerve to ask him personally.  Finally, I am pretty sure I am not &amp;quot;a can of Coke&amp;lt;ref&amp;gt; [http://www.johno.se/book/oops.html OOPs - nasty traps in Object Oriented Programming]&amp;lt;/ref&amp;gt;.&amp;quot;&lt;br /&gt;
* C++,  when I learned C++, the STL was new. New as in &amp;quot;Do you need a container? Please feel free to write an implementation as homework&amp;quot;.  There has been significant progress since then, but I never actually wrote any C++ professionally, so I'm catching up on the changes in C++98, 03, 11, 14, 17, and 20.&lt;br /&gt;
* Specific Aircraft simulations are implemented mostly in XML, AC files, and Nasal, not in C++.&lt;br /&gt;
* Nasal is an interpreted language with separate class structures, memory allocation, and symbol tables, inaccessible to debuggers.&lt;br /&gt;
* The property tree is a global data store used for most intercommunication between subsystems, but it has no concept of messaging or data flow management.  Everything is done with callbacks on individual properties.  It's like watching an ant colony.&lt;br /&gt;
&lt;br /&gt;
None of the above should be taken as a suggestion that FlightGear development take any specific direction in the future.  That will come from me only after I've become a regular and significant contributor of C++, Nasal, and FlightGear data.  Nor should it be taken as criticism of what has been done so far in the 28-year history of the project.&lt;br /&gt;
&lt;br /&gt;
== Getting an Giving Help ==&lt;br /&gt;
I want to request assistance in the appropriate forums, having exhausted all possible avenues to explore answers before seeking help. At the same time I want to help others with any code problems they are struggling with. &lt;br /&gt;
 &lt;br /&gt;
I like helping other people.  It's the best way to make friends. &lt;br /&gt;
&lt;br /&gt;
I want you to know that I sometimes help people by listening to them describe a problem, and suggesting a route to finding some small tidbit of information that makes the problem easier to think about. It doesn't always happen, or even often, but when it does, the result seems very satisfying to both parties.  &lt;br /&gt;
&lt;br /&gt;
There are other times when just having me listen attentively to an explanation of a problem is sufficient for the teller to grasp a solution. I don't have to say a word, but they already have the answer.  Helpful, no?  This has happened to me on numerous occasions, more so than me making helpful comments.  Perhaps my asking for a description of the problem and any naive questions I ask about it are enough to get things moving.&lt;br /&gt;
&lt;br /&gt;
If you're stuck on a point and want my help, please don't hesitate to ask me personally on any forum where you encounter me. &lt;br /&gt;
You can find me on Discord as callahanp, on IRC as pac1 (early internet username formed from my initials)&lt;br /&gt;
&lt;br /&gt;
== Teamwork: ==&lt;br /&gt;
I'm a believer in teamwork and would love working closely in real-time with others on specific programming problems. I hope we can create opportunities for that.  I also believe that the only learning environment is not limited to a formal course, which includes lectures, readings, homework, quizzes, tests, and final grades.  Grown-ups use study groups, working groups, collaborators, publications, conferences, and prior work. And they take formal courses from time to time.&lt;br /&gt;
&lt;br /&gt;
== Pair programming ==&lt;br /&gt;
&lt;br /&gt;
I find pair programming an attractive idea and wonder how it works in practice. What is the result of practicing pair programming with programmers of similar skills? What happens when an expert programmer pairs with an inexperienced one?&lt;br /&gt;
&lt;br /&gt;
I find that most are resistant to participating in pair programming, and I wonder why.  &lt;br /&gt;
&lt;br /&gt;
We're taught in academic settings to program by ourselves and hand in ou submissions for review as &amp;quot;homework&amp;quot;, but we continue that pattern in our work mainly out of inertia and lack of proper training. There's no reason to continue that pattern outside of a classroom as our only or even as main way of working together. &lt;br /&gt;
&lt;br /&gt;
== Understanding FlightGear's Large &amp;amp; Complex Codebase ==&lt;br /&gt;
&lt;br /&gt;
The problem with FlightGear is its size, complexity, and the lack of a detailed guide to exploring that complexity. Several factors contribute to that complexity. Understanding FlightGear requires knowledge of many application domains, C++, an internal scripting language, a global data store, application features driven by XML or scripts, network protocols and data formats, some custom, some obscure, and from the era of mainframe computers.&lt;br /&gt;
&lt;br /&gt;
I'll examine each of these complexity realms with a view to providing a guideline for new FlightGear developers, me for instance, a path to follow leading to regular contributions to the FlightGear in C++, Nasal, and XML and other data formats.&lt;br /&gt;
&lt;br /&gt;
== C++ ==&lt;br /&gt;
&lt;br /&gt;
  First, the application uses C++. As a complex and evolving language, C++ has a reputation for being complex. It's not just the language, its the fragmentation of code into small tidbits, widely scattered in individual files covering supposedly just one aspect of what needs to be done. I don't really know if the structure of C++ code as objects is more efficient than a C++ program done using solid structured programming, but I know which is easier think about and to work on.&lt;br /&gt;
&lt;br /&gt;
== Flight Simulation does a lot of different things == &lt;br /&gt;
&lt;br /&gt;
Second, Flight Simulation involves numerous application domains. Among them are aerodynamics, graphics, geography, geodesy, environment, navigation, networks, audio, video, and human languages. FlightGear addresses all of them and more. Each of these domains has its own view of the world, and many of them are modelled as C++ classes. Full understanding comes from knowing the C++ code, the terminology of the domain, and the way the code's authors chose to structure things as objects and methods.  &lt;br /&gt;
&lt;br /&gt;
== Nasal and the Property Tree ==&lt;br /&gt;
&lt;br /&gt;
Next, in addition to the complexity introduced by C++ and the application domains, there's Nasal. Finally, to tie it all together, loosely, the property tree. a global object, with individual data items of a key-value store actually stored in a tree because they are conceptually related. The property tree introduced complexity because items in it are not &amp;quot;owned&amp;quot;, they're simply created at some point, in either C++, XML processing, or Nasal, and used wherever the data item is &amp;quot;needed&amp;quot;. Connecting the dots through all the code based on identifying individual properties is not all that easy.&lt;br /&gt;
&lt;br /&gt;
== Where should I start? C++, Nasal or XML) ==&lt;br /&gt;
&lt;br /&gt;
It's not clear from existing documentation the central role of Nasal scripting and the Property Tree are in the simulation. It's not just C++, Nasal, and the interface between them, understood as computer languages.   Knowing the languages and interfaces themselves is vital, but even more important is understanding how scripting is used in FlightGear to create the simulation. If you are struggling as a newcomer to understand FlightGear's C++ code, understanding Nasal's role in driving parts of the simulation and the way it interacts with C++ code is probably one of the first things to do. It's what I'll be doing next.&lt;br /&gt;
&lt;br /&gt;
== FlightGear's DataFlow Diagram == &lt;br /&gt;
&lt;br /&gt;
There isn't one. Or rather, there is one, but it's virtual in the sense that no one used it as a design document; rather, it is constructible as a mental model from the observable workings of flightgear itself.`&lt;br /&gt;
&lt;br /&gt;
Part of understanding any body of code is to be able to identify how data flows through the application. Dataflows are usually represented as arrows of various widths. The arrows are messages flowing between parts of an application. The larger the arrow, the more data items in that data flow.  Knowing what is in each of those flows is important to understanding how the application works.  &lt;br /&gt;
&lt;br /&gt;
In FlightGear's C++ code, there are, of course, classes and objects that represent some dataflows. There's a problem, though. Many of the classes are about processing data into ad-hoc structures within the property tree.  How can we define a data flow for these ad-hoc structures?  (Note: need a way to describe two dataflows.  The one that creates the infrastructure as properties in the tree, and a second one implied by the existence of a set of properties.)&lt;br /&gt;
&lt;br /&gt;
There is no C++ class for an Altimeter or a Heading Indicator. Instead, these are represented by a set of properties and data loaded via XML and other formats. The numerical data, stored in the property tree has a path indicating that the properties underneath a node are for the altimeter or the heading indicator. The actual paths in this case are /instrumentation/altimeter and /instrumentation/heading-indicator. Each node in the tree can have properties as child nodes, as well as child nodes that contain additional properties, such as /instrumentation/heading-indicator/gyro.  &lt;br /&gt;
&lt;br /&gt;
Properties are created on the fly, once the property tree's root node is instantiated. Properties are specified in XML data, created by a Nasal script, or by C++ code. The actual property mechanism is implemented in a C++ class.&lt;br /&gt;
&lt;br /&gt;
After they are created, properties are used as needed from Nasal scripts and C++ code, and finally destroyed by a destructor in C++. However, none of that is traceable as a data flow. IDEs are great at connecting elements of code to their definitions and usage, but when we use a data store like the property tree, the connection can't be found by the IDE. These data flows through the property tree mechanisms are a real part of the FlightGear Application, but we have no easy way to visualise them. Any visualization is mentally constructed over time by developers' experiences, as they examine and step through code.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[http://wiki.flightgear.org/User:Callahanp/goals What's up with Pat]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=142774</id>
		<title>User:Callahanp</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=142774"/>
		<updated>2025-10-19T16:35:27Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: small edit removing incomplete sentance&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Me ==&lt;br /&gt;
 &lt;br /&gt;
Hello, my name is Patrick Callahan. People call me Pat. I have a website, and you've found it.&lt;br /&gt;
&lt;br /&gt;
I've been a programmer since I was a teenager. I'm 74 years old and retired now. I have signed [https://agilemanifesto.org/the the Agile Manifesto].&lt;br /&gt;
&lt;br /&gt;
Programming was a fun job. We couldn't believe we got paid to have so much fun.&lt;br /&gt;
&lt;br /&gt;
My current expertise primarily lies in databases, bash scripting, and traditional procedural programming in various languages.&lt;br /&gt;
&lt;br /&gt;
C++ is a work in progress. I took a course in 1993, but never used it professionally.  &lt;br /&gt;
&lt;br /&gt;
I like gardening with my wife of 33 years, Ann. We have a daughter who has given us three very active grandchildren, who will visit us next week for four days. Did I say I kept busy? We reside in the state of Massachusetts in the United States.&lt;br /&gt;
&lt;br /&gt;
I hope to make regular code contributions to FlightGear. I want to gain the skills to address some FlightGear issues as they come up and participate in the discussions and programming for the various [FlightGear Epics |https://gitlab.com/groups/flightgear/-/epics?sort=created_date&amp;amp;state=opened&amp;amp;first_page_size=100]&lt;br /&gt;
&lt;br /&gt;
You are about to read a very personal document. I make statements there that I have not yet validated by discussing these ideas directly with others and trying to put them into practice. Go easy on me. Criticize my ideas, not me. I think this is ok, as the material is buried in a personal web page on a wiki.&lt;br /&gt;
&lt;br /&gt;
== FlightGear Development: ==&lt;br /&gt;
&lt;br /&gt;
I'm motivated to learn enough C++, Nasal, and whatever else it takes to start regularly contributing to the Flightgear Codebase.  &lt;br /&gt;
&lt;br /&gt;
Someone with practical experience writing, maintaining, and fixing problems in C++ can easily begin contributing to FlightGear's codebase.  They may find a few fine points, such as the internal scripting language and the property tree, but they should be able to navigate with little assistance.  That's not me.  I don't have the practical experience, and my  C++ experience consists mostly of a one-semester class.  Not only that, the class was in the previous century.  Move semantics?  What's That!?&lt;br /&gt;
&lt;br /&gt;
You get the idea:  &amp;quot;Nice goal, Pat.  Good luck with that. You do realize you are 75 years old, don't you?&amp;quot;&lt;br /&gt;
Heedless, I press on.&lt;br /&gt;
&lt;br /&gt;
It should be obvious to all that this endeavour requires a lot of work, and anyone undertaking it is going to need help at various points.  It's easy to get stuck on specific points, and stuck in ways that you don't know which question to ask first, and where to ask it.  You, kind reader, may be able to help.  &lt;br /&gt;
&lt;br /&gt;
== Flightgear - Study Group ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I'm continuing to think about the idea of organizing and participating in a study group for flightgear coding, I want to consider current work on Flightgear proceeding on [http://gitlab.com/flightgear Gitlab] as fodder for study.&lt;br /&gt;
&lt;br /&gt;
The study group idea was prompted by my thinking about the codebase itself and why I found it so difficult to understand.  I'm sure others have at least some of the same challenges if they share my goal of becoming a regular flightgear contributor. If so,  we are likely to find common ground in meeting those challenges.&lt;br /&gt;
&lt;br /&gt;
These points are personal challenges in learning how FlightGear works, writing code and documentation, and debugging. &lt;br /&gt;
&lt;br /&gt;
* Object-oriented programming - Don't get me started.  Based on secondary sources, I agree with Alan Kay's thoughts on messaging as the most important aspect of &amp;quot;object&amp;quot; thinking, which most of us seem to overlook.&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://wiki.c2.com/?AlanKaysDefinitionOfObjectOriented Alan Kays Definition Of Object Oriented]&amp;lt;/ref&amp;gt;  Alan appears to live nearby.  Maybe I'll get up the nerve to ask him personally.  Finally, I am pretty sure I am not &amp;quot;a can of Coke&amp;lt;ref&amp;gt; [http://www.johno.se/book/oops.html OOPs - nasty traps in Object Oriented Programming]&amp;lt;/ref&amp;gt;.&amp;quot;&lt;br /&gt;
* C++,  when I learned C++, the STL was new. New as in &amp;quot;Do you need a container? Please feel free to write an implementation as homework&amp;quot;.  There has been significant progress since then, but I never actually wrote any C++ professionally, so I'm catching up on the changes in C++98, 03, 11, 14, 17, and 20.&lt;br /&gt;
* Specific Aircraft simulations are implemented mostly in XML, AC files, and Nasal, not in C++.&lt;br /&gt;
* Nasal is an interpreted language with separate class structures, memory allocation, and symbol tables, inaccessible to debuggers.&lt;br /&gt;
* The property tree is a global data store used for most intercommunication between subsystems, but it has no concept of messaging or data flow management.  Everything is done with callbacks on individual properties.  It's like watching an ant colony.&lt;br /&gt;
&lt;br /&gt;
None of the above should be taken as a suggestion that FlightGear development take any specific direction in the future.  That will come from me only after I've become a regular and significant contributor of C++, Nasal, and FlightGear data.  Nor should it be taken as criticism of what has been done so far in the 28-year history of the project.&lt;br /&gt;
&lt;br /&gt;
== Getting an Giving Help ==&lt;br /&gt;
I want to request assistance in the appropriate forums, having exhausted all possible avenues to explore answers before seeking help. At the same time I want to help others with any code problems they are struggling with. &lt;br /&gt;
 &lt;br /&gt;
I like helping other people.  It's the best way to make friends. &lt;br /&gt;
&lt;br /&gt;
I want you to know that I sometimes help people by listening to them describe a problem, and suggesting a route to finding some small tidbit of information that makes the problem easier to think about. It doesn't always happen, or even often, but when it does, the result seems very satisfying to both parties.  &lt;br /&gt;
&lt;br /&gt;
There are other times when just having me listen attentively to an explanation of a problem is sufficient for the teller to grasp a solution. I don't have to say a word, but they already have the answer.  Helpful, no?  This has happened to me on numerous occasions, more so than me making helpful comments.  Perhaps my asking for a description of the problem and any naive questions I ask about it are enough to get things moving.&lt;br /&gt;
&lt;br /&gt;
If you're stuck on a point and want my help, please don't hesitate to ask me personally on any forum where you encounter me. &lt;br /&gt;
You can find me on Discord as callahanp, on IRC as pac1 (early internet username formed from my initials)&lt;br /&gt;
&lt;br /&gt;
== Teamwork: ==&lt;br /&gt;
I'm a believer in teamwork and would love working closely in real-time with others on specific programming problems. I hope we can create opportunities for that.  I also believe that the only learning environment is not limited to a formal course, which includes lectures, readings, homework, quizzes, tests, and final grades.  Grown-ups use study groups, working groups, collaborators, publications, conferences, and prior work. And they take formal courses from time to time.&lt;br /&gt;
&lt;br /&gt;
== Pair programming ==&lt;br /&gt;
&lt;br /&gt;
I find pair programming an attractive idea and wonder how it works in practice. What is the result of practicing pair programming with programmers of similar skills? What happens when an expert programmer pairs with an inexperienced one?&lt;br /&gt;
&lt;br /&gt;
I find that most are resistant to participating in pair programming, and I wonder why.  &lt;br /&gt;
&lt;br /&gt;
We're taught in academic settings to program by ourselves and hand in ou submissions for review as &amp;quot;homework&amp;quot;, but we continue that pattern in our work mainly out of inertia and lack of proper training. There's no reason to continue that pattern outside of a classroom as our only or even as main way of working together. &lt;br /&gt;
&lt;br /&gt;
== Understanding FlightGear's Large &amp;amp; Complex Codebase ==&lt;br /&gt;
&lt;br /&gt;
The problem with FlightGear is its size, complexity, and the lack of a detailed guide to exploring that complexity. Several factors contribute to that complexity. Understanding FlightGear requires knowledge of many application domains, C++, an internal scripting language, a global data store, application features driven by XML or scripts, network protocols and data formats, some custom, some obscure, and from the era of mainframe computers.&lt;br /&gt;
&lt;br /&gt;
I'll examine each of these complexity realms with a view to providing a guideline for new FlightGear developers, me for instance, a path to follow leading to regular contributions to the FlightGear in C++, Nasal, and XML and other data formats.&lt;br /&gt;
&lt;br /&gt;
== C++ ==&lt;br /&gt;
&lt;br /&gt;
  First, the application uses C++. As a complex and evolving language, C++ has a reputation for being complex. It's not just the language, its the fragmentation of code into small tidbits, widely scattered in individual files covering supposedly just one aspect of what needs to be done. I don't really know if the structure of C++ code as objects is more efficient than a C++ program done using solid structured programming, but I know which is easier think about and to work on.&lt;br /&gt;
&lt;br /&gt;
== Flight Simulation does a lot of different things == &lt;br /&gt;
&lt;br /&gt;
Second, Flight Simulation involves numerous application domains. Among them are aerodynamics, graphics, geography, geodesy, environment, navigation, networks, audio, video, and human languages. FlightGear addresses all of them and more. Each of these domains has its own view of the world, and many of them are modelled as C++ classes. Full understanding comes from knowing the C++ code, the terminology of the domain, and the way the code's authors chose to structure things as objects and methods.  &lt;br /&gt;
&lt;br /&gt;
== Nasal and the Property Tree ==&lt;br /&gt;
&lt;br /&gt;
Next, in addition to the complexity introduced by C++ and the application domains, there's Nasal. Finally, to tie it all together, loosely, the property tree. a global object, with individual data items of a key-value store actually stored in a tree because they are conceptually related. The property tree introduced complexity because items in it are not &amp;quot;owned&amp;quot;, they're simply created at some point, in either C++, XML processing, or Nasal, and used wherever the data item is &amp;quot;needed&amp;quot;. Connecting the dots through all the code based on identifying individual properties is not all that easy.&lt;br /&gt;
&lt;br /&gt;
== Where should I start? C++, Nasal or XML) ==&lt;br /&gt;
&lt;br /&gt;
It's not clear from existing documentation the central role of Nasal scripting and the Property Tree are in the simulation. It's not just C++, Nasal, and the interface between them, understood as computer languages.   Knowing the languages and interfaces themselves is vital, but even more important is understanding how scripting is used in FlightGear to create the simulation. If you are struggling as a newcomer to understand FlightGear's C++ code, understanding Nasal's role in driving parts of the simulation and the way it interacts with C++ code is probably one of the first things to do. It's what I'll be doing next.&lt;br /&gt;
&lt;br /&gt;
== FlightGear's DataFlow Diagram == &lt;br /&gt;
&lt;br /&gt;
There isn't one. Or rather, there is one, but it's virtual in the sense that no one used it as a design document; rather, it is constructible as a mental model from the observable workings of flightgear itself.`&lt;br /&gt;
&lt;br /&gt;
Part of understanding any body of code is to be able to identify how data flows through the application. Dataflows are usually represented as arrows of various widths. The arrows are messages flowing between parts of an application. The larger the arrow, the more data items in that data flow.  Knowing what is in each of those flows is important to understanding how the application works.  &lt;br /&gt;
&lt;br /&gt;
In FlightGear's C++ code, there are, of course, classes and objects that represent some dataflows. There's a problem, though. Many of the classes are about processing data into ad-hoc structures within the property tree.  How can we define a data flow for these ad-hoc structures?  (Note: need a way to describe two dataflows.  The one that creates the infrastructure as properties in the tree, and a second one implied by the existence of the property.)&lt;br /&gt;
&lt;br /&gt;
There is no C++ class for an Altimeter or a Heading Indicator. Instead, these are represented by a set of properties and data loaded via XML and other formats. The numerical data, stored in the property tree has a path indicating that the properties underneath a node are for the altimeter or the heading indicator. The actual paths in this case are /instrumentation/altimeter and /instrumentation/heading-indicator. Each node in the tree can have properties as child nodes, as well as child nodes that contain additional properties, such as /instrumentation/heading-indicator/gyro.  &lt;br /&gt;
&lt;br /&gt;
Properties are created on the fly, once the property tree's root node is instantiated. Properties are specified in XML data, created by a Nasal script, or by C++ code. The actual property mechanism is implemented in a C++ class.&lt;br /&gt;
&lt;br /&gt;
After they are created, properties are used as needed from Nasal scripts and C++ code, and finally destroyed by a destructor in C++. However, none of that is traceable as a data flow. IDEs are great at connecting elements of code to their definitions and usage, but when we use a data store like the property tree, the connection can't be found by the IDE. These data flows through the property tree mechanisms are a real part of the FlightGear Application, but we have no easy way to visualise them. Any visualization is mentally constructed over time by developers' experiences, as they examine and step through code.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[http://wiki.flightgear.org/User:Callahanp/goals What's up with Pat]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=142033</id>
		<title>User:Callahanp</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=142033"/>
		<updated>2025-06-30T20:07:58Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: /* About Me */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Me ==&lt;br /&gt;
 &lt;br /&gt;
Hello, my name is Patrick Callahan. People call me Pat. I have a website, and you've found it.&lt;br /&gt;
&lt;br /&gt;
I've been a programmer since I was a teenager. I'm 74 years old and retired now. I have signed [https://agilemanifesto.org/the the Agile Manifesto].&lt;br /&gt;
&lt;br /&gt;
Programming was a fun job. We couldn't believe we got paid to have so much fun.&lt;br /&gt;
&lt;br /&gt;
My current expertise primarily lies in databases, bash scripting, and traditional procedural programming in various languages.&lt;br /&gt;
&lt;br /&gt;
C++ is a work in progress. I took a course in 1993, but never used it professionally.  &lt;br /&gt;
&lt;br /&gt;
I like gardening with my wife of 33 years, Ann. We have a daughter who has given us three very active grandchildren, who will visit us next week for four days. Did I say I kept busy? We reside in the state of Massachusetts in the United States.&lt;br /&gt;
&lt;br /&gt;
I hope to make regular code contributions to FlightGear. I want to gain the skills to address some FlightGear issues as they come up and participate in the discussions and programming for the various [FlightGear Epics |https://gitlab.com/groups/flightgear/-/epics?sort=created_date&amp;amp;state=opened&amp;amp;first_page_size=100]&lt;br /&gt;
&lt;br /&gt;
You are about to read a very personal document. I make statements there that I have not yet validated by discussing these ideas directly with others and trying to put them into practice. Go easy on me. Criticize my ideas, not me. I think this is ok, as the material is buried in a personal web page on a wiki.&lt;br /&gt;
&lt;br /&gt;
== FlightGear Development: ==&lt;br /&gt;
&lt;br /&gt;
I'm motivated to learn enough C++, Nasal, and whatever else it takes to start regularly contributing to the Flightgear Codebase.  &lt;br /&gt;
&lt;br /&gt;
Someone with practical experience writing, maintaining, and fixing problems in C++ can easily begin contributing to FlightGear's codebase.  They may find a few fine points, such as the internal scripting language and the property tree, but they should be able to navigate with little assistance.  That's not me.  I don't have the practical experience, and my  C++ experience consists mostly of a one-semester class.  Not only that, the class was in the previous century.  Move semantics?  What's That!?&lt;br /&gt;
&lt;br /&gt;
You get the idea:  &amp;quot;Nice goal, Pat.  Good luck with that. You do realize you are 75 years old, don't you?&amp;quot;&lt;br /&gt;
Heedless, I press on.&lt;br /&gt;
&lt;br /&gt;
It should be obvious to all that this endeavour requires a lot of work, and anyone undertaking it is going to need help at various points.  It's easy to get stuck on specific points, and stuck in ways that you don't know which question to ask first, and where to ask it.  You, kind reader, may be able to help.  &lt;br /&gt;
&lt;br /&gt;
== Flightgear - Study Group ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I'm continuing to think about the idea of organizing and participating in a study group for flightgear coding, I want to consider current work on Flightgear proceeding on [http://gitlab.com/flightgear Gitlab] as fodder for study.&lt;br /&gt;
&lt;br /&gt;
The study group idea was prompted by my thinking about the codebase itself and why I found it so difficult to understand.  I'm sure others have at least some of the same challenges if they share my goal of becoming a regular flightgear contributor. If so,  we are likely to find common ground in meeting those challenges.&lt;br /&gt;
&lt;br /&gt;
These points are personal challenges in learning how FlightGear works, writing code and documentation, and debugging. &lt;br /&gt;
&lt;br /&gt;
* Object-oriented programming - Don't get me started.  Based on secondary sources, I agree with Alan Kay's thoughts on messaging as the most important aspect of &amp;quot;object&amp;quot; thinking, which most of us seem to overlook.&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://wiki.c2.com/?AlanKaysDefinitionOfObjectOriented Alan Kays Definition Of Object Oriented]&amp;lt;/ref&amp;gt;  Alan appears to live nearby.  Maybe I'll get up the nerve to ask him personally.  Finally, I am pretty sure I am not &amp;quot;a can of Coke&amp;lt;ref&amp;gt; [http://www.johno.se/book/oops.html OOPs - nasty traps in Object Oriented Programming]&amp;lt;/ref&amp;gt;.&amp;quot;&lt;br /&gt;
* C++,  when I learned C++, the STL was new. New as in &amp;quot;Do you need a container? Please feel free to write an implementation as homework&amp;quot;.  There has been significant progress since then, but I never actually wrote any C++ professionally, so I'm catching up on the changes in C++98, 03, 11, 14, 17, and 20.&lt;br /&gt;
* Specific Aircraft simulations are implemented mostly in XML, AC files, and Nasal, not in C++.&lt;br /&gt;
* Nasal is an interpreted language with separate class structures, memory allocation, and symbol tables, inaccessible to debuggers.&lt;br /&gt;
* The property tree is a global data store used for most intercommunication between subsystems, but it has no concept of messaging or data flow management.  Everything is done with callbacks on individual properties.  It's like watching an ant colony.&lt;br /&gt;
&lt;br /&gt;
None of the above should be taken as a suggestion that FlightGear development take any specific direction in the future.  That will come from me only after I've become a regular and significant contributor of C++, Nasal, and FlightGear data.  Nor should it be taken as criticism of what has been done so far in the 28-year history of the project.&lt;br /&gt;
&lt;br /&gt;
== Getting an Giving Help ==&lt;br /&gt;
I want to request assistance in the appropriate forums, having exhausted all possible avenues to explore answers before seeking help. At the same time I want to help others with any code problems they are struggling with. &lt;br /&gt;
 &lt;br /&gt;
I like helping other people.  It's the best way to make friends. &lt;br /&gt;
&lt;br /&gt;
I want you to know that I sometimes help people by listening to them describe a problem, and suggesting a route to finding some small tidbit of information that makes the problem easier to think about. It doesn't always happen, or even often, but when it does, the result seems very satisfying to both parties.  &lt;br /&gt;
&lt;br /&gt;
There are other times when just having me listen attentively to an explanation of a problem is sufficient for the teller to grasp a solution. I don't have to say a word, but they already have the answer.  Helpful, no?  This has happened to me on numerous occasions, more so than me making helpful comments.  Perhaps my asking for a description of the problem and any naive questions I ask about it are enough to get things moving.&lt;br /&gt;
&lt;br /&gt;
If you're stuck on a point and want my help, please don't hesitate to ask me personally on any forum where you encounter me. &lt;br /&gt;
You can find me on Discord as callahanp, on IRC as pac1 (early internet username formed from my initials)&lt;br /&gt;
&lt;br /&gt;
== Teamwork: ==&lt;br /&gt;
I'm a believer in teamwork and would love working closely in real-time with others on specific programming problems. I hope we can create opportunities for that.  I also believe that the only learning environment is not limited to a formal course, which includes lectures, readings, homework, quizzes, tests, and final grades.  Grown-ups use study groups, working groups, collaborators, publications, conferences, and prior work. And they take formal courses from time to time.&lt;br /&gt;
&lt;br /&gt;
== Pair programming ==&lt;br /&gt;
&lt;br /&gt;
I find pair programming an attractive idea and wonder how it works in practice. What is the result of practicing pair programming with programmers of similar skills? What happens when an expert programmer pairs with an inexperienced one?&lt;br /&gt;
&lt;br /&gt;
I find that most are resistant to participating in pair programming, and I wonder why.  &lt;br /&gt;
&lt;br /&gt;
We're taught in academic settings to program by ourselves and hand in ou submissions for review as &amp;quot;homework&amp;quot;, but we continue that pattern in our work mainly out of inertia and lack of proper training. There's no reason to continue that pattern outside of a classroom as our only or even as main way of working together. &lt;br /&gt;
&lt;br /&gt;
== Understanding FlightGear's Large &amp;amp; Complex Codebase ==&lt;br /&gt;
&lt;br /&gt;
The problem with FlightGear is its size, complexity, and the lack of a detailed guide to exploring that complexity. Several factors contribute to that complexity. Understanding FlightGear requires knowledge of many application domains, C++, an internal scripting language, a global data store, application features driven by XML or scripts, network protocols and data formats, some custom, some obscure, and from the era of mainframe computers.&lt;br /&gt;
&lt;br /&gt;
I'll examine each of these complexity realms with a view to providing a guideline for new FlightGear developers, me for instance, a path to follow leading to regular contributions to the FlightGear in C++, Nasal, and XML and other data formats.&lt;br /&gt;
&lt;br /&gt;
== C++ ==&lt;br /&gt;
&lt;br /&gt;
  First, the application uses C++. As a complex and evolving language, C++ has a reputation for being complex. It's not just the language, its the fragmentation of code into small tidbits, widely scattered in individual files covering supposedly just one aspect of what needs to be done. I don't really know if the structure of C++ code as objects is more efficient than a C++ program done using solid structured programming, but I know which is easier think about and to work on.&lt;br /&gt;
&lt;br /&gt;
== Flight Simulation does a lot of different things == &lt;br /&gt;
&lt;br /&gt;
Second, Flight Simulation involves numerous application domains. Among them are aerodynamics, graphics, geography, geodesy, environment, navigation, networks, audio, video, and human languages. FlightGear addresses all of them and more. Each of these domains has its own view of the world, and many of them are modelled as C++ classes. Full understanding comes from knowing the C++ code, the terminology of the domain, and the way the code's authors chose to structure things as objects and methods.  &lt;br /&gt;
&lt;br /&gt;
== Nasal and the Property Tree ==&lt;br /&gt;
&lt;br /&gt;
Next, in addition to the complexity introduced by C++ and the application domains, there's Nasal. Finally, to tie it all together, loosely, the property tree. a global object, with individual data items of a key-value store actually stored in a tree because they are conceptually related. The property tree introduced complexity because items in it are not &amp;quot;owned&amp;quot;, they're simply created at some point, in either C++, XML processing, or Nasal, and used wherever the data item is &amp;quot;needed&amp;quot;. Connecting the dots through all the code based on identifying individual properties is not all that easy.&lt;br /&gt;
&lt;br /&gt;
== Where should I start? C++, Nasal or XML) ==&lt;br /&gt;
&lt;br /&gt;
It's not clear from existing documentation the central role of Nasal scripting and the Property Tree are in the simulation. It's not just C++, Nasal, and the interface between them, understood as computer languages.   Knowing the languages and interfaces themselves is vital, but even more important is understanding how scripting is used in FlightGear to create the simulation. If you are struggling as a newcomer to understand FlightGear's C++ code, understanding Nasal's role in driving parts of the simulation and the way it interacts with C++ code is probably one of the first things to do. It's what I'll be doing next.&lt;br /&gt;
&lt;br /&gt;
== FlightGear's DataFlow Diagram == &lt;br /&gt;
&lt;br /&gt;
There isn't one. Or rather, there is one, but it's virtual in the sense that no one used it as a design document; rather, it is constructible as a mental model from the observable workings of flightgear itself.`&lt;br /&gt;
&lt;br /&gt;
Part of understanding any body of code is to be able to identify how data flows through the application. Dataflows are usually represented as arrows of various widths. The arrows are messages flowing between parts of an application. The larger the arrow, the more data items in that data flow.  Knowing what is in each of those flows is important to understanding how the application works.  &lt;br /&gt;
&lt;br /&gt;
In FlightGear's C++ code, there are, of course, classes and objects that represent some dataflows. There's a problem, though. Many of the classes are about processing data into ad-hoc structures within the property tree.  How can we define a data flow for these ad-hoc structures?  (Note: need a way to describe two dataflows.  The one that creates the infrastructure as properties in the tree, and a second one implied by the existence of the property.)&lt;br /&gt;
&lt;br /&gt;
There is no C++ class for an Altimeter or a Heading Indicator. Instead, these are represented by a set of properties and data loaded via XML and other formats. The numerical data, stored in the property tree has a path indicating that the properties underneath a node are for the altimeter or the heading indicator. The actual paths in this case are /instrumentation/altimeter and /instrumentation/heading-indicator. Each node in the tree can have properties as child nodes, as well as child nodes that contain additional properties, such as /instrumentation/heading-indicator/gyro. Usually, only the lear nodes of th e tree &lt;br /&gt;
&lt;br /&gt;
Properties are created on the fly, once the property tree's root node is instantiated. Properties are specified in XML data, created by a Nasal script, or by C++ code. The actual property mechanism is implemented in a C++ class.&lt;br /&gt;
&lt;br /&gt;
After they are created, properties are used as needed from Nasal scripts and C++ code, and finally destroyed by a destructor in C++. However, none of that is traceable as a data flow. IDEs are great at connecting elements of code to their definitions and usage, but when we use a data store like the property tree, the connection can't be found by the IDE. These data flows through the property tree mechanisms are a real part of the FlightGear Application, but we have no easy way to visualise them. Any visualization is mentally constructed over time by developers' experiences, as they examine and step through code.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[http://wiki.flightgear.org/User:Callahanp/goals What's up with Pat]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=142032</id>
		<title>User:Callahanp</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=142032"/>
		<updated>2025-06-30T20:05:48Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Me ==&lt;br /&gt;
 &lt;br /&gt;
Hello, my name is Patrick Callahan. People call me Pat. I have a web page, and you found it.&lt;br /&gt;
&lt;br /&gt;
I've been a programmer since I was a teenager. I'm 74 years old and retired now.  I have signed [https://agilemanifesto.org/&amp;lt;nowiki&amp;gt; the Agile Manifesto].&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Programming was a fun job. We couldn't believe we got paid to have so much fun.&lt;br /&gt;
&lt;br /&gt;
My current expertise primarily lies in databases, bash scripting, and traditional procedural programming in various languages.&lt;br /&gt;
&lt;br /&gt;
C++ is a work in progress. I took a course in 1993, but never used it professionally.  &lt;br /&gt;
&lt;br /&gt;
I like gardening with my wife of 33 years, Ann. We have a daughter who has given us three very active grandchildren, who will visit us next week for four days. Did I say I kept busy? We reside in the state of Massachusetts in the United States.&lt;br /&gt;
&lt;br /&gt;
I hope to make regular code contributions to FlightGear. I want to gain the skills to address some FlightGear issues as they come up and participate in the discussions and programming for the various [FlightGear Epics |https://gitlab.com/groups/flightgear/-/epics?sort=created_date&amp;amp;state=opened&amp;amp;first_page_size=100]&lt;br /&gt;
&lt;br /&gt;
You are about to read a very personal document.  I make statements there that I have not yet validated by discussing these ideas directly with others and trying to put them into practice.  Go easy on me.  Criticize my ideas, not me.  I think this is ok, as the material is buried in a personal web page on a wiki.&lt;br /&gt;
&lt;br /&gt;
== FlightGear Development: ==&lt;br /&gt;
&lt;br /&gt;
I'm motivated to learn enough C++, Nasal, and whatever else it takes to start regularly contributing to the Flightgear Codebase.  &lt;br /&gt;
&lt;br /&gt;
Someone with practical experience writing, maintaining, and fixing problems in C++ can easily begin contributing to FlightGear's codebase.  They may find a few fine points, such as the internal scripting language and the property tree, but they should be able to navigate with little assistance.  That's not me.  I don't have the practical experience, and my  C++ experience consists mostly of a one-semester class.  Not only that, the class was in the previous century.  Move semantics?  What's That!?&lt;br /&gt;
&lt;br /&gt;
You get the idea:  &amp;quot;Nice goal, Pat.  Good luck with that. You do realize you are 75 years old, don't you?&amp;quot;&lt;br /&gt;
Heedless, I press on.&lt;br /&gt;
&lt;br /&gt;
It should be obvious to all that this endeavour requires a lot of work, and anyone undertaking it is going to need help at various points.  It's easy to get stuck on specific points, and stuck in ways that you don't know which question to ask first, and where to ask it.  You, kind reader, may be able to help.  &lt;br /&gt;
&lt;br /&gt;
== Flightgear - Study Group ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I'm continuing to think about the idea of organizing and participating in a study group for flightgear coding, I want to consider current work on Flightgear proceeding on [http://gitlab.com/flightgear Gitlab] as fodder for study.&lt;br /&gt;
&lt;br /&gt;
The study group idea was prompted by my thinking about the codebase itself and why I found it so difficult to understand.  I'm sure others have at least some of the same challenges if they share my goal of becoming a regular flightgear contributor. If so,  we are likely to find common ground in meeting those challenges.&lt;br /&gt;
&lt;br /&gt;
These points are personal challenges in learning how FlightGear works, writing code and documentation, and debugging. &lt;br /&gt;
&lt;br /&gt;
* Object-oriented programming - Don't get me started.  Based on secondary sources, I agree with Alan Kay's thoughts on messaging as the most important aspect of &amp;quot;object&amp;quot; thinking, which most of us seem to overlook.&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://wiki.c2.com/?AlanKaysDefinitionOfObjectOriented Alan Kays Definition Of Object Oriented]&amp;lt;/ref&amp;gt;  Alan appears to live nearby.  Maybe I'll get up the nerve to ask him personally.  Finally, I am pretty sure I am not &amp;quot;a can of Coke&amp;lt;ref&amp;gt; [http://www.johno.se/book/oops.html OOPs - nasty traps in Object Oriented Programming]&amp;lt;/ref&amp;gt;.&amp;quot;&lt;br /&gt;
* C++,  when I learned C++, the STL was new. New as in &amp;quot;Do you need a container? Please feel free to write an implementation as homework&amp;quot;.  There has been significant progress since then, but I never actually wrote any C++ professionally, so I'm catching up on the changes in C++98, 03, 11, 14, 17, and 20.&lt;br /&gt;
* Specific Aircraft simulations are implemented mostly in XML, AC files, and Nasal, not in C++.&lt;br /&gt;
* Nasal is an interpreted language with separate class structures, memory allocation, and symbol tables, inaccessible to debuggers.&lt;br /&gt;
* The property tree is a global data store used for most intercommunication between subsystems, but it has no concept of messaging or data flow management.  Everything is done with callbacks on individual properties.  It's like watching an ant colony.&lt;br /&gt;
&lt;br /&gt;
None of the above should be taken as a suggestion that FlightGear development take any specific direction in the future.  That will come from me only after I've become a regular and significant contributor of C++, Nasal, and FlightGear data.  Nor should it be taken as criticism of what has been done so far in the 28-year history of the project.&lt;br /&gt;
&lt;br /&gt;
== Getting an Giving Help ==&lt;br /&gt;
I want to request assistance in the appropriate forums, having exhausted all possible avenues to explore answers before seeking help. At the same time I want to help others with any code problems they are struggling with. &lt;br /&gt;
 &lt;br /&gt;
I like helping other people.  It's the best way to make friends. &lt;br /&gt;
&lt;br /&gt;
I want you to know that I sometimes help people by listening to them describe a problem, and suggesting a route to finding some small tidbit of information that makes the problem easier to think about. It doesn't always happen, or even often, but when it does, the result seems very satisfying to both parties.  &lt;br /&gt;
&lt;br /&gt;
There are other times when just having me listen attentively to an explanation of a problem is sufficient for the teller to grasp a solution. I don't have to say a word, but they already have the answer.  Helpful, no?  This has happened to me on numerous occasions, more so than me making helpful comments.  Perhaps my asking for a description of the problem and any naive questions I ask about it are enough to get things moving.&lt;br /&gt;
&lt;br /&gt;
If you're stuck on a point and want my help, please don't hesitate to ask me personally on any forum where you encounter me. &lt;br /&gt;
You can find me on Discord as callahanp, on IRC as pac1 (early internet username formed from my initials)&lt;br /&gt;
&lt;br /&gt;
== Teamwork: ==&lt;br /&gt;
I'm a believer in teamwork and would love working closely in real-time with others on specific programming problems. I hope we can create opportunities for that.  I also believe that the only learning environment is not limited to a formal course, which includes lectures, readings, homework, quizzes, tests, and final grades.  Grown-ups use study groups, working groups, collaborators, publications, conferences, and prior work. And they take formal courses from time to time.&lt;br /&gt;
&lt;br /&gt;
== Pair programming ==&lt;br /&gt;
&lt;br /&gt;
I find pair programming an attractive idea and wonder how it works in practice. What is the result of practicing pair programming with programmers of similar skills? What happens when an expert programmer pairs with an inexperienced one?&lt;br /&gt;
&lt;br /&gt;
I find that most are resistant to participating in pair programming, and I wonder why.  &lt;br /&gt;
&lt;br /&gt;
We're taught in academic settings to program by ourselves and hand in ou submissions for review as &amp;quot;homework&amp;quot;, but we continue that pattern in our work mainly out of inertia and lack of proper training. There's no reason to continue that pattern outside of a classroom as our only or even as main way of working together. &lt;br /&gt;
&lt;br /&gt;
== Understanding FlightGear's Large &amp;amp; Complex Codebase ==&lt;br /&gt;
&lt;br /&gt;
The problem with FlightGear is its size, complexity, and the lack of a detailed guide to exploring that complexity. Several factors contribute to that complexity. Understanding FlightGear requires knowledge of many application domains, C++, an internal scripting language, a global data store, application features driven by XML or scripts, network protocols and data formats, some custom, some obscure, and from the era of mainframe computers.&lt;br /&gt;
&lt;br /&gt;
I'll examine each of these complexity realms with a view to providing a guideline for new FlightGear developers, me for instance, a path to follow leading to regular contributions to the FlightGear in C++, Nasal, and XML and other data formats.&lt;br /&gt;
&lt;br /&gt;
== C++ ==&lt;br /&gt;
&lt;br /&gt;
  First, the application uses C++. As a complex and evolving language, C++ has a reputation for being complex. It's not just the language, its the fragmentation of code into small tidbits, widely scattered in individual files covering supposedly just one aspect of what needs to be done. I don't really know if the structure of C++ code as objects is more efficient than a C++ program done using solid structured programming, but I know which is easier think about and to work on.&lt;br /&gt;
&lt;br /&gt;
== Flight Simulation does a lot of different things == &lt;br /&gt;
&lt;br /&gt;
Second, Flight Simulation involves numerous application domains. Among them are aerodynamics, graphics, geography, geodesy, environment, navigation, networks, audio, video, and human languages. FlightGear addresses all of them and more. Each of these domains has its own view of the world, and many of them are modelled as C++ classes. Full understanding comes from knowing the C++ code, the terminology of the domain, and the way the code's authors chose to structure things as objects and methods.  &lt;br /&gt;
&lt;br /&gt;
== Nasal and the Property Tree ==&lt;br /&gt;
&lt;br /&gt;
Next, in addition to the complexity introduced by C++ and the application domains, there's Nasal. Finally, to tie it all together, loosely, the property tree. a global object, with individual data items of a key-value store actually stored in a tree because they are conceptually related. The property tree introduced complexity because items in it are not &amp;quot;owned&amp;quot;, they're simply created at some point, in either C++, XML processing, or Nasal, and used wherever the data item is &amp;quot;needed&amp;quot;. Connecting the dots through all the code based on identifying individual properties is not all that easy.&lt;br /&gt;
&lt;br /&gt;
== Where should I start? C++, Nasal or XML) ==&lt;br /&gt;
&lt;br /&gt;
It's not clear from existing documentation the central role of Nasal scripting and the Property Tree are in the simulation. It's not just C++, Nasal, and the interface between them, understood as computer languages.   Knowing the languages and interfaces themselves is vital, but even more important is understanding how scripting is used in FlightGear to create the simulation. If you are struggling as a newcomer to understand FlightGear's C++ code, understanding Nasal's role in driving parts of the simulation and the way it interacts with C++ code is probably one of the first things to do. It's what I'll be doing next.&lt;br /&gt;
&lt;br /&gt;
== FlightGear's DataFlow Diagram == &lt;br /&gt;
&lt;br /&gt;
There isn't one. Or rather, there is one, but it's virtual in the sense that no one used it as a design document; rather, it is constructible as a mental model from the observable workings of flightgear itself.`&lt;br /&gt;
&lt;br /&gt;
Part of understanding any body of code is to be able to identify how data flows through the application. Dataflows are usually represented as arrows of various widths. The arrows are messages flowing between parts of an application. The larger the arrow, the more data items in that data flow.  Knowing what is in each of those flows is important to understanding how the application works.  &lt;br /&gt;
&lt;br /&gt;
In FlightGear's C++ code, there are, of course, classes and objects that represent some dataflows. There's a problem, though. Many of the classes are about processing data into ad-hoc structures within the property tree.  How can we define a data flow for these ad-hoc structures?  (Note: need a way to describe two dataflows.  The one that creates the infrastructure as properties in the tree, and a second one implied by the existence of the property.)&lt;br /&gt;
&lt;br /&gt;
There is no C++ class for an Altimeter or a Heading Indicator. Instead, these are represented by a set of properties and data loaded via XML and other formats. The numerical data, stored in the property tree has a path indicating that the properties underneath a node are for the altimeter or the heading indicator. The actual paths in this case are /instrumentation/altimeter and /instrumentation/heading-indicator. Each node in the tree can have properties as child nodes, as well as child nodes that contain additional properties, such as /instrumentation/heading-indicator/gyro. Usually, only the lear nodes of th e tree &lt;br /&gt;
&lt;br /&gt;
Properties are created on the fly, once the property tree's root node is instantiated. Properties are specified in XML data, created by a Nasal script, or by C++ code. The actual property mechanism is implemented in a C++ class.&lt;br /&gt;
&lt;br /&gt;
After they are created, properties are used as needed from Nasal scripts and C++ code, and finally destroyed by a destructor in C++. However, none of that is traceable as a data flow. IDEs are great at connecting elements of code to their definitions and usage, but when we use a data store like the property tree, the connection can't be found by the IDE. These data flows through the property tree mechanisms are a real part of the FlightGear Application, but we have no easy way to visualise them. Any visualization is mentally constructed over time by developers' experiences, as they examine and step through code.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[http://wiki.flightgear.org/User:Callahanp/goals What's up with Pat]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=142031</id>
		<title>User:Callahanp</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=142031"/>
		<updated>2025-06-30T20:03:03Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: /* About Me */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Me ==&lt;br /&gt;
 &lt;br /&gt;
Hello, my name is Patrick Callahan. People call me Pat. I have a web page, and you found it.&lt;br /&gt;
&lt;br /&gt;
I've been a programmer since I was a teenager. I'm 74 years old and retired now.  I have signed the Agile Manifesto.&lt;br /&gt;
&lt;br /&gt;
Programming was a fun job. We couldn't believe we got paid to have so much fun.&lt;br /&gt;
&lt;br /&gt;
My current expertise primarily lies in databases, bash scripting, and traditional procedural programming in various languages.&lt;br /&gt;
&lt;br /&gt;
C++ is a work in progress. I took a course in 1993, but never used it professionally.  &lt;br /&gt;
&lt;br /&gt;
I like gardening with my wife of 33 years, Ann. We have a daughter who has given us three very active grandchildren, who will visit us next week for four days. Did I say I kept busy? We reside in the state of Massachusetts in the United States.&lt;br /&gt;
&lt;br /&gt;
I hope to make regular code contributions to FlightGear. I want to gain the skills to address some FlightGear issues as they come up and participate in the discussions and programming for the various [FlightGear Epics |https://gitlab.com/groups/flightgear/-/epics?sort=created_date&amp;amp;state=opened&amp;amp;first_page_size=100]&lt;br /&gt;
&lt;br /&gt;
You are about to read a very personal document.  I make statements there that I have not yet validated by discussing these ideas directly with others and trying to put them into practice.  Go easy on me.  Criticize my ideas, not me.  I think this is ok, as the material is buried in a personal web page on a wiki.&lt;br /&gt;
&lt;br /&gt;
== FlightGear Development: ==&lt;br /&gt;
&lt;br /&gt;
I'm motivated to learn enough C++, Nasal, and whatever else it takes to start regularly contributing to the Flightgear Codebase.  &lt;br /&gt;
&lt;br /&gt;
Someone with practical experience writing, maintaining, and fixing problems in C++ can easily begin contributing to FlightGear's codebase.  They may find a few fine points, such as the internal scripting language and the property tree, but they should be able to navigate with little assistance.  That's not me.  I don't have the practical experience, and my  C++ experience consists mostly of a one-semester class.  Not only that, the class was in the previous century.  Move semantics?  What's That!?&lt;br /&gt;
&lt;br /&gt;
You get the idea:  &amp;quot;Nice goal, Pat.  Good luck with that. You do realize you are 75 years old, don't you?&amp;quot;&lt;br /&gt;
Heedless, I press on.&lt;br /&gt;
&lt;br /&gt;
It should be obvious to all that this endeavour requires a lot of work, and anyone undertaking it is going to need help at various points.  It's easy to get stuck on specific points, and stuck in ways that you don't know which question to ask first, and where to ask it.  You, kind reader, may be able to help.  &lt;br /&gt;
&lt;br /&gt;
== Flightgear - Study Group ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I'm continuing to think about the idea of organizing and participating in a study group for flightgear coding, I want to consider current work on Flightgear proceeding on [http://gitlab.com/flightgear Gitlab] as fodder for study.&lt;br /&gt;
&lt;br /&gt;
The study group idea was prompted by my thinking about the codebase itself and why I found it so difficult to understand.  I'm sure others have at least some of the same challenges if they share my goal of becoming a regular flightgear contributor. If so,  we are likely to find common ground in meeting those challenges.&lt;br /&gt;
&lt;br /&gt;
These points are personal challenges in learning how FlightGear works, writing code and documentation, and debugging. &lt;br /&gt;
&lt;br /&gt;
* Object-oriented programming - Don't get me started.  Based on secondary sources, I agree with Alan Kay's thoughts on messaging as the most important aspect of &amp;quot;object&amp;quot; thinking, which most of us seem to overlook.&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://wiki.c2.com/?AlanKaysDefinitionOfObjectOriented Alan Kays Definition Of Object Oriented]&amp;lt;/ref&amp;gt;  Alan appears to live nearby.  Maybe I'll get up the nerve to ask him personally.  Finally, I am pretty sure I am not &amp;quot;a can of Coke&amp;lt;ref&amp;gt; [http://www.johno.se/book/oops.html OOPs - nasty traps in Object Oriented Programming]&amp;lt;/ref&amp;gt;.&amp;quot;&lt;br /&gt;
* C++,  when I learned C++, the STL was new. New as in &amp;quot;Do you need a container? Please feel free to write an implementation as homework&amp;quot;.  There has been significant progress since then, but I never actually wrote any C++ professionally, so I'm catching up on the changes in C++98, 03, 11, 14, 17, and 20.&lt;br /&gt;
* Specific Aircraft simulations are implemented mostly in XML, AC files, and Nasal, not in C++.&lt;br /&gt;
* Nasal is an interpreted language with separate class structures, memory allocation, and symbol tables, inaccessible to debuggers.&lt;br /&gt;
* The property tree is a global data store used for most intercommunication between subsystems, but it has no concept of messaging or data flow management.  Everything is done with callbacks on individual properties.  It's like watching an ant colony.&lt;br /&gt;
&lt;br /&gt;
None of the above should be taken as a suggestion that FlightGear development take any specific direction in the future.  That will come from me only after I've become a regular and significant contributor of C++, Nasal, and FlightGear data.  Nor should it be taken as criticism of what has been done so far in the 28-year history of the project.&lt;br /&gt;
&lt;br /&gt;
== Getting an Giving Help ==&lt;br /&gt;
I want to request assistance in the appropriate forums, having exhausted all possible avenues to explore answers before seeking help. At the same time I want to help others with any code problems they are struggling with. &lt;br /&gt;
 &lt;br /&gt;
I like helping other people.  It's the best way to make friends. &lt;br /&gt;
&lt;br /&gt;
I want you to know that I sometimes help people by listening to them describe a problem, and suggesting a route to finding some small tidbit of information that makes the problem easier to think about. It doesn't always happen, or even often, but when it does, the result seems very satisfying to both parties.  &lt;br /&gt;
&lt;br /&gt;
There are other times when just having me listen attentively to an explanation of a problem is sufficient for the teller to grasp a solution. I don't have to say a word, but they already have the answer.  Helpful, no?  This has happened to me on numerous occasions, more so than me making helpful comments.  Perhaps my asking for a description of the problem and any naive questions I ask about it are enough to get things moving.&lt;br /&gt;
&lt;br /&gt;
If you're stuck on a point and want my help, please don't hesitate to ask me personally on any forum where you encounter me. &lt;br /&gt;
You can find me on Discord as callahanp, on IRC as pac1 (early internet username formed from my initials)&lt;br /&gt;
&lt;br /&gt;
== Teamwork: ==&lt;br /&gt;
I'm a believer in teamwork and would love working closely in real-time with others on specific programming problems. I hope we can create opportunities for that.  I also believe that the only learning environment is not limited to a formal course, which includes lectures, readings, homework, quizzes, tests, and final grades.  Grown-ups use study groups, working groups, collaborators, publications, conferences, and prior work. And they take formal courses from time to time.&lt;br /&gt;
&lt;br /&gt;
== Pair programming ==&lt;br /&gt;
&lt;br /&gt;
I find pair programming an attractive idea and wonder how it works in practice. What is the result of practicing pair programming with programmers of similar skills? What happens when an expert programmer pairs with an inexperienced one?&lt;br /&gt;
&lt;br /&gt;
I find that most are resistant to participating in pair programming, and I wonder why.  &lt;br /&gt;
&lt;br /&gt;
We're taught in academic settings to program by ourselves and hand in ou submissions for review as &amp;quot;homework&amp;quot;, but we continue that pattern in our work mainly out of inertia and lack of proper training. There's no reason to continue that pattern outside of a classroom as our only or even as main way of working together. &lt;br /&gt;
&lt;br /&gt;
== Understanding FlightGear's Large &amp;amp; Complex Codebase ==&lt;br /&gt;
&lt;br /&gt;
The problem with FlightGear is its size, complexity, and the lack of a detailed guide to exploring that complexity. Several factors contribute to that complexity. Understanding FlightGear requires knowledge of many application domains, C++, an internal scripting language, a global data store, application features driven by XML or scripts, network protocols and data formats, some custom, some obscure, and from the era of mainframe computers.&lt;br /&gt;
&lt;br /&gt;
I'll examine each of these complexity realms with a view to providing a guideline for new FlightGear developers, me for instance, a path to follow leading to regular contributions to the FlightGear in C++, Nasal, and XML and other data formats.&lt;br /&gt;
&lt;br /&gt;
== C++ ==&lt;br /&gt;
&lt;br /&gt;
  First, the application uses C++. As a complex and evolving language, C++ has a reputation for being complex. It's not just the language, its the fragmentation of code into small tidbits, widely scattered in individual files covering supposedly just one aspect of what needs to be done. I don't really know if the structure of C++ code as objects is more efficient than a C++ program done using solid structured programming, but I know which is easier think about and to work on.&lt;br /&gt;
&lt;br /&gt;
== Flight Simulation does a lot of different things == &lt;br /&gt;
&lt;br /&gt;
Second, Flight Simulation involves numerous application domains. Among them are aerodynamics, graphics, geography, geodesy, environment, navigation, networks, audio, video, and human languages. FlightGear addresses all of them and more. Each of these domains has its own view of the world, and many of them are modelled as C++ classes. Full understanding comes from knowing the C++ code, the terminology of the domain, and the way the code's authors chose to structure things as objects and methods.  &lt;br /&gt;
&lt;br /&gt;
== Nasal and the Property Tree ==&lt;br /&gt;
&lt;br /&gt;
Next, in addition to the complexity introduced by C++ and the application domains, there's Nasal. Finally, to tie it all together, loosely, the property tree. a global object, with individual data items of a key-value store actually stored in a tree because they are conceptually related. The property tree introduced complexity because items in it are not &amp;quot;owned&amp;quot;, they're simply created at some point, in either C++, XML processing, or Nasal, and used wherever the data item is &amp;quot;needed&amp;quot;. Connecting the dots through all the code based on identifying individual properties is not all that easy.&lt;br /&gt;
&lt;br /&gt;
== Where should I start? C++, Nasal or XML) ==&lt;br /&gt;
&lt;br /&gt;
It's not clear from existing documentation the central role of Nasal scripting and the Property Tree are in the simulation. It's not just C++, Nasal, and the interface between them, understood as computer languages.   Knowing the languages and interfaces themselves is vital, but even more important is understanding how scripting is used in FlightGear to create the simulation. If you are struggling as a newcomer to understand FlightGear's C++ code, understanding Nasal's role in driving parts of the simulation and the way it interacts with C++ code is probably one of the first things to do. It's what I'll be doing next.&lt;br /&gt;
&lt;br /&gt;
== FlightGear's DataFlow Diagram == &lt;br /&gt;
&lt;br /&gt;
There isn't one. Or rather, there is one, but it's virtual in the sense that no one used it as a design document; rather, it is constructible as a mental model from the observable workings of flightgear itself.`&lt;br /&gt;
&lt;br /&gt;
Part of understanding any body of code is to be able to identify how data flows through the application. Dataflows are usually represented as arrows of various widths. The arrows are messages flowing between parts of an application. The larger the arrow, the more data items in that data flow.  Knowing what is in each of those flows is important to understanding how the application works.  &lt;br /&gt;
&lt;br /&gt;
In FlightGear's C++ code, there are, of course, classes and objects that represent some dataflows. There's a problem, though. Many of the classes are about processing data into ad-hoc structures within the property tree.  How can we define a data flow for these ad-hoc structures?  (Note: need a way to describe two dataflows.  The one that creates the infrastructure as properties in the tree, and a second one implied by the existence of the property.)&lt;br /&gt;
&lt;br /&gt;
There is no C++ class for an Altimeter or a Heading Indicator. Instead, these are represented by a set of properties and data loaded via XML and other formats. The numerical data, stored in the property tree has a path indicating that the properties underneath a node are for the altimeter or the heading indicator. The actual paths in this case are /instrumentation/altimeter and /instrumentation/heading-indicator. Each node in the tree can have properties as child nodes, as well as child nodes that contain additional properties, such as /instrumentation/heading-indicator/gyro. Usually, only the lear nodes of th e tree &lt;br /&gt;
&lt;br /&gt;
Properties are created on the fly, once the property tree's root node is instantiated. Properties are specified in XML data, created by a Nasal script, or by C++ code. The actual property mechanism is implemented in a C++ class.&lt;br /&gt;
&lt;br /&gt;
After they are created, properties are used as needed from Nasal scripts and C++ code, and finally destroyed by a destructor in C++. However, none of that is traceable as a data flow. IDEs are great at connecting elements of code to their definitions and usage, but when we use a data store like the property tree, the connection can't be found by the IDE. These data flows through the property tree mechanisms are a real part of the FlightGear Application, but we have no easy way to visualise them. Any visualization is mentally constructed over time by developers' experiences, as they examine and step through code.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[http://wiki.flightgear.org/User:Callahanp/goals What's up with Pat]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=142028</id>
		<title>User:Callahanp</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=142028"/>
		<updated>2025-06-30T16:05:57Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: /* Flightgear - Study Group */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Me ==&lt;br /&gt;
 &lt;br /&gt;
Hello, my name is Patrick Callahan. People call me Pat. I have a web page, and you found it.&lt;br /&gt;
&lt;br /&gt;
I've been a programmer since I was a teenager. I'm 74 years old and retired now.&lt;br /&gt;
&lt;br /&gt;
Programming was a fun job. We couldn't believe we got paid to have so much fun.&lt;br /&gt;
&lt;br /&gt;
My current expertise primarily lies in databases, bash scripting, and traditional procedural programming in various languages.&lt;br /&gt;
&lt;br /&gt;
C++ is a work in progress. I took a course in 1993, but never used it professionally.  &lt;br /&gt;
&lt;br /&gt;
I like gardening with my wife of 33 years, Ann. We have a daughter who has given us three very active grandchildren, who will visit us next week for four days. Did I say I kept busy? We reside in the state of Massachusetts in the United States.&lt;br /&gt;
&lt;br /&gt;
I hope to make regular code contributions to FlightGear. I want to gain the skills to address some FlightGear issues as they come up and participate in the discussions and programming for the various [FlightGear Epics |https://gitlab.com/groups/flightgear/-/epics?sort=created_date&amp;amp;state=opened&amp;amp;first_page_size=100]&lt;br /&gt;
&lt;br /&gt;
You are about to read a very personal document.  I make statements there that I have not yet validated by discussing these ideas directly with others and trying to put them into practice.  Go easy on me.  Criticize my ideas, not me.  I think this is ok, as the material is buried in a personal web page on a wiki.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
== FlightGear Development: ==&lt;br /&gt;
&lt;br /&gt;
I'm motivated to learn enough C++, Nasal, and whatever else it takes to start regularly contributing to the Flightgear Codebase.  &lt;br /&gt;
&lt;br /&gt;
Someone with practical experience writing, maintaining, and fixing problems in C++ can easily begin contributing to FlightGear's codebase.  They may find a few fine points, such as the internal scripting language and the property tree, but they should be able to navigate with little assistance.  That's not me.  I don't have the practical experience, and my  C++ experience consists mostly of a one-semester class.  Not only that, the class was in the previous century.  Move semantics?  What's That!?&lt;br /&gt;
&lt;br /&gt;
You get the idea:  &amp;quot;Nice goal, Pat.  Good luck with that. You do realize you are 75 years old, don't you?&amp;quot;&lt;br /&gt;
Heedless, I press on.&lt;br /&gt;
&lt;br /&gt;
It should be obvious to all that this endeavour requires a lot of work, and anyone undertaking it is going to need help at various points.  It's easy to get stuck on specific points, and stuck in ways that you don't know which question to ask first, and where to ask it.  You, kind reader, may be able to help.  &lt;br /&gt;
&lt;br /&gt;
== Flightgear - Study Group ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I'm continuing to think about the idea of organizing and participating in a study group for flightgear coding, I want to consider current work on Flightgear proceeding on [http://gitlab.com/flightgear Gitlab] as fodder for study.&lt;br /&gt;
&lt;br /&gt;
The study group idea was prompted by my thinking about the codebase itself and why I found it so difficult to understand.  I'm sure others have at least some of the same challenges if they share my goal of becoming a regular flightgear contributor. If so,  we are likely to find common ground in meeting those challenges.&lt;br /&gt;
&lt;br /&gt;
These points are personal challenges in learning how FlightGear works, writing code and documentation, and debugging. &lt;br /&gt;
&lt;br /&gt;
* Object-oriented programming - Don't get me started.  Based on secondary sources, I agree with Alan Kay's thoughts on messaging as the most important aspect of &amp;quot;object&amp;quot; thinking, which most of us seem to overlook.&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://wiki.c2.com/?AlanKaysDefinitionOfObjectOriented Alan Kays Definition Of Object Oriented]&amp;lt;/ref&amp;gt;  Alan appears to live nearby.  Maybe I'll get up the nerve to ask him personally.  Finally, I am pretty sure I am not &amp;quot;a can of Coke&amp;lt;ref&amp;gt; [http://www.johno.se/book/oops.html OOPs - nasty traps in Object Oriented Programming]&amp;lt;/ref&amp;gt;.&amp;quot;&lt;br /&gt;
* C++,  when I learned C++, the STL was new. New as in &amp;quot;Do you need a container? Please feel free to write an implementation as homework&amp;quot;.  There has been significant progress since then, but I never actually wrote any C++ professionally, so I'm catching up on the changes in C++98, 03, 11, 14, 17, and 20.&lt;br /&gt;
* Specific Aircraft simulations are implemented mostly in XML, AC files, and Nasal, not in C++.&lt;br /&gt;
* Nasal is an interpreted language with separate class structures, memory allocation, and symbol tables, inaccessible to debuggers.&lt;br /&gt;
* The property tree is a global data store used for most intercommunication between subsystems, but it has no concept of messaging or data flow management.  Everything is done with callbacks on individual properties.  It's like watching an ant colony.&lt;br /&gt;
&lt;br /&gt;
None of the above should be taken as a suggestion that FlightGear development take any specific direction in the future.  That will come from me only after I've become a regular and significant contributor of C++, Nasal, and FlightGear data.  Nor should it be taken as criticism of what has been done so far in the 28-year history of the project.&lt;br /&gt;
&lt;br /&gt;
== Getting an Giving Help ==&lt;br /&gt;
I want to request assistance in the appropriate forums, having exhausted all possible avenues to explore answers before seeking help. At the same time I want to help others with any code problems they are struggling with. &lt;br /&gt;
 &lt;br /&gt;
I like helping other people.  It's the best way to make friends. &lt;br /&gt;
&lt;br /&gt;
I want you to know that I sometimes help people by listening to them describe a problem, and suggesting a route to finding some small tidbit of information that makes the problem easier to think about. It doesn't always happen, or even often, but when it does, the result seems very satisfying to both parties.  &lt;br /&gt;
&lt;br /&gt;
There are other times when just having me listen attentively to an explanation of a problem is sufficient for the teller to grasp a solution. I don't have to say a word, but they already have the answer.  Helpful, no?  This has happened to me on numerous occasions, more so than me making helpful comments.  Perhaps my asking for a description of the problem and any naive questions I ask about it are enough to get things moving.&lt;br /&gt;
&lt;br /&gt;
If you're stuck on a point and want my help, please don't hesitate to ask me personally on any forum where you encounter me. &lt;br /&gt;
You can find me on Discord as callahanp, on IRC as pac1 (early internet username formed from my initials)&lt;br /&gt;
&lt;br /&gt;
== Teamwork: ==&lt;br /&gt;
I'm a believer in teamwork and would love working closely in real-time with others on specific programming problems. I hope we can create opportunities for that.  I also believe that the only learning environment is not limited to a formal course, which includes lectures, readings, homework, quizzes, tests, and final grades.  Grown-ups use study groups, working groups, collaborators, publications, conferences, and prior work. And they take formal courses from time to time.&lt;br /&gt;
&lt;br /&gt;
== Pair programming ==&lt;br /&gt;
&lt;br /&gt;
I find pair programming an attractive idea and wonder how it works in practice. What is the result of practicing pair programming with programmers of similar skills? What happens when an expert programmer pairs with an inexperienced one?&lt;br /&gt;
&lt;br /&gt;
I find that most are resistant to participating in pair programming, and I wonder why.  &lt;br /&gt;
&lt;br /&gt;
We're taught in academic settings to program by ourselves and hand in ou submissions for review as &amp;quot;homework&amp;quot;, but we continue that pattern in our work mainly out of inertia and lack of proper training. There's no reason to continue that pattern outside of a classroom as our only or even as main way of working together. &lt;br /&gt;
&lt;br /&gt;
== Understanding FlightGear's Large &amp;amp; Complex Codebase ==&lt;br /&gt;
&lt;br /&gt;
The problem with FlightGear is its size, complexity, and the lack of a detailed guide to exploring that complexity. Several factors contribute to that complexity. Understanding FlightGear requires knowledge of many application domains, C++, an internal scripting language, a global data store, application features driven by XML or scripts, network protocols and data formats, some custom, some obscure, and from the era of mainframe computers.&lt;br /&gt;
&lt;br /&gt;
I'll examine each of these complexity realms with a view to providing a guideline for new FlightGear developers, me for instance, a path to follow leading to regular contributions to the FlightGear in C++, Nasal, and XML and other data formats.&lt;br /&gt;
&lt;br /&gt;
== C++ ==&lt;br /&gt;
&lt;br /&gt;
  First, the application uses C++. As a complex and evolving language, C++ has a reputation for being complex. It's not just the language, its the fragmentation of code into small tidbits, widely scattered in individual files covering supposedly just one aspect of what needs to be done. I don't really know if the structure of C++ code as objects is more efficient than a C++ program done using solid structured programming, but I know which is easier think about and to work on.&lt;br /&gt;
&lt;br /&gt;
== Flight Simulation does a lot of different things == &lt;br /&gt;
&lt;br /&gt;
Second, Flight Simulation involves numerous application domains. Among them are aerodynamics, graphics, geography, geodesy, environment, navigation, networks, audio, video, and human languages. FlightGear addresses all of them and more. Each of these domains has its own view of the world, and many of them are modelled as C++ classes. Full understanding comes from knowing the C++ code, the terminology of the domain, and the way the code's authors chose to structure things as objects and methods.  &lt;br /&gt;
&lt;br /&gt;
== Nasal and the Property Tree ==&lt;br /&gt;
&lt;br /&gt;
Next, in addition to the complexity introduced by C++ and the application domains, there's Nasal. Finally, to tie it all together, loosely, the property tree. a global object, with individual data items of a key-value store actually stored in a tree because they are conceptually related. The property tree introduced complexity because items in it are not &amp;quot;owned&amp;quot;, they're simply created at some point, in either C++, XML processing, or Nasal, and used wherever the data item is &amp;quot;needed&amp;quot;. Connecting the dots through all the code based on identifying individual properties is not all that easy.&lt;br /&gt;
&lt;br /&gt;
== Where should I start? C++, Nasal or XML) ==&lt;br /&gt;
&lt;br /&gt;
It's not clear from existing documentation the central role of Nasal scripting and the Property Tree are in the simulation. It's not just C++, Nasal, and the interface between them, understood as computer languages.   Knowing the languages and interfaces themselves is vital, but even more important is understanding how scripting is used in FlightGear to create the simulation. If you are struggling as a newcomer to understand FlightGear's C++ code, understanding Nasal's role in driving parts of the simulation and the way it interacts with C++ code is probably one of the first things to do. It's what I'll be doing next.&lt;br /&gt;
&lt;br /&gt;
== FlightGear's DataFlow Diagram == &lt;br /&gt;
&lt;br /&gt;
There isn't one. Or rather, there is one, but it's virtual in the sense that no one used it as a design document; rather, it is constructible as a mental model from the observable workings of flightgear itself.`&lt;br /&gt;
&lt;br /&gt;
Part of understanding any body of code is to be able to identify how data flows through the application. Dataflows are usually represented as arrows of various widths. The arrows are messages flowing between parts of an application. The larger the arrow, the more data items in that data flow.  Knowing what is in each of those flows is important to understanding how the application works.  &lt;br /&gt;
&lt;br /&gt;
In FlightGear's C++ code, there are, of course, classes and objects that represent some dataflows. There's a problem, though. Many of the classes are about processing data into ad-hoc structures within the property tree.  How can we define a data flow for these ad-hoc structures?  (Note: need a way to describe two dataflows.  The one that creates the infrastructure as properties in the tree, and a second one implied by the existence of the property.)&lt;br /&gt;
&lt;br /&gt;
There is no C++ class for an Altimeter or a Heading Indicator. Instead, these are represented by a set of properties and data loaded via XML and other formats. The numerical data, stored in the property tree has a path indicating that the properties underneath a node are for the altimeter or the heading indicator. The actual paths in this case are /instrumentation/altimeter and /instrumentation/heading-indicator. Each node in the tree can have properties as child nodes, as well as child nodes that contain additional properties, such as /instrumentation/heading-indicator/gyro. Usually, only the lear nodes of th e tree &lt;br /&gt;
&lt;br /&gt;
Properties are created on the fly, once the property tree's root node is instantiated. Properties are specified in XML data, created by a Nasal script, or by C++ code. The actual property mechanism is implemented in a C++ class.&lt;br /&gt;
&lt;br /&gt;
After they are created, properties are used as needed from Nasal scripts and C++ code, and finally destroyed by a destructor in C++. However, none of that is traceable as a data flow. IDEs are great at connecting elements of code to their definitions and usage, but when we use a data store like the property tree, the connection can't be found by the IDE. These data flows through the property tree mechanisms are a real part of the FlightGear Application, but we have no easy way to visualise them. Any visualization is mentally constructed over time by developers' experiences, as they examine and step through code.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[http://wiki.flightgear.org/User:Callahanp/goals What's up with Pat]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=142027</id>
		<title>User:Callahanp</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=142027"/>
		<updated>2025-06-30T15:49:54Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: /* Flightgear - Study Group */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Me ==&lt;br /&gt;
 &lt;br /&gt;
Hello, my name is Patrick Callahan. People call me Pat. I have a web page, and you found it.&lt;br /&gt;
&lt;br /&gt;
I've been a programmer since I was a teenager. I'm 74 years old and retired now.&lt;br /&gt;
&lt;br /&gt;
Programming was a fun job. We couldn't believe we got paid to have so much fun.&lt;br /&gt;
&lt;br /&gt;
My current expertise primarily lies in databases, bash scripting, and traditional procedural programming in various languages.&lt;br /&gt;
&lt;br /&gt;
C++ is a work in progress. I took a course in 1993, but never used it professionally.  &lt;br /&gt;
&lt;br /&gt;
I like gardening with my wife of 33 years, Ann. We have a daughter who has given us three very active grandchildren, who will visit us next week for four days. Did I say I kept busy? We reside in the state of Massachusetts in the United States.&lt;br /&gt;
&lt;br /&gt;
I hope to make regular code contributions to FlightGear. I want to gain the skills to address some FlightGear issues as they come up and participate in the discussions and programming for the various [FlightGear Epics |https://gitlab.com/groups/flightgear/-/epics?sort=created_date&amp;amp;state=opened&amp;amp;first_page_size=100]&lt;br /&gt;
&lt;br /&gt;
You are about to read a very personal document.  I make statements there that I have not yet validated by discussing these ideas directly with others and trying to put them into practice.  Go easy on me.  Criticize my ideas, not me.  I think this is ok, as the material is buried in a personal web page on a wiki.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
== FlightGear Development: ==&lt;br /&gt;
&lt;br /&gt;
I'm motivated to learn enough C++, Nasal, and whatever else it takes to start regularly contributing to the Flightgear Codebase.  &lt;br /&gt;
&lt;br /&gt;
Someone with practical experience writing, maintaining, and fixing problems in C++ can easily begin contributing to FlightGear's codebase.  They may find a few fine points, such as the internal scripting language and the property tree, but they should be able to navigate with little assistance.  That's not me.  I don't have the practical experience, and my  C++ experience consists mostly of a one-semester class.  Not only that, the class was in the previous century.  Move semantics?  What's That!?&lt;br /&gt;
&lt;br /&gt;
You get the idea:  &amp;quot;Nice goal, Pat.  Good luck with that. You do realize you are 75 years old, don't you?&amp;quot;&lt;br /&gt;
Heedless, I press on.&lt;br /&gt;
&lt;br /&gt;
It should be obvious to all that this endeavour requires a lot of work, and anyone undertaking it is going to need help at various points.  It's easy to get stuck on specific points, and stuck in ways that you don't know which question to ask first, and where to ask it.  You, kind reader, may be able to help.  &lt;br /&gt;
&lt;br /&gt;
== Flightgear - Study Group ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I'm continuing to think about the idea of organizing and participating in a study group for flightgear coding, I want to consider current work on Flightgear proceeding on [http://gitlab.com/flightgear Gitlab] as fodder for study.&lt;br /&gt;
&lt;br /&gt;
The study group idea was prompted by my thinking about the codebase itself and why I found it so difficult to understand.  I'm sure others have at least some of the same challenges if they share my goal of becoming a regular flightgear contributor. If so,  we are likely to find common ground in meeting those challenges.&lt;br /&gt;
&lt;br /&gt;
These points are personal challenges in learning how FlightGear works, writing code and documentation, and debugging. &lt;br /&gt;
&lt;br /&gt;
* Object-oriented programming - Don't get me started.  Based on secondary sources, I agree with Alan Kay's thoughts on it.&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://wiki.c2.com/?AlanKaysDefinitionOfObjectOriented Alan Kays Definition Of Object Oriented]&amp;lt;/ref&amp;gt;  Alan appears to live nearby.  Maybe I'll get up the nerve to ask him personally.  Finally, I am pretty sure I am not &amp;quot;a can of Coke&amp;lt;ref&amp;gt; [http://www.johno.se/book/oops.html OOPs - nasty traps in Object Oriented Programming]&amp;lt;/ref&amp;gt;.&amp;quot;&lt;br /&gt;
* C++,  when I learned C++, the STL was new. New as in &amp;quot;Do you need a container? Please feel free to write an implementation as homework&amp;quot;.  There has been significant progress since then, but I never actually wrote any C++ professionally, so I'm catching up on the changes in C++98, 03, 11, 14, 17, and 20.&lt;br /&gt;
* Specific Aircraft simulations are implemented mostly in XML, AC files, and Nasal, not in C++.&lt;br /&gt;
* Nasal is an interpreted language with separate class structures, memory allocation, and symbol tables, inaccessible to debuggers.&lt;br /&gt;
* The property tree is a global data store used for most intercommunication between subsystems, but it has no concept of messaging or data flow management.  Everything is done with callbacks on individual properties.  It's like watching an ant colony.&lt;br /&gt;
&lt;br /&gt;
None of the above should be taken as a suggestion that FlightGear development take any specific direction in the future.  That will come from me only after I've become a regular and significant contributor of C++, Nasal, and FlightGear data.  Nor should it be taken as criticism of what has been done so far in the 28-year history of the project.&lt;br /&gt;
&lt;br /&gt;
== Getting an Giving Help ==&lt;br /&gt;
I want to request assistance in the appropriate forums, having exhausted all possible avenues to explore answers before seeking help. At the same time I want to help others with any code problems they are struggling with. &lt;br /&gt;
 &lt;br /&gt;
I like helping other people.  It's the best way to make friends. &lt;br /&gt;
&lt;br /&gt;
I want you to know that I sometimes help people by listening to them describe a problem, and suggesting a route to finding some small tidbit of information that makes the problem easier to think about. It doesn't always happen, or even often, but when it does, the result seems very satisfying to both parties.  &lt;br /&gt;
&lt;br /&gt;
There are other times when just having me listen attentively to an explanation of a problem is sufficient for the teller to grasp a solution. I don't have to say a word, but they already have the answer.  Helpful, no?  This has happened to me on numerous occasions, more so than me making helpful comments.  Perhaps my asking for a description of the problem and any naive questions I ask about it are enough to get things moving.&lt;br /&gt;
&lt;br /&gt;
If you're stuck on a point and want my help, please don't hesitate to ask me personally on any forum where you encounter me. &lt;br /&gt;
You can find me on Discord as callahanp, on IRC as pac1 (early internet username formed from my initials)&lt;br /&gt;
&lt;br /&gt;
== Teamwork: ==&lt;br /&gt;
I'm a believer in teamwork and would love working closely in real-time with others on specific programming problems. I hope we can create opportunities for that.  I also believe that the only learning environment is not limited to a formal course, which includes lectures, readings, homework, quizzes, tests, and final grades.  Grown-ups use study groups, working groups, collaborators, publications, conferences, and prior work. And they take formal courses from time to time.&lt;br /&gt;
&lt;br /&gt;
== Pair programming ==&lt;br /&gt;
&lt;br /&gt;
I find pair programming an attractive idea and wonder how it works in practice. What is the result of practicing pair programming with programmers of similar skills? What happens when an expert programmer pairs with an inexperienced one?&lt;br /&gt;
&lt;br /&gt;
I find that most are resistant to participating in pair programming, and I wonder why.  &lt;br /&gt;
&lt;br /&gt;
We're taught in academic settings to program by ourselves and hand in ou submissions for review as &amp;quot;homework&amp;quot;, but we continue that pattern in our work mainly out of inertia and lack of proper training. There's no reason to continue that pattern outside of a classroom as our only or even as main way of working together. &lt;br /&gt;
&lt;br /&gt;
== Understanding FlightGear's Large &amp;amp; Complex Codebase ==&lt;br /&gt;
&lt;br /&gt;
The problem with FlightGear is its size, complexity, and the lack of a detailed guide to exploring that complexity. Several factors contribute to that complexity. Understanding FlightGear requires knowledge of many application domains, C++, an internal scripting language, a global data store, application features driven by XML or scripts, network protocols and data formats, some custom, some obscure, and from the era of mainframe computers.&lt;br /&gt;
&lt;br /&gt;
I'll examine each of these complexity realms with a view to providing a guideline for new FlightGear developers, me for instance, a path to follow leading to regular contributions to the FlightGear in C++, Nasal, and XML and other data formats.&lt;br /&gt;
&lt;br /&gt;
== C++ ==&lt;br /&gt;
&lt;br /&gt;
  First, the application uses C++. As a complex and evolving language, C++ has a reputation for being complex. It's not just the language, its the fragmentation of code into small tidbits, widely scattered in individual files covering supposedly just one aspect of what needs to be done. I don't really know if the structure of C++ code as objects is more efficient than a C++ program done using solid structured programming, but I know which is easier think about and to work on.&lt;br /&gt;
&lt;br /&gt;
== Flight Simulation does a lot of different things == &lt;br /&gt;
&lt;br /&gt;
Second, Flight Simulation involves numerous application domains. Among them are aerodynamics, graphics, geography, geodesy, environment, navigation, networks, audio, video, and human languages. FlightGear addresses all of them and more. Each of these domains has its own view of the world, and many of them are modelled as C++ classes. Full understanding comes from knowing the C++ code, the terminology of the domain, and the way the code's authors chose to structure things as objects and methods.  &lt;br /&gt;
&lt;br /&gt;
== Nasal and the Property Tree ==&lt;br /&gt;
&lt;br /&gt;
Next, in addition to the complexity introduced by C++ and the application domains, there's Nasal. Finally, to tie it all together, loosely, the property tree. a global object, with individual data items of a key-value store actually stored in a tree because they are conceptually related. The property tree introduced complexity because items in it are not &amp;quot;owned&amp;quot;, they're simply created at some point, in either C++, XML processing, or Nasal, and used wherever the data item is &amp;quot;needed&amp;quot;. Connecting the dots through all the code based on identifying individual properties is not all that easy.&lt;br /&gt;
&lt;br /&gt;
== Where should I start? C++, Nasal or XML) ==&lt;br /&gt;
&lt;br /&gt;
It's not clear from existing documentation the central role of Nasal scripting and the Property Tree are in the simulation. It's not just C++, Nasal, and the interface between them, understood as computer languages.   Knowing the languages and interfaces themselves is vital, but even more important is understanding how scripting is used in FlightGear to create the simulation. If you are struggling as a newcomer to understand FlightGear's C++ code, understanding Nasal's role in driving parts of the simulation and the way it interacts with C++ code is probably one of the first things to do. It's what I'll be doing next.&lt;br /&gt;
&lt;br /&gt;
== FlightGear's DataFlow Diagram == &lt;br /&gt;
&lt;br /&gt;
There isn't one. Or rather, there is one, but it's virtual in the sense that no one used it as a design document; rather, it is constructible as a mental model from the observable workings of flightgear itself.`&lt;br /&gt;
&lt;br /&gt;
Part of understanding any body of code is to be able to identify how data flows through the application. Dataflows are usually represented as arrows of various widths. The arrows are messages flowing between parts of an application. The larger the arrow, the more data items in that data flow.  Knowing what is in each of those flows is important to understanding how the application works.  &lt;br /&gt;
&lt;br /&gt;
In FlightGear's C++ code, there are, of course, classes and objects that represent some dataflows. There's a problem, though. Many of the classes are about processing data into ad-hoc structures within the property tree.  How can we define a data flow for these ad-hoc structures?  (Note: need a way to describe two dataflows.  The one that creates the infrastructure as properties in the tree, and a second one implied by the existence of the property.)&lt;br /&gt;
&lt;br /&gt;
There is no C++ class for an Altimeter or a Heading Indicator. Instead, these are represented by a set of properties and data loaded via XML and other formats. The numerical data, stored in the property tree has a path indicating that the properties underneath a node are for the altimeter or the heading indicator. The actual paths in this case are /instrumentation/altimeter and /instrumentation/heading-indicator. Each node in the tree can have properties as child nodes, as well as child nodes that contain additional properties, such as /instrumentation/heading-indicator/gyro. Usually, only the lear nodes of th e tree &lt;br /&gt;
&lt;br /&gt;
Properties are created on the fly, once the property tree's root node is instantiated. Properties are specified in XML data, created by a Nasal script, or by C++ code. The actual property mechanism is implemented in a C++ class.&lt;br /&gt;
&lt;br /&gt;
After they are created, properties are used as needed from Nasal scripts and C++ code, and finally destroyed by a destructor in C++. However, none of that is traceable as a data flow. IDEs are great at connecting elements of code to their definitions and usage, but when we use a data store like the property tree, the connection can't be found by the IDE. These data flows through the property tree mechanisms are a real part of the FlightGear Application, but we have no easy way to visualise them. Any visualization is mentally constructed over time by developers' experiences, as they examine and step through code.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[http://wiki.flightgear.org/User:Callahanp/goals What's up with Pat]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=142026</id>
		<title>User:Callahanp</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=142026"/>
		<updated>2025-06-30T15:34:12Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: /* Flightgear - Study Group */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Me ==&lt;br /&gt;
 &lt;br /&gt;
Hello, my name is Patrick Callahan. People call me Pat. I have a web page, and you found it.&lt;br /&gt;
&lt;br /&gt;
I've been a programmer since I was a teenager. I'm 74 years old and retired now.&lt;br /&gt;
&lt;br /&gt;
Programming was a fun job. We couldn't believe we got paid to have so much fun.&lt;br /&gt;
&lt;br /&gt;
My current expertise primarily lies in databases, bash scripting, and traditional procedural programming in various languages.&lt;br /&gt;
&lt;br /&gt;
C++ is a work in progress. I took a course in 1993, but never used it professionally.  &lt;br /&gt;
&lt;br /&gt;
I like gardening with my wife of 33 years, Ann. We have a daughter who has given us three very active grandchildren, who will visit us next week for four days. Did I say I kept busy? We reside in the state of Massachusetts in the United States.&lt;br /&gt;
&lt;br /&gt;
I hope to make regular code contributions to FlightGear. I want to gain the skills to address some FlightGear issues as they come up and participate in the discussions and programming for the various [FlightGear Epics |https://gitlab.com/groups/flightgear/-/epics?sort=created_date&amp;amp;state=opened&amp;amp;first_page_size=100]&lt;br /&gt;
&lt;br /&gt;
You are about to read a very personal document.  I make statements there that I have not yet validated by discussing these ideas directly with others and trying to put them into practice.  Go easy on me.  Criticize my ideas, not me.  I think this is ok, as the material is buried in a personal web page on a wiki.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
== FlightGear Development: ==&lt;br /&gt;
&lt;br /&gt;
I'm motivated to learn enough C++, Nasal, and whatever else it takes to start regularly contributing to the Flightgear Codebase.  &lt;br /&gt;
&lt;br /&gt;
Someone with practical experience writing, maintaining, and fixing problems in C++ can easily begin contributing to FlightGear's codebase.  They may find a few fine points, such as the internal scripting language and the property tree, but they should be able to navigate with little assistance.  That's not me.  I don't have the practical experience, and my  C++ experience consists mostly of a one-semester class.  Not only that, the class was in the previous century.  Move semantics?  What's That!?&lt;br /&gt;
&lt;br /&gt;
You get the idea:  &amp;quot;Nice goal, Pat.  Good luck with that. You do realize you are 75 years old, don't you?&amp;quot;&lt;br /&gt;
Heedless, I press on.&lt;br /&gt;
&lt;br /&gt;
It should be obvious to all that this endeavour requires a lot of work, and anyone undertaking it is going to need help at various points.  It's easy to get stuck on specific points, and stuck in ways that you don't know which question to ask first, and where to ask it.  You, kind reader, may be able to help.  &lt;br /&gt;
&lt;br /&gt;
== Flightgear - Study Group ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I'm continuing to think about the idea of organizing and participating in a study group for flightgear coding, I want to consider current work on Flightgear proceeding on [http://gitlab.com/flightgear Gitlab] as fodder for study.&lt;br /&gt;
&lt;br /&gt;
The study group idea was prompted by my thinking about the codebase itself and why I found it so difficult to understand.  I'm sure others have at least some of the same challenges if they share my goal of becoming a regular flightgear contributor. If so,  we are likely to find common ground in meeting those challenges.&lt;br /&gt;
&lt;br /&gt;
These points are personal challenges in learning how FlightGear works, writing code and documentation, and debugging. &lt;br /&gt;
&lt;br /&gt;
* Object-oriented programming - Don't get me started.  Based on secondary sources I agree with Alan Kay's thoughts on it.&amp;lt;ref&amp;gt;&lt;br /&gt;
[https://wiki.c2.com/?AlanKaysDefinitionOfObjectOriented Alan Kays Definition Of Object Oriented]&amp;lt;/ref&amp;gt;  Alan appears to live nearby.  Maybe I'll get up the nerve to ask him personally.  Finally, I am pretty sure I am not &amp;quot;a can of Coke&amp;lt;ref&amp;gt; [http://www.johno.se/book/oops.html OOPs - nasty traps in Object Oriented Programming]&amp;lt;/ref&amp;gt;.&amp;quot;&lt;br /&gt;
* C++,  when I learned C++, the STL was new. New as in &amp;quot;Do you need a container? Please feel free to write an implementation as homework&amp;quot;.  There has been significant progress since then, but I never actually wrote any C++ professionally, so I'm catching up on the changes in C++98, 03, 11, 14, 17, and 20.&lt;br /&gt;
* Specific Aircraft simulations are implemented mostly in XML, AC files, and Nasal, not in C++.&lt;br /&gt;
* Nasal is an interpreted language with separate class structures, memory allocation, and symbol tables, inaccessible to debuggers.&lt;br /&gt;
* The property tree is a global data store used for most intercommunication between subsystems, but it has no concept of messaging or data flow management.  Everything is done with callbacks on individual properties.  It's like watching an ant colony.&lt;br /&gt;
&lt;br /&gt;
None of the above should be taken as a suggestion that FlightGear development take any specific direction in the future.  That will come from me only after I've become a regular and significant contributor of C++, Nasal, and FlightGear data.  Nor should it be taken as criticism of what has been done so far in the 28-year history of the project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{reflist}}&lt;br /&gt;
&lt;br /&gt;
== Getting an Giving Help ==&lt;br /&gt;
I want to request assistance in the appropriate forums, having exhausted all possible avenues to explore answers before seeking help. At the same time I want to help others with any code problems they are struggling with. &lt;br /&gt;
 &lt;br /&gt;
I like helping other people.  It's the best way to make friends. &lt;br /&gt;
&lt;br /&gt;
I want you to know that I sometimes help people by listening to them describe a problem, and suggesting a route to finding some small tidbit of information that makes the problem easier to think about. It doesn't always happen, or even often, but when it does, the result seems very satisfying to both parties.  &lt;br /&gt;
&lt;br /&gt;
There are other times when just having me listen attentively to an explanation of a problem is sufficient for the teller to grasp a solution. I don't have to say a word, but they already have the answer.  Helpful, no?  This has happened to me on numerous occasions, more so than me making helpful comments.  Perhaps my asking for a description of the problem and any naive questions I ask about it are enough to get things moving.&lt;br /&gt;
&lt;br /&gt;
If you're stuck on a point and want my help, please don't hesitate to ask me personally on any forum where you encounter me. &lt;br /&gt;
You can find me on Discord as callahanp, on IRC as pac1 (early internet username formed from my initials)&lt;br /&gt;
&lt;br /&gt;
== Teamwork: ==&lt;br /&gt;
I'm a believer in teamwork and would love working closely in real-time with others on specific programming problems. I hope we can create opportunities for that.  I also believe that the only learning environment is not limited to a formal course, which includes lectures, readings, homework, quizzes, tests, and final grades.  Grown-ups use study groups, working groups, collaborators, publications, conferences, and prior work. And they take formal courses from time to time.&lt;br /&gt;
&lt;br /&gt;
== Pair programming ==&lt;br /&gt;
&lt;br /&gt;
I find pair programming an attractive idea and wonder how it works in practice. What is the result of practicing pair programming with programmers of similar skills? What happens when an expert programmer pairs with an inexperienced one?&lt;br /&gt;
&lt;br /&gt;
I find that most are resistant to participating in pair programming, and I wonder why.  &lt;br /&gt;
&lt;br /&gt;
We're taught in academic settings to program by ourselves and hand in ou submissions for review as &amp;quot;homework&amp;quot;, but we continue that pattern in our work mainly out of inertia and lack of proper training. There's no reason to continue that pattern outside of a classroom as our only or even as main way of working together. &lt;br /&gt;
&lt;br /&gt;
== Understanding FlightGear's Large &amp;amp; Complex Codebase ==&lt;br /&gt;
&lt;br /&gt;
The problem with FlightGear is its size, complexity, and the lack of a detailed guide to exploring that complexity. Several factors contribute to that complexity. Understanding FlightGear requires knowledge of many application domains, C++, an internal scripting language, a global data store, application features driven by XML or scripts, network protocols and data formats, some custom, some obscure, and from the era of mainframe computers.&lt;br /&gt;
&lt;br /&gt;
I'll examine each of these complexity realms with a view to providing a guideline for new FlightGear developers, me for instance, a path to follow leading to regular contributions to the FlightGear in C++, Nasal, and XML and other data formats.&lt;br /&gt;
&lt;br /&gt;
== C++ ==&lt;br /&gt;
&lt;br /&gt;
  First, the application uses C++. As a complex and evolving language, C++ has a reputation for being complex. It's not just the language, its the fragmentation of code into small tidbits, widely scattered in individual files covering supposedly just one aspect of what needs to be done. I don't really know if the structure of C++ code as objects is more efficient than a C++ program done using solid structured programming, but I know which is easier think about and to work on.&lt;br /&gt;
&lt;br /&gt;
== Flight Simulation does a lot of different things == &lt;br /&gt;
&lt;br /&gt;
Second, Flight Simulation involves numerous application domains. Among them are aerodynamics, graphics, geography, geodesy, environment, navigation, networks, audio, video, and human languages. FlightGear addresses all of them and more. Each of these domains has its own view of the world, and many of them are modelled as C++ classes. Full understanding comes from knowing the C++ code, the terminology of the domain, and the way the code's authors chose to structure things as objects and methods.  &lt;br /&gt;
&lt;br /&gt;
== Nasal and the Property Tree ==&lt;br /&gt;
&lt;br /&gt;
Next, in addition to the complexity introduced by C++ and the application domains, there's Nasal. Finally, to tie it all together, loosely, the property tree. a global object, with individual data items of a key-value store actually stored in a tree because they are conceptually related. The property tree introduced complexity because items in it are not &amp;quot;owned&amp;quot;, they're simply created at some point, in either C++, XML processing, or Nasal, and used wherever the data item is &amp;quot;needed&amp;quot;. Connecting the dots through all the code based on identifying individual properties is not all that easy.&lt;br /&gt;
&lt;br /&gt;
== Where should I start? C++, Nasal or XML) ==&lt;br /&gt;
&lt;br /&gt;
It's not clear from existing documentation the central role of Nasal scripting and the Property Tree are in the simulation. It's not just C++, Nasal, and the interface between them, understood as computer languages.   Knowing the languages and interfaces themselves is vital, but even more important is understanding how scripting is used in FlightGear to create the simulation. If you are struggling as a newcomer to understand FlightGear's C++ code, understanding Nasal's role in driving parts of the simulation and the way it interacts with C++ code is probably one of the first things to do. It's what I'll be doing next.&lt;br /&gt;
&lt;br /&gt;
== FlightGear's DataFlow Diagram == &lt;br /&gt;
&lt;br /&gt;
There isn't one. Or rather, there is one, but it's virtual in the sense that no one used it as a design document; rather, it is constructible as a mental model from the observable workings of flightgear itself.`&lt;br /&gt;
&lt;br /&gt;
Part of understanding any body of code is to be able to identify how data flows through the application. Dataflows are usually represented as arrows of various widths. The arrows are messages flowing between parts of an application. The larger the arrow, the more data items in that data flow.  Knowing what is in each of those flows is important to understanding how the application works.  &lt;br /&gt;
&lt;br /&gt;
In FlightGear's C++ code, there are, of course, classes and objects that represent some dataflows. There's a problem, though. Many of the classes are about processing data into ad-hoc structures within the property tree.  How can we define a data flow for these ad-hoc structures?  (Note: need a way to describe two dataflows.  The one that creates the infrastructure as properties in the tree, and a second one implied by the existence of the property.)&lt;br /&gt;
&lt;br /&gt;
There is no C++ class for an Altimeter or a Heading Indicator. Instead, these are represented by a set of properties and data loaded via XML and other formats. The numerical data, stored in the property tree has a path indicating that the properties underneath a node are for the altimeter or the heading indicator. The actual paths in this case are /instrumentation/altimeter and /instrumentation/heading-indicator. Each node in the tree can have properties as child nodes, as well as child nodes that contain additional properties, such as /instrumentation/heading-indicator/gyro. Usually, only the lear nodes of th e tree &lt;br /&gt;
&lt;br /&gt;
Properties are created on the fly, once the property tree's root node is instantiated. Properties are specified in XML data, created by a Nasal script, or by C++ code. The actual property mechanism is implemented in a C++ class.&lt;br /&gt;
&lt;br /&gt;
After they are created, properties are used as needed from Nasal scripts and C++ code, and finally destroyed by a destructor in C++. However, none of that is traceable as a data flow. IDEs are great at connecting elements of code to their definitions and usage, but when we use a data store like the property tree, the connection can't be found by the IDE. These data flows through the property tree mechanisms are a real part of the FlightGear Application, but we have no easy way to visualise them. Any visualization is mentally constructed over time by developers' experiences, as they examine and step through code.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[http://wiki.flightgear.org/User:Callahanp/goals What's up with Pat]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=142025</id>
		<title>User:Callahanp</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=142025"/>
		<updated>2025-06-30T15:07:47Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Me ==&lt;br /&gt;
 &lt;br /&gt;
Hello, my name is Patrick Callahan. People call me Pat. I have a web page, and you found it.&lt;br /&gt;
&lt;br /&gt;
I've been a programmer since I was a teenager. I'm 74 years old and retired now.&lt;br /&gt;
&lt;br /&gt;
Programming was a fun job. We couldn't believe we got paid to have so much fun.&lt;br /&gt;
&lt;br /&gt;
My current expertise primarily lies in databases, bash scripting, and traditional procedural programming in various languages.&lt;br /&gt;
&lt;br /&gt;
C++ is a work in progress. I took a course in 1993, but never used it professionally.  &lt;br /&gt;
&lt;br /&gt;
I like gardening with my wife of 33 years, Ann. We have a daughter who has given us three very active grandchildren, who will visit us next week for four days. Did I say I kept busy? We reside in the state of Massachusetts in the United States.&lt;br /&gt;
&lt;br /&gt;
I hope to make regular code contributions to FlightGear. I want to gain the skills to address some FlightGear issues as they come up and participate in the discussions and programming for the various [FlightGear Epics |https://gitlab.com/groups/flightgear/-/epics?sort=created_date&amp;amp;state=opened&amp;amp;first_page_size=100]&lt;br /&gt;
&lt;br /&gt;
You are about to read a very personal document.  I make statements there that I have not yet validated by discussing these ideas directly with others and trying to put them into practice.  Go easy on me.  Criticize my ideas, not me.  I think this is ok, as the material is buried in a personal web page on a wiki.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
== FlightGear Development: ==&lt;br /&gt;
&lt;br /&gt;
I'm motivated to learn enough C++, Nasal, and whatever else it takes to start regularly contributing to the Flightgear Codebase.  &lt;br /&gt;
&lt;br /&gt;
Someone with practical experience writing, maintaining, and fixing problems in C++ can easily begin contributing to FlightGear's codebase.  They may find a few fine points, such as the internal scripting language and the property tree, but they should be able to navigate with little assistance.  That's not me.  I don't have the practical experience, and my  C++ experience consists mostly of a one-semester class.  Not only that, the class was in the previous century.  Move semantics?  What's That!?&lt;br /&gt;
&lt;br /&gt;
You get the idea:  &amp;quot;Nice goal, Pat.  Good luck with that. You do realize you are 75 years old, don't you?&amp;quot;&lt;br /&gt;
Heedless, I press on.&lt;br /&gt;
&lt;br /&gt;
It should be obvious to all that this endeavour requires a lot of work, and anyone undertaking it is going to need help at various points.  It's easy to get stuck on specific points, and stuck in ways that you don't know which question to ask first, and where to ask it.  You, kind reader, may be able to help.  &lt;br /&gt;
&lt;br /&gt;
== Flightgear - Study Group ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I'm continuing to think about the idea of organizing and participating in a study group for flightgear coding, I want to consider current work on Flightgear proceeding on &amp;lt;nowiki&amp;gt;[http://gitlab.com/flightgear | FlighGear on Gitlab]&amp;lt;/nowiki&amp;gt; as fodder for study.&lt;br /&gt;
&lt;br /&gt;
I'm also thinking about the codebase itself and why I found it so difficult to understand.  &lt;br /&gt;
&lt;br /&gt;
These points are challenges in learning how FlightGear works, writing code and documentation, and debugging. &lt;br /&gt;
&lt;br /&gt;
* Object-oriented programming - Don't get me started.  I agree with Alan Kay. And I am not &amp;quot;a can of Coke*.&amp;quot;&lt;br /&gt;
* C++,  when I learned C++, the STL was new. New as in &amp;quot;Do you need a container? Please feel free to write an implementation as homework&amp;quot;.  There has been significant progress since then, but I never actually wrote any C++ professionally, so I'm catching up on the changes in C++98, 03, 11, 14, 17, and 20.&lt;br /&gt;
* Specific Aircraft simulations are implemented mostly in XML, AC files, and Nasal, not in C++.&lt;br /&gt;
* Nasal is an interpreted language with separate class structures, memory allocation, and symbol tables, inaccessible to debuggers.&lt;br /&gt;
* The property tree is a global data store used for most intercommunication between subsystems, but it has no concept of messaging or data flow management.  Everything is done with callbacks on individual properties.  It's like watching an ant colony.&lt;br /&gt;
&lt;br /&gt;
None of the above should be taken as a suggestion that FlightGear development take any specific direction in the future.  That will come from me only after I've become a regular and signicant contributor of C++, Nasal and FlightGear data.  Nor should it be taken as criticism of what has been done so far in the 25-year history of the project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt; &amp;lt;nowiki&amp;gt;http://www.johno.se/book/oops.html&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Getting an Giving Help ==&lt;br /&gt;
I want to request assistance in the appropriate forums, having exhausted all possible avenues to explore answers before seeking help. At the same time I want to help others with any code problems they are struggling with. &lt;br /&gt;
 &lt;br /&gt;
I like helping other people.  It's the best way to make friends. &lt;br /&gt;
&lt;br /&gt;
I want you to know that I sometimes help people by listening to them describe a problem, and suggesting a route to finding some small tidbit of information that makes the problem easier to think about. It doesn't always happen, or even often, but when it does, the result seems very satisfying to both parties.  &lt;br /&gt;
&lt;br /&gt;
There are other times when just having me listen attentively to an explanation of a problem is sufficient for the teller to grasp a solution. I don't have to say a word, but they already have the answer.  Helpful, no?  This has happened to me on numerous occasions, more so than me making helpful comments.  Perhaps my asking for a description of the problem and any naive questions I ask about it are enough to get things moving.&lt;br /&gt;
&lt;br /&gt;
If you're stuck on a point and want my help, please don't hesitate to ask me personally on any forum where you encounter me. &lt;br /&gt;
You can find me on Discord as callahanp, on IRC as pac1 (early internet username formed from my initials)&lt;br /&gt;
&lt;br /&gt;
== Teamwork: ==&lt;br /&gt;
I'm a believer in teamwork and would love working closely in real-time with others on specific programming problems. I hope we can create opportunities for that.  I also believe that the only learning environment is not limited to a formal course, which includes lectures, readings, homework, quizzes, tests, and final grades.  Grown-ups use study groups, working groups, collaborators, publications, conferences, and prior work. And they take formal courses from time to time.&lt;br /&gt;
&lt;br /&gt;
== Pair programming ==&lt;br /&gt;
&lt;br /&gt;
I find pair programming an attractive idea and wonder how it works in practice. What is the result of practicing pair programming with programmers of similar skills? What happens when an expert programmer pairs with an inexperienced one?&lt;br /&gt;
&lt;br /&gt;
I find that most are resistant to participating in pair programming, and I wonder why.  &lt;br /&gt;
&lt;br /&gt;
We're taught in academic settings to program by ourselves and hand in ou submissions for review as &amp;quot;homework&amp;quot;, but we continue that pattern in our work mainly out of inertia and lack of proper training. There's no reason to continue that pattern outside of a classroom as our only or even as main way of working together. &lt;br /&gt;
&lt;br /&gt;
== Understanding FlightGear's Large &amp;amp; Complex Codebase ==&lt;br /&gt;
&lt;br /&gt;
The problem with FlightGear is its size, complexity, and the lack of a detailed guide to exploring that complexity. Several factors contribute to that complexity. Understanding FlightGear requires knowledge of many application domains, C++, an internal scripting language, a global data store, application features driven by XML or scripts, network protocols and data formats, some custom, some obscure, and from the era of mainframe computers.&lt;br /&gt;
&lt;br /&gt;
I'll examine each of these complexity realms with a view to providing a guideline for new FlightGear developers, me for instance, a path to follow leading to regular contributions to the FlightGear in C++, Nasal, and XML and other data formats.&lt;br /&gt;
&lt;br /&gt;
== C++ ==&lt;br /&gt;
&lt;br /&gt;
  First, the application uses C++. As a complex and evolving language, C++ has a reputation for being complex. It's not just the language, its the fragmentation of code into small tidbits, widely scattered in individual files covering supposedly just one aspect of what needs to be done. I don't really know if the structure of C++ code as objects is more efficient than a C++ program done using solid structured programming, but I know which is easier think about and to work on.&lt;br /&gt;
&lt;br /&gt;
== Flight Simulation does a lot of different things == &lt;br /&gt;
&lt;br /&gt;
Second, Flight Simulation involves numerous application domains. Among them are aerodynamics, graphics, geography, geodesy, environment, navigation, networks, audio, video, and human languages. FlightGear addresses all of them and more. Each of these domains has its own view of the world, and many of them are modelled as C++ classes. Full understanding comes from knowing the C++ code, the terminology of the domain, and the way the code's authors chose to structure things as objects and methods.  &lt;br /&gt;
&lt;br /&gt;
== Nasal and the Property Tree ==&lt;br /&gt;
&lt;br /&gt;
Next, in addition to the complexity introduced by C++ and the application domains, there's Nasal. Finally, to tie it all together, loosely, the property tree. a global object, with individual data items of a key-value store actually stored in a tree because they are conceptually related. The property tree introduced complexity because items in it are not &amp;quot;owned&amp;quot;, they're simply created at some point, in either C++, XML processing, or Nasal, and used wherever the data item is &amp;quot;needed&amp;quot;. Connecting the dots through all the code based on identifying individual properties is not all that easy.&lt;br /&gt;
&lt;br /&gt;
== Where should I start? C++, Nasal or XML) ==&lt;br /&gt;
&lt;br /&gt;
It's not clear from existing documentation the central role of Nasal scripting and the Property Tree are in the simulation. It's not just C++, Nasal, and the interface between them, understood as computer languages.   Knowing the languages and interfaces themselves is vital, but even more important is understanding how scripting is used in FlightGear to create the simulation. If you are struggling as a newcomer to understand FlightGear's C++ code, understanding Nasal's role in driving parts of the simulation and the way it interacts with C++ code is probably one of the first things to do. It's what I'll be doing next.&lt;br /&gt;
&lt;br /&gt;
== FlightGear's DataFlow Diagram == &lt;br /&gt;
&lt;br /&gt;
There isn't one. Or rather, there is one, but it's virtual in the sense that no one used it as a design document; rather, it is constructible as a mental model from the observable workings of flightgear itself.`&lt;br /&gt;
&lt;br /&gt;
Part of understanding any body of code is to be able to identify how data flows through the application. Dataflows are usually represented as arrows of various widths. The arrows are messages flowing between parts of an application. The larger the arrow, the more data items in that data flow.  Knowing what is in each of those flows is important to understanding how the application works.  &lt;br /&gt;
&lt;br /&gt;
In FlightGear's C++ code, there are, of course, classes and objects that represent some dataflows. There's a problem, though. Many of the classes are about processing data into ad-hoc structures within the property tree.  How can we define a data flow for these ad-hoc structures?  (Note: need a way to describe two dataflows.  The one that creates the infrastructure as properties in the tree, and a second one implied by the existence of the property.)&lt;br /&gt;
&lt;br /&gt;
There is no C++ class for an Altimeter or a Heading Indicator. Instead, these are represented by a set of properties and data loaded via XML and other formats. The numerical data, stored in the property tree has a path indicating that the properties underneath a node are for the altimeter or the heading indicator. The actual paths in this case are /instrumentation/altimeter and /instrumentation/heading-indicator. Each node in the tree can have properties as child nodes, as well as child nodes that contain additional properties, such as /instrumentation/heading-indicator/gyro. Usually, only the lear nodes of th e tree &lt;br /&gt;
&lt;br /&gt;
Properties are created on the fly, once the property tree's root node is instantiated. Properties are specified in XML data, created by a Nasal script, or by C++ code. The actual property mechanism is implemented in a C++ class.&lt;br /&gt;
&lt;br /&gt;
After they are created, properties are used as needed from Nasal scripts and C++ code, and finally destroyed by a destructor in C++. However, none of that is traceable as a data flow. IDEs are great at connecting elements of code to their definitions and usage, but when we use a data store like the property tree, the connection can't be found by the IDE. These data flows through the property tree mechanisms are a real part of the FlightGear Application, but we have no easy way to visualise them. Any visualization is mentally constructed over time by developers' experiences, as they examine and step through code.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[http://wiki.flightgear.org/User:Callahanp/goals What's up with Pat]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=142014</id>
		<title>User:Callahanp</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=142014"/>
		<updated>2025-06-23T04:49:22Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Me ==&lt;br /&gt;
 &lt;br /&gt;
Hello, my name is Patrick Callahan. People call me Pat. I have a web page, and you found it.&lt;br /&gt;
&lt;br /&gt;
I've been a programmer since I was a teenager. I'm 74 years old and retired now.&lt;br /&gt;
&lt;br /&gt;
Programming was a fun job. We couldn't believe we got paid to have so much fun.&lt;br /&gt;
&lt;br /&gt;
My current expertise primarily lies in databases, bash scripting, and traditional procedural programming in various languages.&lt;br /&gt;
&lt;br /&gt;
C++ is a work in progress. I took a course in 1993, but never used it professionally.  &lt;br /&gt;
&lt;br /&gt;
I like gardening with my wife of 33 years, Ann. We have a daughter who has given us three very active grandchildren, who will visit us next week for four days. Did I say I kept busy? We reside in the state of Massachusetts in the United States.&lt;br /&gt;
&lt;br /&gt;
I hope to make regular code contributions to FlightGear. I want to gain the skills to address some FlightGear issues as they come up and participate in the discussions and programming for the various [FlightGear Epics |https://gitlab.com/groups/flightgear/-/epics?sort=created_date&amp;amp;state=opened&amp;amp;first_page_size=100]&lt;br /&gt;
&lt;br /&gt;
You are about to read a very personal document.  I make statements there that I have not yet validated by discussing these ideas directly with others and trying to put them into practice.  Go easy on me.  Criticize my ideas, not me.  I think this is ok, as the material is buried in a personal web page on a wiki.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
== FlightGear Development: ==&lt;br /&gt;
&lt;br /&gt;
I'm motivated to learn enough C++, Nasal, and whatever else it takes to start regularly contributing to the Flightgear Codebase.  &lt;br /&gt;
&lt;br /&gt;
Someone with practical experience writing, maintaining, and fixing problems in C++ can easily begin contributing to FlightGear's codebase.  They may find a few fine points, such as the internal scripting language and the property tree, but they should be able to navigate with little assistance.  That's not me.  I don't have the practical experience, and my  C++ experience consists mostly of a one-semester class.  Not only that, the class was in the previous century.  Move semantics?  What's That!?&lt;br /&gt;
&lt;br /&gt;
You get the idea:  &amp;quot;Nice goal, Pat.  Good luck with that. You do realize you are 75 years old, don't you?&amp;quot;&lt;br /&gt;
Heedless, I press on.&lt;br /&gt;
&lt;br /&gt;
It should be obvious to all that this kind of endeavour requires a lot of work, and anyone undertaking it is going to need help at various points.  It's easy to get stuck on specific points, and stuck in ways that you don't know which question to ask first, and where to ask it.  You may be able to help.  &lt;br /&gt;
&lt;br /&gt;
== Getting an Giving Help ==&lt;br /&gt;
I want to request assistance in the appropriate forums, having exhausted all possible avenues to explore answers before seeking help. At the same time I want to help others with any code problems they are struggling with. &lt;br /&gt;
 &lt;br /&gt;
I like helping other people.  It's the best way to make friends. &lt;br /&gt;
&lt;br /&gt;
I want you to know that I sometimes help people by listening to them describe a problem, and suggesting a route to finding some small tidbit of information that makes the problem easier to think about. It doesn't always happen, or even often, but when it does, the result seems very satisfying to both parties.  &lt;br /&gt;
&lt;br /&gt;
There are other times when just having me listen attentively to an explanation of a problem is sufficient for the teller to grasp a solution. I don't have to say a word, but they already have the answer.  Helpful, no?  This has happened to me on numerous occasions, more so than me making helpful comments.  Perhaps my asking for a description of the problem and any naive questions I ask about it are enough to get things moving.&lt;br /&gt;
&lt;br /&gt;
If you're stuck on a point and want my help, please don't hesitate to ask me personally on any forum where you encounter me. &lt;br /&gt;
You can find me on Discord as callahanp, on IRC as pac1 (early internet username formed from my initials)&lt;br /&gt;
&lt;br /&gt;
== Teamwork: ==&lt;br /&gt;
I'm a believer in teamwork and would love working closely in real-time with others on specific programming problems. I hope we can create opportunities for that.  I also believe that the only learning environment is not limited to a formal course, which includes lectures, readings, homework, quizzes, tests, and final grades.  Grown-ups use study groups, working groups, collaborators, publications, conferences, and prior work. And they take formal courses from time to time.&lt;br /&gt;
&lt;br /&gt;
== Pair programming ==&lt;br /&gt;
&lt;br /&gt;
I find pair programming an attractive idea and wonder how it works in practice. What is the result of practicing pair programming with programmers of similar skills? What happens when an expert programmer pairs with an inexperienced one?&lt;br /&gt;
&lt;br /&gt;
I find that most are resistant to participating in pair programming, and I wonder why.  &lt;br /&gt;
&lt;br /&gt;
We're taught in academic settings to program by ourselves and hand in ou submissions for review as &amp;quot;homework&amp;quot;, but we continue that pattern in our work mainly out of inertia and lack of proper training. There's no reason to continue that pattern outside of a classroom as our only or even as main way of working together. &lt;br /&gt;
&lt;br /&gt;
== Understanding FlightGear's Large &amp;amp; Complex Codebase ==&lt;br /&gt;
&lt;br /&gt;
The problem with FlightGear is its size, complexity, and the lack of a detailed guide to exploring that complexity. Several factors contribute to that complexity. Understanding FlightGear requires knowledge of many application domains, C++, an internal scripting language, a global data store, application features driven by XML or scripts, network protocols and data formats, some custom, some obscure, and from the era of mainframe computers.&lt;br /&gt;
&lt;br /&gt;
I'll examine each of these complexity realms with a view to providing a guideline for new FlightGear developers, me for instance, a path to follow leading to regular contributions to the FlightGear in C++, Nasal, and XML and other data formats.&lt;br /&gt;
&lt;br /&gt;
== C++ ==&lt;br /&gt;
&lt;br /&gt;
  First, the application uses C++. As a complex and evolving language, C++ has a reputation for being complex. It's not just the language, its the fragmentation of code into small tidbits, widely scattered in individual files covering supposedly just one aspect of what needs to be done. I don't really know if the structure of C++ code as objects is more efficient than a C++ program done using solid structured programming, but I know which is easier think about and to work on.&lt;br /&gt;
&lt;br /&gt;
== Flight Simulation does a lot of different things == &lt;br /&gt;
&lt;br /&gt;
Second, Flight Simulation involves numerous application domains. Among them are aerodynamics, graphics, geography, geodesy, environment, navigation, networks, audio, video, and human languages. FlightGear addresses all of them and more. Each of these domains has its own view of the world, and many of them are modelled as C++ classes. Full understanding comes from knowing the C++ code, the terminology of the domain, and the way the code's authors chose to structure things as objects and methods.  &lt;br /&gt;
&lt;br /&gt;
== Nasal and the Property Tree ==&lt;br /&gt;
&lt;br /&gt;
Next, in addition to the complexity introduced by C++ and the application domains, there's Nasal. Finally, to tie it all together, loosely, the property tree. a global object, with individual data items of a key-value store actually stored in a tree because they are conceptually related. The property tree introduced complexity because items in it are not &amp;quot;owned&amp;quot;, they're simply created at some point, in either C++, XML processing, or Nasal, and used wherever the data item is &amp;quot;needed&amp;quot;. Connecting the dots through all the code based on identifying individual properties is not all that easy.&lt;br /&gt;
&lt;br /&gt;
== Where should I start? C++, Nasal or XML) ==&lt;br /&gt;
&lt;br /&gt;
It's not clear from existing documentation the central role of Nasal scripting and the Property Tree are in the simulation. It's not just C++, Nasal, and the interface between them, understood as computer languages.   Knowing the languages and interfaces themselves is vital, but even more important is understanding how scripting is used in FlightGear to create the simulation. If you are struggling as a newcomer to understand FlightGear's C++ code, understanding Nasal's role in driving parts of the simulation and the way it interacts with C++ code is probably one of the first things to do. It's what I'll be doing next.&lt;br /&gt;
&lt;br /&gt;
== FlightGear's DataFlow Diagram == &lt;br /&gt;
&lt;br /&gt;
There isn't one. Or rather, there is one, but it's virtual in the sense that no one used it as a design document; rather, it is constructible as a mental model from the observable workings of flightgear itself.`&lt;br /&gt;
&lt;br /&gt;
Part of understanding any body of code is to be able to identify how data flows through the application. Dataflows are usually represented as arrows of various widths. The arrows are messages flowing between parts of an application. The larger the arrow, the more data items in that data flow.  Knowing what is in each of those flows is important to understanding how the application works.  &lt;br /&gt;
&lt;br /&gt;
In FlightGear's C++ code, there are, of course, classes and objects that represent some dataflows. There's a problem, though. Many of the classes are about processing data into ad-hoc structures within the property tree.  How can we define a data flow for these ad-hoc structures?  (Note: need a way to describe two dataflows.  The one that creates the infrastructure as properties in the tree, and a second one implied by the existence of the property.)&lt;br /&gt;
&lt;br /&gt;
There is no C++ class for an Altimeter or a Heading Indicator. Instead, these are represented by a set of properties and data loaded via XML and other formats. The numerical data, stored in the property tree has a path indicating that the properties underneath a node are for the altimeter or the heading indicator. The actual paths in this case are /instrumentation/altimeter and /instrumentation/heading-indicator. Each node in the tree can have properties as child nodes, as well as child nodes that contain additional properties, such as /instrumentation/heading-indicator/gyro. Usually, only the lear nodes of th e tree &lt;br /&gt;
&lt;br /&gt;
Properties are created on the fly, once the property tree's root node is instantiated. Properties are specified in XML data, created by a Nasal script, or by C++ code. The actual property mechanism is implemented in a C++ class.&lt;br /&gt;
&lt;br /&gt;
After they are created, properties are used as needed from Nasal scripts and C++ code, and finally destroyed by a destructor in C++. However, none of that is traceable as a data flow. IDEs are great at connecting elements of code to their definitions and usage, but when we use a data store like the property tree, the connection can't be found by the IDE. These data flows through the property tree mechanisms are a real part of the FlightGear Application, but we have no easy way to visualise them. Any visualization is mentally constructed over time by developers' experiences, as they examine and step through code.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[http://wiki.flightgear.org/User:Callahanp/goals What's up with Pat]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=142013</id>
		<title>User:Callahanp</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=142013"/>
		<updated>2025-06-23T04:24:18Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Me ==&lt;br /&gt;
 &lt;br /&gt;
Hello, my name is Patrick Callahan. People call me Pat. I have a web page, and you found it.&lt;br /&gt;
&lt;br /&gt;
I've been a programmer since I was a teenager. I'm 74 years old and retired now.&lt;br /&gt;
&lt;br /&gt;
Programming was a fun job. We couldn't believe we got paid to have so much fun.&lt;br /&gt;
&lt;br /&gt;
My current expertise primarily lies in databases, bash scripting, and traditional procedural programming in various languages.&lt;br /&gt;
&lt;br /&gt;
C++ is a work in progress. I took a course in 1993, but never used it professionally.  &lt;br /&gt;
&lt;br /&gt;
I like gardening with my wife of 33 years, Ann. We have a daughter who has given us three very active grandchildren, who will visit us next week for four days. Did I say I kept busy? We reside in the state of Massachusetts in the United States.&lt;br /&gt;
&lt;br /&gt;
I hope to make regular code contributions to FlightGear. I want to gain the skills to address some FlightGear issues as they come up and participate in the discussions and programming for the various [FlightGear Epics |https://gitlab.com/groups/flightgear/-/epics?sort=created_date&amp;amp;state=opened&amp;amp;first_page_size=100]&lt;br /&gt;
&lt;br /&gt;
== FlightGear Development: ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I'm motivated to learn enough C++, Nasal and whatever else it takes to start regularly contributing to the Flightgear Codebase.  &lt;br /&gt;
&lt;br /&gt;
Someone with practical experience writing, maintaining and fixing problems in C++ can easily begin contributing to FlightGear's codebase.  They may find there are a few fine points such as the internal scripting language and the property tree, but they should be able to find their way with a little assistance.  That's not me.  I don't have the practical experience and my c++ experience consists mostly of a one semester class.  Not only that, the class was in the previous century.  Move semantics?  What's That!?&lt;br /&gt;
You get the idea:  &amp;quot;Nice goal, Pat.  Good luck with that. You do realize you are 75 years old don't you?&amp;quot;&lt;br /&gt;
Heedless, I press on.&lt;br /&gt;
It should be obvious to all that this kind of endeavour requires a lot of work, and anyone undertaking it is going to need help at various points.  It's easy to get stuck on specific points, and stuck in ways that you don't know which question to ask first and where to ask it.  You may be able to help.  &lt;br /&gt;
&lt;br /&gt;
== Getting an Giving Help ==&lt;br /&gt;
I want to ask for help in the appropriate forums, having done all I can to explore answers before asking. At the same time I want to help others with any code problems they are struggling with.  &lt;br /&gt;
I like helping other people.  It's the best way toward friendship. &lt;br /&gt;
I want you to know that I sometimes help people by listening to them describe a problem, and suggesting a route to finding some small tidbit of information that makes the problem easier to think about.  It doesn't always happen, or even often, but when it does the result seems very satisfying to both parties.  &lt;br /&gt;
There are other times when just having me listen attentively to and explanation of a problem is sufficient for the teller to grasp a solution. I don't have to say a word, but thay already have the answer.  Helpful, no?  This has happened to me on numerous occasions, more so than me making helpful comments.  Perhaps my asking for a  description the problem and any naieve questions I ask about it are enough to get things moving.&lt;br /&gt;
So if stuck on some point and you want my help, just ask me personally, on any forum you encounter me on. &lt;br /&gt;
You can find me on discord as callahanp, on irc as pac1 (early internet username formed from my initials)&lt;br /&gt;
&lt;br /&gt;
== Teamwork: ==&lt;br /&gt;
I'm a believer in teamwork and would love working closely in real-time with others on specific programming problems. I hope we can create opportunities for that.  I also believe the only learning environment is not a formal course: lecture, reading, homework, quizzes, tests and final grades.  Grownups use study groups, working groups, collaborators, publication, journal reading, conferences and work. And they take formal courses from time to time.&lt;br /&gt;
&lt;br /&gt;
== Pair programming ==&lt;br /&gt;
&lt;br /&gt;
I find pair programming an attractive idea and wonder how it works in practice. What is the result of practicing pair programming with programmers of similar skills? What happens when an expert programmer pairs with an inexperienced one?&lt;br /&gt;
&lt;br /&gt;
I find that most are resistant to participating in pair programming, and I wonder why.  &lt;br /&gt;
&lt;br /&gt;
We're taught in academic settings to program by ourselves and hand in ou submissions for review as &amp;quot;homework&amp;quot;, but we continue that pattern in our work mainly out of inertia and lack of proper training. There's no reason to continue that pattern outside of a classroom as our only or even as main way of working together. &lt;br /&gt;
&lt;br /&gt;
== Understanding FlightGear's Large &amp;amp; Complex Codebase ==&lt;br /&gt;
&lt;br /&gt;
The problem with FlightGear is its size, complexity, and the lack of a detailed guide to exploring that complexity. Several factors contribute to that complexity. Understanding FlightGear requires knowledge of many application domains, C++, an internal scripting language, a global data store, application features driven by XML or scripts, network protocols and data formats, some custom, some obscure, and from the era of mainframe computers.&lt;br /&gt;
&lt;br /&gt;
I'll examine each of these complexity realms with a view to providing a guideline for new FlightGear developers, me for instance, a path to follow leading to regular contributions to the FlightGear in C++, Nasal, and XML and other data formats.&lt;br /&gt;
&lt;br /&gt;
== C++ ==&lt;br /&gt;
&lt;br /&gt;
  First, the application uses C++. As a complex evolving language, C++ has a reputation for complexity. It's not just the language, its the fragmentation of code into small tidbits, widely scattered in individual files covering supposedly just one aspect of what needs to be done. I don't really know if the structure of C++ code as objects is more efficient than a C++ program done using solid structured programming, but I know which is easier think about and to work on.&lt;br /&gt;
&lt;br /&gt;
== Flight Simulation does a lot of different things == &lt;br /&gt;
&lt;br /&gt;
Second, Flight Simulation involves numerous application domains. Among them are aerodynamics, graphics, geography, geodesy, environment, navigation, networks, audio, video, and human languages. FlightGear addresses all of them and more. Each of these domains has their own view of the world, and many of them are modelled as C++ classes. Full understanding comes from knowing the C++ code, The terminolgy of the domain, and the way the code's authors chose to structure things as objects and methods.  &lt;br /&gt;
&lt;br /&gt;
== Nasal and the Property Tree ==&lt;br /&gt;
&lt;br /&gt;
Next, in addition to the complexity introduced by C++ and the application domains, there's Nasal. Finally, to tie it all together, loosely, the property tree. a global object, with individual data items of a key-value store actually stored in a tree because they are conceptually related. The property tree introduced compexity because items in it are not &amp;quot;owned&amp;quot;, they're simply created at some point, in either C++, XML processing or Nasal and used wherever the data item is &amp;quot;needed&amp;quot;. Connecting the dots through all the code based on identifying individual properties is not all that easy.&lt;br /&gt;
&lt;br /&gt;
== Where should I start? C++, Nasal or XML) ==&lt;br /&gt;
&lt;br /&gt;
It's not clear from existing documentation the central role of Nasal scripting and the Property Tree are in the simulation. It's not just C++, Nasal, and the interface between them, understood as computer languages.   Knowing the languages and interfaces themselves is vital, but even more important is understanding how scripting is used in FlightGear to create the simulation. If you are struggling as a newcomer to understand FlightGear's C++ code, understanding Nasal's role in driving parts of the simulation and the way it interacts with C++ code is probably one of the first things to do. It's what I'll be doing next.&lt;br /&gt;
&lt;br /&gt;
== FlightGear's DataFlow Diagram == &lt;br /&gt;
&lt;br /&gt;
There isn't one. Or rather there is one, but it's virtual in the sense that no-one used it as a design, document, rather it is constructable from the observable workings of flightgear itself.`&lt;br /&gt;
&lt;br /&gt;
Part of understanding any body of code is to be able to identify how data flows through the application. Dataflows are usually represented as arrows of various widths. The arrows are messages flowing between parts of an application. The larger the arrow, the more data items in that data flow.  Knowing what is in each of those flows is important to understanding how the application works.  &lt;br /&gt;
&lt;br /&gt;
In FlightGear's C++ code, there are, of course, classes and objects that represent some dataflows. There's a problem, though. Many of the classes are about processing data into ad-hoc structures within the property tree.  How can we define a data flog for these items.  There is one implied by the instantiation and use of these run time These define a While these are dataflows, they are only infrastructure.  The content of these infrastructure data flows are simply allocations of indivual data items that are the sources and sinks of   These items are the content of the actual data flows between subsysems in Flightgear. &lt;br /&gt;
&lt;br /&gt;
There is no C++ class for an Altimeter or a Heading Indicator. Instead, these are represented by a set of properties and data loaded via XML and other formats. The numerical data, stored in the property tree has a path indicating that the properties underneath a node are for the altimeter or the heading indicator. The actual paths in this case are /instrumentation/altimeter and /instrumentation/heading-indicator. Each node in the tree can have properties as child nodes, as well as child nodes that contain additional properties, such as /instrumentation/heading-indicator/gyro. Usually, only the lear nodes of th e tree &lt;br /&gt;
&lt;br /&gt;
Properties are created on the fly, once the property tree's root node is instantiated. Properties are specified in XML data, created by a Nasal script, or by C++ code. The actual property mechanism is implemented in a C++ class.&lt;br /&gt;
&lt;br /&gt;
After they are created, properties are used as needed from Nasal scripts and C++ code, and finally destroyed by a destructor in C++. However, none of that is traceable as a data flow. IDEs are great at connecting elements of code to their definitions and usage, but when we use a data store like the property tree, the connection can't be found by the IDE. These data flows through the property tree mechanisms are a real part of the FlightGear Application, but we have no easy way to visualise them. Any visualization is mentally constructed over time by developers' experiences, as they examine and step through code.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[http://wiki.flightgear.org/User:Callahanp/goals What's up with Pat]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=142011</id>
		<title>User:Callahanp</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=142011"/>
		<updated>2025-06-22T13:10:45Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Me ==&lt;br /&gt;
 &lt;br /&gt;
Hello, my name is Patrick Callahan. People call me Pat. I have a web page, and you found it.&lt;br /&gt;
&lt;br /&gt;
I've been a programmer since I was a teenager. I'm 74 years old and retired now.&lt;br /&gt;
&lt;br /&gt;
Programming was a fun job. We couldn't believe we got paid to have so much fun.&lt;br /&gt;
&lt;br /&gt;
My current expertise primarily lies in databases, bash scripting, and traditional procedural programming in various languages.&lt;br /&gt;
&lt;br /&gt;
C++ is a work in progress. I took a course in 1993, but never used it professionally.  &lt;br /&gt;
&lt;br /&gt;
I like gardening with my wife of 33 years, Ann. We have a daughter who has given us three very active grandchildren, who will visit us next week for four days. Did I say I kept busy? We reside in the state of Massachusetts in the United States.&lt;br /&gt;
&lt;br /&gt;
I hope to make regular code contributions to FlightGear. I want to gain the skills to address some FlightGear issues as they come up and participate in the discussions and programming for the various [FlightGear Epics |https://gitlab.com/groups/flightgear/-/epics?sort=created_date&amp;amp;state=opened&amp;amp;first_page_size=100]&lt;br /&gt;
&lt;br /&gt;
== Teamwork: ==&lt;br /&gt;
I'm a believer in teamwork and would love working closely in real-time with others on specific programming problems. I hope we can create opportunities for that.&lt;br /&gt;
&lt;br /&gt;
== Pair programming ==&lt;br /&gt;
&lt;br /&gt;
I find pair programming an attractive idea and wonder how it works in practice. What is the result of practicing pair programming with programmers of similar skills? What happens when an expert programmer pairs with an inexperienced one?&lt;br /&gt;
&lt;br /&gt;
I find that most are resistant to participating in pair programming, and I wonder why.  &lt;br /&gt;
&lt;br /&gt;
We're taught in academic settings to program by ourselves and hand in ou submissions for review as &amp;quot;homework&amp;quot;, but we continue that pattern in our work mainly out of inertia and lack of proper training. There's no reason to continue that pattern outside of a classroom as our only or even as main way of working together. &lt;br /&gt;
&lt;br /&gt;
== Understanding FlightGear's Large &amp;amp; Complex Codebase ==&lt;br /&gt;
&lt;br /&gt;
The problem with FlightGear is its size, complexity, and the lack of a detailed guide to exploring that complexity. Several factors contribute to that complexity. Understanding FlightGear requires knowledge of many application domains, C++, an internal scripting language, a global data store, application features driven by XML or scripts, network protocols and data formats, some custom, some obscure, and from the era of mainframe computers.&lt;br /&gt;
&lt;br /&gt;
I'll examine each of these complexity realms with a view to providing a guideline for new FlightGear developers, me for instance, a path to follow leading to regular contributions to the FlightGear in C++, Nasal, and XML and other data formats.&lt;br /&gt;
&lt;br /&gt;
== C++ ==&lt;br /&gt;
&lt;br /&gt;
  First, the application uses C++. As a complex evolving language, C++ has a reputation for complexity. It's not just the language, its the fragmentation of code into small tidbits, widely scattered in individual files covering supposedly just one aspect of what needs to be done. I don't really know if the structure of C++ code as objects is more efficient than a C++ program done using solid structured programming, but I know which is easier think about and to work on.&lt;br /&gt;
&lt;br /&gt;
== Flight Simulation does a lot of different things == &lt;br /&gt;
&lt;br /&gt;
Second, Flight Simulation involves numerous application domains. Among them are aerodynamics, graphics, geography, geodesy, environment, navigation, networks, audio, video, and human languages. FlightGear addresses all of them and more. Each of these domains has their own view of the world, and many of them are modelled as C++ classes. Full understanding comes from knowing the C++ code, The terminolgy of the domain, and the way the code's authors chose to structure things as objects and methods.  &lt;br /&gt;
&lt;br /&gt;
== Nasal and the Property Tree ==&lt;br /&gt;
&lt;br /&gt;
Next, in addition to the complexity introduced by C++ and the application domains, there's Nasal. Finally, to tie it all together, loosely, the property tree. a global object, with individual data items of a key-value store actually stored in a tree because they are conceptually related. The property tree introduced compexity because items in it are not &amp;quot;owned&amp;quot;, they're simply created at some point, in either C++, XML processing or Nasal and used wherever the data item is &amp;quot;needed&amp;quot;. Connecting the dots through all the code based on identifying individual properties is not all that easy.&lt;br /&gt;
&lt;br /&gt;
== Where should I start? C++, Nasal or XML) ==&lt;br /&gt;
&lt;br /&gt;
It's not clear from existing documentation the central role of Nasal scripting and the Property Tree are in the simulation. It's not just C++, Nasal, and the interface between them, understood as computer languages.   Knowing the languages and interfaces themselves is vital, but even more important is understanding how scripting is used in FlightGear to create the simulation. If you are struggling as a newcomer to understand FlightGear's C++ code, understanding Nasal's role in driving parts of the simulation and the way it interacts with C++ code is probably one of the first things to do. It's what I'll be doing next.&lt;br /&gt;
&lt;br /&gt;
== FlightGear's DataFlow Diagram == &lt;br /&gt;
&lt;br /&gt;
There isn't one. Or rather there is one, but it's virtual in the sense that no-one used it as a design, document, rather it is constructable from the observable workings of flightgear itself.`&lt;br /&gt;
&lt;br /&gt;
Part of understanding any body of code is to be able to identify how data flows through the application. Dataflows are usually represented as arrows of various widths. The arrows are messages flowing between parts of an application. The larger the arrow, the more data items in that data flow.  Knowing what is in each of those flows is important to understanding how the application works.  &lt;br /&gt;
&lt;br /&gt;
In FlightGear's C++ code, there are, of course, classes and objects that represent some dataflows. There's a problem, though. Many of the classes are about processing data into ad-hoc structures within the property tree.  How can we define a data flog for these items.  There is one implied by the instantiation and use of these run time These define a While these are dataflows, they are only infrastructure.  The content of these infrastructure data flows are simply allocations of indivual data items that are the sources and sinks of   These items are the content of the actual data flows between subsysems in Flightgear. &lt;br /&gt;
&lt;br /&gt;
There is no C++ class for an Altimeter or a Heading Indicator. Instead, these are represented by a set of properties and data loaded via XML and other formats. The numerical data, stored in the property tree has a path indicating that the properties underneath a node are for the altimeter or the heading indicator. The actual paths in this case are /instrumentation/altimeter and /instrumentation/heading-indicator. Each node in the tree can have properties as child nodes, as well as child nodes that contain additional properties, such as /instrumentation/heading-indicator/gyro. Usually, only the lear nodes of th e tree &lt;br /&gt;
&lt;br /&gt;
Properties are created on the fly, once the property tree's root node is instantiated. Properties are specified in XML data, created by a Nasal script, or by C++ code. The actual property mechanism is implemented in a C++ class.&lt;br /&gt;
&lt;br /&gt;
After they are created, properties are used as needed from Nasal scripts and C++ code, and finally destroyed by a destructor in C++. However, none of that is traceable as a data flow. IDEs are great at connecting elements of code to their definitions and usage, but when we use a data store like the property tree, the connection can't be found by the IDE. These data flows through the property tree mechanisms are a real part of the FlightGear Application, but we have no easy way to visualise them. Any visualization is mentally constructed over time by developers' experiences, as they examine and step through code.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[http://wiki.flightgear.org/User:Callahanp/goals What's up with Pat]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=142010</id>
		<title>User:Callahanp</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=142010"/>
		<updated>2025-06-21T22:41:05Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: /* Teamwork: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Me ==&lt;br /&gt;
 &lt;br /&gt;
Hello, my name is Patrick Callahan. People call me Pat. I have a web page, and you found it.&lt;br /&gt;
&lt;br /&gt;
I've been a programmer since I was a teenager. I'm 74 years old and retired now.&lt;br /&gt;
&lt;br /&gt;
Programming was a fun job. We couldn't believe we got paid to have so much fun.&lt;br /&gt;
&lt;br /&gt;
My current expertise primarily lies in databases, bash scripting, and traditional procedural programming in various languages.&lt;br /&gt;
&lt;br /&gt;
C++ is a work in progress. I took a course in 1993, but never used it professionally.  &lt;br /&gt;
&lt;br /&gt;
I like gardening with my wife of 33 years, Ann. We have a daughter who has given us three very active grandchildren, who will visit us next week for four days. Did I say I kept busy? We reside in the state of Massachusetts in the United States.&lt;br /&gt;
&lt;br /&gt;
I hope to make regular code contributions to FlightGear. I want to gain the skills to address some FlightGear issues as they come up and participate in the discussions and programming for the various [FlightGear Epics |https://gitlab.com/groups/flightgear/-/epics?sort=created_date&amp;amp;state=opened&amp;amp;first_page_size=100]&lt;br /&gt;
&lt;br /&gt;
== Teamwork: ==&lt;br /&gt;
I'm a believer in teamwork and would love working closely in real-time with others on specific programming problems. I hope we can create opportunities for that.&lt;br /&gt;
&lt;br /&gt;
== Pair programming ==&lt;br /&gt;
&lt;br /&gt;
I find pair programming an attractive idea and wonder how it works in practice. What is the result of practicing pair programming with programmers of similar skills? What happens when an expert programmer pairs with an inexperienced one?&lt;br /&gt;
&lt;br /&gt;
I find that most are resistant to participating in pair programming, and I wonder why.  &lt;br /&gt;
&lt;br /&gt;
We're taught in academic settings to program by ourselves and hand in ou submissions for review as &amp;quot;homework&amp;quot;, but we continue that pattern in our work mainly out of inertia and lack of proper training. There's no reason to continue that pattern outside of a classroom as our only or even as main way of working together. &lt;br /&gt;
&lt;br /&gt;
== Understanding FlightGear's Large &amp;amp; Complex Codebase ==&lt;br /&gt;
&lt;br /&gt;
The problem with FlightGear is its size, complexity, and the lack of a detailed guide to exploring that complexity. Several factors contribute to that complexity. Understanding FlightGear requires knowledge of many application domains, C++, an internal scripting language, a global data store, application features driven by XML or scripts, network protocols and data formats, some custom, some obscure, and from the era of mainframe computers.&lt;br /&gt;
&lt;br /&gt;
I'll examine each of these complexity realms with a view to providing a guideline for new FlightGear developers, me for instance, a path to follow leading to regular contributions to the FlightGear in C++, Nasal, and XML and other data formats.&lt;br /&gt;
&lt;br /&gt;
== C++ ==&lt;br /&gt;
&lt;br /&gt;
  First, the application uses C++. As a complex evolving language, C++ has a reputation for complexity. It's not just the language, its the fragmentation of code into small tidbits, widely scattered in individual files covering supposedly just one aspect of what needs to be done. I don't really know if the structure of C++ code as objects is more efficient than a C++ program done using solid structured programming, but I know which is easier think about and to work on.&lt;br /&gt;
&lt;br /&gt;
== Flight Simulation does a lot of different things == &lt;br /&gt;
&lt;br /&gt;
Second, Flight Simulation involves numerous application domains. Among them are aerodynamics, graphics, geography, geodesy, environment, navigation, networks, audio, video, and human languages. FlightGear addresses all of them and more. Each of these domains has their own view of the world, and many of them are modelled as C++ classes. Full understanding comes from knowing the C++ code, The terminolgy of the domain, and the way the code's authors chose to structure things as objects and methods.  &lt;br /&gt;
&lt;br /&gt;
== Nasal and the Property Tree ==&lt;br /&gt;
&lt;br /&gt;
Next, in addition to the complexity introduced by C++ and the application domains, there's Nasal. Finally, to tie it all together, loosely, the property tree. a global object, with individual data items of a key-value store actually stored in a tree because they are conceptually related. The property tree introduced compexity because items in it are not &amp;quot;owned&amp;quot;, they're simply created at some point, in either C++, XML processing or Nasal and used wherever the data item is &amp;quot;needed&amp;quot;. Connecting the dots through all the code based on identifying individual properties is not all that easy.&lt;br /&gt;
&lt;br /&gt;
== Where should I start? C++, Nasal or XML) ==&lt;br /&gt;
&lt;br /&gt;
It's not clear from existing documentation the central role of Nasal scripting and the Property Tree are in the simulation. It's not just C++, Nasal, and the interface between them, understood as computer languages.   Knowing the languages and interfaces themselves is vital, but even more important is understanding how scripting is used in FlightGear to create the simulation. If you are struggling as a newcomer to understand FlightGear's C++ code, understanding Nasal's role in driving parts of the simulation and the way it interacts with C++ code is probably one of the first things to do. It's what I'll be doing next.&lt;br /&gt;
&lt;br /&gt;
== FlightGear's DataFlow Diagram == &lt;br /&gt;
&lt;br /&gt;
There isn't one.&lt;br /&gt;
&lt;br /&gt;
Part of understanding any body of code is to be able to identify how data flows through the application. Dataflows are usually represented as arrows of various widths. The arrows are messages flowing between parts of an application. The larger the arrow, the more data items in that data flow.  &lt;br /&gt;
&lt;br /&gt;
In FlightGear's C++ code, there are, of course, classes and objects that represent some dataflows. There's a problem, though. Many of the classes are about processing data into ad-hoc structures within the property tree. &lt;br /&gt;
&lt;br /&gt;
There is no C++ class for an Altimeter or a Heading Indicator. Instead, these are represented by a set of properties and data loaded via XML and other formats. The numerical data, stored in the property tree has a path indicating that the properties underneath a node are for the altimeter or the heading indicator. The actual paths in this case are /instrumentation/altimeter and /instrumentation/heading-indicator. Each node in the tree can have properties as child nodes, as well as child nodes that contain additional properties, such as /instrumentation/heading-indicator/gyro. Usually, only the lear nodes of th e tree &lt;br /&gt;
&lt;br /&gt;
Properties are created on the fly, once the property tree's root node is instantiated. Properties are specified in XML data, created by a Nasal script, or by C++ code. The actual property mechanism is implemented in a C++ class.&lt;br /&gt;
&lt;br /&gt;
After they are created, properties are used as needed from Nasal scripts and C++ code, and finally destroyed by a destructor in C++. However, none of that is traceable as a data flow. IDEs are great at connecting elements of code to their definitions and usage, but when we use a data store like the property tree, the connection can't be found by the IDE. These data flows through the property tree mechanisms are a real part of the FlightGear Application, but we have no easy way to visualise them. Any visualization is mentally constructed over time by developers' experiences, as they examine and step through code.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[http://wiki.flightgear.org/User:Callahanp/goals What's up with Pat]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=142009</id>
		<title>User:Callahanp</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=142009"/>
		<updated>2025-06-21T22:40:45Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Me ==&lt;br /&gt;
 &lt;br /&gt;
Hello, my name is Patrick Callahan. People call me Pat. I have a web page, and you found it.&lt;br /&gt;
&lt;br /&gt;
I've been a programmer since I was a teenager. I'm 74 years old and retired now.&lt;br /&gt;
&lt;br /&gt;
Programming was a fun job. We couldn't believe we got paid to have so much fun.&lt;br /&gt;
&lt;br /&gt;
My current expertise primarily lies in databases, bash scripting, and traditional procedural programming in various languages.&lt;br /&gt;
&lt;br /&gt;
C++ is a work in progress. I took a course in 1993, but never used it professionally.  &lt;br /&gt;
&lt;br /&gt;
I like gardening with my wife of 33 years, Ann. We have a daughter who has given us three very active grandchildren, who will visit us next week for four days. Did I say I kept busy? We reside in the state of Massachusetts in the United States.&lt;br /&gt;
&lt;br /&gt;
I hope to make regular code contributions to FlightGear. I want to gain the skills to address some FlightGear issues as they come up and participate in the discussions and programming for the various [FlightGear Epics |https://gitlab.com/groups/flightgear/-/epics?sort=created_date&amp;amp;state=opened&amp;amp;first_page_size=100]&lt;br /&gt;
&lt;br /&gt;
=== Teamwork: ===&lt;br /&gt;
I'm a believer in teamwork and would love working closely in real-time with others on specific programming problems. I hope we can create opportunities for that. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Pair programming ==&lt;br /&gt;
&lt;br /&gt;
I find pair programming an attractive idea and wonder how it works in practice. What is the result of practicing pair programming with programmers of similar skills? What happens when an expert programmer pairs with an inexperienced one?&lt;br /&gt;
&lt;br /&gt;
I find that most are resistant to participating in pair programming, and I wonder why.  &lt;br /&gt;
&lt;br /&gt;
We're taught in academic settings to program by ourselves and hand in ou submissions for review as &amp;quot;homework&amp;quot;, but we continue that pattern in our work mainly out of inertia and lack of proper training. There's no reason to continue that pattern outside of a classroom as our only or even as main way of working together. &lt;br /&gt;
&lt;br /&gt;
== Understanding FlightGear's Large &amp;amp; Complex Codebase ==&lt;br /&gt;
&lt;br /&gt;
The problem with FlightGear is its size, complexity, and the lack of a detailed guide to exploring that complexity. Several factors contribute to that complexity. Understanding FlightGear requires knowledge of many application domains, C++, an internal scripting language, a global data store, application features driven by XML or scripts, network protocols and data formats, some custom, some obscure, and from the era of mainframe computers.&lt;br /&gt;
&lt;br /&gt;
I'll examine each of these complexity realms with a view to providing a guideline for new FlightGear developers, me for instance, a path to follow leading to regular contributions to the FlightGear in C++, Nasal, and XML and other data formats.&lt;br /&gt;
&lt;br /&gt;
== C++ ==&lt;br /&gt;
&lt;br /&gt;
  First, the application uses C++. As a complex evolving language, C++ has a reputation for complexity. It's not just the language, its the fragmentation of code into small tidbits, widely scattered in individual files covering supposedly just one aspect of what needs to be done. I don't really know if the structure of C++ code as objects is more efficient than a C++ program done using solid structured programming, but I know which is easier think about and to work on.&lt;br /&gt;
&lt;br /&gt;
== Flight Simulation does a lot of different things == &lt;br /&gt;
&lt;br /&gt;
Second, Flight Simulation involves numerous application domains. Among them are aerodynamics, graphics, geography, geodesy, environment, navigation, networks, audio, video, and human languages. FlightGear addresses all of them and more. Each of these domains has their own view of the world, and many of them are modelled as C++ classes. Full understanding comes from knowing the C++ code, The terminolgy of the domain, and the way the code's authors chose to structure things as objects and methods.  &lt;br /&gt;
&lt;br /&gt;
== Nasal and the Property Tree ==&lt;br /&gt;
&lt;br /&gt;
Next, in addition to the complexity introduced by C++ and the application domains, there's Nasal. Finally, to tie it all together, loosely, the property tree. a global object, with individual data items of a key-value store actually stored in a tree because they are conceptually related. The property tree introduced compexity because items in it are not &amp;quot;owned&amp;quot;, they're simply created at some point, in either C++, XML processing or Nasal and used wherever the data item is &amp;quot;needed&amp;quot;. Connecting the dots through all the code based on identifying individual properties is not all that easy.&lt;br /&gt;
&lt;br /&gt;
== Where should I start? C++, Nasal or XML) ==&lt;br /&gt;
&lt;br /&gt;
It's not clear from existing documentation the central role of Nasal scripting and the Property Tree are in the simulation. It's not just C++, Nasal, and the interface between them, understood as computer languages.   Knowing the languages and interfaces themselves is vital, but even more important is understanding how scripting is used in FlightGear to create the simulation. If you are struggling as a newcomer to understand FlightGear's C++ code, understanding Nasal's role in driving parts of the simulation and the way it interacts with C++ code is probably one of the first things to do. It's what I'll be doing next.&lt;br /&gt;
&lt;br /&gt;
== FlightGear's DataFlow Diagram == &lt;br /&gt;
&lt;br /&gt;
There isn't one.&lt;br /&gt;
&lt;br /&gt;
Part of understanding any body of code is to be able to identify how data flows through the application. Dataflows are usually represented as arrows of various widths. The arrows are messages flowing between parts of an application. The larger the arrow, the more data items in that data flow.  &lt;br /&gt;
&lt;br /&gt;
In FlightGear's C++ code, there are, of course, classes and objects that represent some dataflows. There's a problem, though. Many of the classes are about processing data into ad-hoc structures within the property tree. &lt;br /&gt;
&lt;br /&gt;
There is no C++ class for an Altimeter or a Heading Indicator. Instead, these are represented by a set of properties and data loaded via XML and other formats. The numerical data, stored in the property tree has a path indicating that the properties underneath a node are for the altimeter or the heading indicator. The actual paths in this case are /instrumentation/altimeter and /instrumentation/heading-indicator. Each node in the tree can have properties as child nodes, as well as child nodes that contain additional properties, such as /instrumentation/heading-indicator/gyro. Usually, only the lear nodes of th e tree &lt;br /&gt;
&lt;br /&gt;
Properties are created on the fly, once the property tree's root node is instantiated. Properties are specified in XML data, created by a Nasal script, or by C++ code. The actual property mechanism is implemented in a C++ class.&lt;br /&gt;
&lt;br /&gt;
After they are created, properties are used as needed from Nasal scripts and C++ code, and finally destroyed by a destructor in C++. However, none of that is traceable as a data flow. IDEs are great at connecting elements of code to their definitions and usage, but when we use a data store like the property tree, the connection can't be found by the IDE. These data flows through the property tree mechanisms are a real part of the FlightGear Application, but we have no easy way to visualise them. Any visualization is mentally constructed over time by developers' experiences, as they examine and step through code.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[http://wiki.flightgear.org/User:Callahanp/goals What's up with Pat]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=142008</id>
		<title>User:Callahanp</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=142008"/>
		<updated>2025-06-21T22:38:32Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Me ==&lt;br /&gt;
 &lt;br /&gt;
Hello, my name is Patrick Callahan. People call me Pat. I have a web page, and you found it.&lt;br /&gt;
&lt;br /&gt;
I've been a programmer since I was a teenager. I'm 74 years old and retired now.&lt;br /&gt;
&lt;br /&gt;
Programming was a fun job. We couldn't believe we got paid to have so much fun.&lt;br /&gt;
&lt;br /&gt;
My current expertise primarily lies in databases, bash scripting, and traditional procedural programming in various languages.&lt;br /&gt;
&lt;br /&gt;
C++ is a work in progress. I took a course in 1993, but never used it professionally.  &lt;br /&gt;
&lt;br /&gt;
I like gardening with my wife of 33 years, Ann. We have a daughter who has given us three very active grandchildren, who will visit us next week for four days. Did I say I kept busy? We reside in the state of Massachusetts in the United States.&lt;br /&gt;
&lt;br /&gt;
I hope to make regular code contributions to FlightGear. I want to gain the skills to address some FlightGear issues as they come up and participate in the discussions and programming for the various [FlightGear Epics |https://gitlab.com/groups/flightgear/-/epics?sort=created_date&amp;amp;state=opened&amp;amp;first_page_size=100]&lt;br /&gt;
&lt;br /&gt;
Teamwork:&lt;br /&gt;
&lt;br /&gt;
I'm a believer in teamwork and would love working closely in real-time with others on specific programming problems. I hope we can create opportunities for that. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Pair programming ==&lt;br /&gt;
&lt;br /&gt;
I find pair programming an attractive idea and wonder how it works in practice. What is the result of practicing pair programming with programmers of similar skills? What happens when an expert programmer pairs with an inexperienced one?&lt;br /&gt;
&lt;br /&gt;
I find that most are resistant to participating in pair programming, and I wonder why.  &lt;br /&gt;
&lt;br /&gt;
We're taught in academic settings to program by ourselves and hand in ou submissions for review as &amp;quot;homework&amp;quot;, but we continue that pattern in our work mainly out of inertia and lack of proper training. There's no reason to continue that pattern outside of a classroom as our only or even as main way of working together. &lt;br /&gt;
&lt;br /&gt;
== Understanding FlightGear's codebase ==&lt;br /&gt;
&lt;br /&gt;
The problem with FlightGear is its size, complexity, and the lack of a detailed guide to exploring that complexity. Several factors contribute to that complexity. Understanding FlightGear requires knowledge of many application domains, C++, an internal scripting language, a global data store, application features driven by XML or scripts, network protocols and data formats, some custom, some obscure, and from the era of mainframe computers.&lt;br /&gt;
&lt;br /&gt;
I'll examine each of these complexity realms with a view to providing a guideline for new FlightGear developers, me for instance, a path to follow leading to regular contributions to the FlightGear in C++, Nasal, and XML and other data formats.&lt;br /&gt;
&lt;br /&gt;
== C++ ==&lt;br /&gt;
&lt;br /&gt;
  First, the application uses C++. As a complex evolving language, C++ has a reputation for complexity. It's not just the language, its the fragmentation of code into small tidbits, widely scattered in individual files covering supposedly just one aspect of what needs to be done. I don't really know if the structure of C++ code as objects is more efficient than a C++ program done using solid structured programming, but I know which is easier think about and to work on.&lt;br /&gt;
&lt;br /&gt;
== Flight Simulation does a lot of different things == &lt;br /&gt;
&lt;br /&gt;
Second, Flight Simulation involves numerous application domains. Among them are aerodynamics, graphics, geography, geodesy, environment, navigation, networks, audio, video, and human languages. FlightGear addresses all of them and more. Each of these domains has their own view of the world, and many of them are modelled as C++ classes. Full understanding comes from knowing the C++ code, The terminolgy of the domain, and the way the code's authors chose to structure things as objects and methods.  &lt;br /&gt;
&lt;br /&gt;
== Nasal and the Property Tree ==&lt;br /&gt;
&lt;br /&gt;
Next, in addition to the complexity introduced by C++ and the application domains, there's Nasal. Finally, to tie it all together, loosely, the property tree. a global object, with individual data items of a key-value store actually stored in a tree because they are conceptually related. The property tree introduced compexity because items in it are not &amp;quot;owned&amp;quot;, they're simply created at some point, in either C++, XML processing or Nasal and used wherever the data item is &amp;quot;needed&amp;quot;. Connecting the dots through all the code based on identifying individual properties is not all that easy.&lt;br /&gt;
&lt;br /&gt;
== Where should I start? C++, Nasal or XML) ==&lt;br /&gt;
&lt;br /&gt;
It's not clear from existing documentation the central role of Nasal scripting and the Property Tree are in the simulation. It's not just C++, Nasal, and the interface between them, understood as computer languages.   Knowing the languages and interfaces themselves is vital, but even more important is understanding how scripting is used in FlightGear to create the simulation. If you are struggling as a newcomer to understand FlightGear's C++ code, understanding Nasal's role in driving parts of the simulation and the way it interacts with C++ code is probably one of the first things to do. It's what I'll be doing next.&lt;br /&gt;
&lt;br /&gt;
== FlightGear's DataFlow Diagram == &lt;br /&gt;
&lt;br /&gt;
There isn't one.&lt;br /&gt;
&lt;br /&gt;
Part of understanding any body of code is to be able to identify how data flows through the application. Dataflows are usually represented as arrows of various widths. The arrows are messages flowing between parts of an application. The larger the arrow, the more data items in that data flow.  &lt;br /&gt;
&lt;br /&gt;
In FlightGear's C++ code, there are, of course, classes and objects that represent some dataflows. There's a problem, though. Many of the classes are about processing data into ad-hoc structures within the property tree. &lt;br /&gt;
&lt;br /&gt;
There is no C++ class for an Altimeter or a Heading Indicator. Instead, these are represented by a set of properties and data loaded via XML and other formats. The numerical data, stored in the property tree has a path indicating that the properties underneath a node are for the altimeter or the heading indicator. The actual paths in this case are /instrumentation/altimeter and /instrumentation/heading-indicator. Each node in the tree can have properties as child nodes, as well as child nodes that contain additional properties, such as /instrumentation/heading-indicator/gyro. Usually, only the lear nodes of th e tree &lt;br /&gt;
&lt;br /&gt;
Properties are created on the fly, once the property tree's root node is instantiated. Properties are specified in XML data, created by a Nasal script, or by C++ code. The actual property mechanism is implemented in a C++ class.&lt;br /&gt;
&lt;br /&gt;
After they are created, properties are used as needed from Nasal scripts and C++ code, and finally destroyed by a destructor in C++. However, none of that is traceable as a data flow. IDEs are great at connecting elements of code to their definitions and usage, but when we use a data store like the property tree, the connection can't be found by the IDE. These data flows through the property tree mechanisms are a real part of the FlightGear Application, but we have no easy way to visualise them. Any visualization is mentally constructed over time by developers' experiences, as they examine and step through code.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[http://wiki.flightgear.org/User:Callahanp/goals What's up with Pat]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=142007</id>
		<title>User:Callahanp</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=142007"/>
		<updated>2025-06-21T22:37:40Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Me ==&lt;br /&gt;
 &lt;br /&gt;
Hello, my name is Patrick Callahan. People call me Pat. I have a web page, and you found it.&lt;br /&gt;
&lt;br /&gt;
I've been a programmer since I was a teenager. I'm 74 years old and retired now.&lt;br /&gt;
&lt;br /&gt;
Programming was a fun job. We couldn't believe we got paid to have so much fun.&lt;br /&gt;
&lt;br /&gt;
My current expertise primarily lies in databases, bash scripting, and traditional procedural programming in various languages.&lt;br /&gt;
&lt;br /&gt;
C++ is a work in progress. I took a course in 1993, but never used it professionally.  &lt;br /&gt;
&lt;br /&gt;
I like gardening with my wife of 33 years, Ann. We have a daughter who has given us three very active grandchildren, who will visit us next week for four days. Did I say I kept busy? We reside in the state of Massachusetts in the United States.&lt;br /&gt;
&lt;br /&gt;
I hope to make regular code contributions to FlightGear. I want to gain the skills to address some FlightGear issues as they come up and participate in the discussions and programming for the various [FlightGear Epics |https://gitlab.com/groups/flightgear/-/epics?sort=created_date&amp;amp;state=opened&amp;amp;first_page_size=100]&lt;br /&gt;
&lt;br /&gt;
Teamwork:&lt;br /&gt;
&lt;br /&gt;
I'm a believer in teamwork and would love working closely in real-time with others on specific programming problems. I hope we can create opportunities for that. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Pair programming ==&lt;br /&gt;
&lt;br /&gt;
I find pair programming an attractive idea and wonder how it works in practice. What is the result of practicing pair programming with programmers of similar skills? What happens when an expert programmer pairs with an inexperienced one?&lt;br /&gt;
&lt;br /&gt;
I find that most are resistant to participating in pair programming, and I wonder why.  &lt;br /&gt;
&lt;br /&gt;
We're taught in academic settings to program by ourselves and hand in ou submissions for review as &amp;quot;homework&amp;quot;, but we continue that pattern in our work mainly out of inertia and lack of proper training. There's no reason to continue that pattern outside of a classroom as our only or even as main way of working together. &lt;br /&gt;
&lt;br /&gt;
== Understanding FlightGear's codebase ==&lt;br /&gt;
&lt;br /&gt;
The problem with FlightGear is its size, complexity, and the lack of a detailed guide to exploring that complexity. Several factors contribute to that complexity. Understanding FlightGear requires knowledge of many application domains, C++, an internal scripting language, a global data store, application features driven by XML or scripts, network protocols and data formats, some custom, some obscure, and from the era of mainframe computers.&lt;br /&gt;
&lt;br /&gt;
I'll examine each of these complexity realms with a view to providing a guideline for new FlightGear developers, me for instance, a path to follow leading to regular contributions to the FlightGear in C++, Nasal, and XML and other data formats.&lt;br /&gt;
&lt;br /&gt;
== C++ ==&lt;br /&gt;
&lt;br /&gt;
  First, the application uses C++. As a complex evolving language, C++ has a reputation for complexity. It's not just the language, its the fragmentation of code into small tidbits, widely scattered in individual files covering supposedly just one aspect of what needs to be done. I don't really know if the structure of C++ code as objects is more efficient than a C++ program done using solid structured programming, but I know which is easier think about and to work on.&lt;br /&gt;
&lt;br /&gt;
== Flight Simulation does a lot of different things == &lt;br /&gt;
&lt;br /&gt;
Second, Flight Simulation involves numerous application domains. Among them are aerodynamics, graphics, geography, geodesy, environment, navigation, networks, audio, video, and human languages. FlightGear addresses all of them and more. Each of these domains has their own view of the world, and many of them are modelled as C++ classes. Full understanding comes from knowing the C++ code, The terminolgy of the domain, and the way the code's authors chose to structure things as objects and methods.  &lt;br /&gt;
&lt;br /&gt;
== Nasal and the Property Tree=&lt;br /&gt;
&lt;br /&gt;
Next, in addition to the complexity introduced by C++ and the application domains, there's Nasal. Finally, to tie it all together, loosely, the property tree. a global object, with individual data items of a key-value store actually stored in a tree because they are conceptually related. The property tree introduced compexity because items in it are not &amp;quot;owned&amp;quot;, they're simply created at some point, in either C++, XML processing or Nasal and used wherever the data item is &amp;quot;needed&amp;quot;. Connecting the dots through all the code based on identifying individual properties is not all that easy.&lt;br /&gt;
&lt;br /&gt;
== Where should I start? C++, Nasal or XML)&lt;br /&gt;
&lt;br /&gt;
It's not clear from existing documentation the central role of Nasal scripting and the Property Tree are in the simulation. It's not just C++, Nasal, and the interface between them, understood as computer languages.   Knowing the languages and interfaces themselves is vital, but even more important is understanding how scripting is used in FlightGear to create the simulation. If you are struggling as a newcomer to understand FlightGear's C++ code, understanding Nasal's role in driving parts of the simulation and the way it interacts with C++ code is probably one of the first things to do. It's what I'll be doing next.&lt;br /&gt;
== FlightGear's DataFlow Diagram == &lt;br /&gt;
&lt;br /&gt;
There isn't one.&lt;br /&gt;
&lt;br /&gt;
Part of understanding any body of code is to be able to identify how data flows through the application. Dataflows are usually represented as arrows of various widths. The arrows are messages flowing between parts of an application. The larger the arrow, the more data items in that data flow.  &lt;br /&gt;
&lt;br /&gt;
In FlightGear's C++ code, there are, of course, classes and objects that represent some dataflows. There's a problem, though. Many of the classes are about processing data into ad-hoc structures within the property tree. &lt;br /&gt;
&lt;br /&gt;
There is no C++ class for an Altimeter or a Heading Indicator. Instead, these are represented by a set of properties and data loaded via XML and other formats. The numerical data, stored in the property tree has a path indicating that the properties underneath a node are for the altimeter or the heading indicator. The actual paths in this case are /instrumentation/altimeter and /instrumentation/heading-indicator. Each node in the tree can have properties as child nodes, as well as child nodes that contain additional properties, such as /instrumentation/heading-indicator/gyro. Usually, only the lear nodes of th e tree &lt;br /&gt;
&lt;br /&gt;
Properties are created on the fly, once the property tree's root node is instantiated. Properties are specified in XML data, created by a Nasal script, or by C++ code. The actual property mechanism is implemented in a C++ class.&lt;br /&gt;
&lt;br /&gt;
After they are created, properties are used as needed from Nasal scripts and C++ code, and finally destroyed by a destructor in C++. However, none of that is traceable as a data flow. IDEs are great at connecting elements of code to their definitions and usage, but when we use a data store like the property tree, the connection can't be found by the IDE. These data flows through the property tree mechanisms are a real part of the FlightGear Application, but we have no easy way to visualise them. Any visualization is mentally constructed over time by developers' experiences, as they examine and step through code.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[http://wiki.flightgear.org/User:Callahanp/goals What's up with Pat]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=142006</id>
		<title>User:Callahanp</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=142006"/>
		<updated>2025-06-21T22:37:12Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About Me ==&lt;br /&gt;
 &lt;br /&gt;
Hello, my name is Patrick Callahan. People call me Pat. I have a web page, and you found it.&lt;br /&gt;
&lt;br /&gt;
I've been a programmer since I was a teenager. I'm 74 years old and retired now.&lt;br /&gt;
&lt;br /&gt;
Programming was a fun job. We couldn't believe we got paid to have so much fun.&lt;br /&gt;
&lt;br /&gt;
My current expertise primarily lies in databases, bash scripting, and traditional procedural programming in various languages.&lt;br /&gt;
&lt;br /&gt;
C++ is a work in progress. I took a course in 1993, but never used it professionally.  &lt;br /&gt;
&lt;br /&gt;
I like gardening with my wife of 33 years, Ann. We have a daughter who has given us three very active grandchildren, who will visit us next week for four days. Did I say I kept busy? We reside in the state of Massachusetts in the United States.&lt;br /&gt;
&lt;br /&gt;
I hope to make regular code contributions to FlightGear. I want to gain the skills to address some FlightGear issues as they come up and participate in the discussions and programming for the various [FlightGear Epics |https://gitlab.com/groups/flightgear/-/epics?sort=created_date&amp;amp;state=opened&amp;amp;first_page_size=100]&lt;br /&gt;
&lt;br /&gt;
Teamwork:&lt;br /&gt;
&lt;br /&gt;
I'm a believer in teamwork and would love working closely in real-time with others on specific programming problems. I hope we can create opportunities for that. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Pair programming ==.  &lt;br /&gt;
&lt;br /&gt;
I find pair programming an attractive idea and wonder how it works in practice. What is the result of practicing pair programming with programmers of similar skills? What happens when an expert programmer pairs with an inexperienced one?&lt;br /&gt;
&lt;br /&gt;
I find that most are resistant to participating in pair programming, and I wonder why.  &lt;br /&gt;
&lt;br /&gt;
We're taught in academic settings to program by ourselves and hand in ou submissions for review as &amp;quot;homework&amp;quot;, but we continue that pattern in our work mainly out of inertia and lack of proper training. There's no reason to continue that pattern outside of a classroom as our only or even as main way of working together. &lt;br /&gt;
&lt;br /&gt;
== Understanding FlightGear's codebase ==&lt;br /&gt;
&lt;br /&gt;
The problem with FlightGear is its size, complexity, and the lack of a detailed guide to exploring that complexity. Several factors contribute to that complexity. Understanding FlightGear requires knowledge of many application domains, C++, an internal scripting language, a global data store, application features driven by XML or scripts, network protocols and data formats, some custom, some obscure, and from the era of mainframe computers.&lt;br /&gt;
&lt;br /&gt;
I'll examine each of these complexity realms with a view to providing a guideline for new FlightGear developers, me for instance, a path to follow leading to regular contributions to the FlightGear in C++, Nasal, and XML and other data formats.&lt;br /&gt;
&lt;br /&gt;
== C++ ==&lt;br /&gt;
&lt;br /&gt;
  First, the application uses C++. As a complex evolving language, C++ has a reputation for complexity. It's not just the language, its the fragmentation of code into small tidbits, widely scattered in individual files covering supposedly just one aspect of what needs to be done. I don't really know if the structure of C++ code as objects is more efficient than a C++ program done using solid structured programming, but I know which is easier think about and to work on.&lt;br /&gt;
&lt;br /&gt;
== Flight Simulation does a lot of different things == &lt;br /&gt;
&lt;br /&gt;
Second, Flight Simulation involves numerous application domains. Among them are aerodynamics, graphics, geography, geodesy, environment, navigation, networks, audio, video, and human languages. FlightGear addresses all of them and more. Each of these domains has their own view of the world, and many of them are modelled as C++ classes. Full understanding comes from knowing the C++ code, The terminolgy of the domain, and the way the code's authors chose to structure things as objects and methods.  &lt;br /&gt;
&lt;br /&gt;
== Nasal and the Property Tree=&lt;br /&gt;
&lt;br /&gt;
Next, in addition to the complexity introduced by C++ and the application domains, there's Nasal. Finally, to tie it all together, loosely, the property tree. a global object, with individual data items of a key-value store actually stored in a tree because they are conceptually related. The property tree introduced compexity because items in it are not &amp;quot;owned&amp;quot;, they're simply created at some point, in either C++, XML processing or Nasal and used wherever the data item is &amp;quot;needed&amp;quot;. Connecting the dots through all the code based on identifying individual properties is not all that easy.&lt;br /&gt;
&lt;br /&gt;
== Where should I start? C++, Nasal or XML)&lt;br /&gt;
&lt;br /&gt;
It's not clear from existing documentation the central role of Nasal scripting and the Property Tree are in the simulation. It's not just C++, Nasal, and the interface between them, understood as computer languages.   Knowing the languages and interfaces themselves is vital, but even more important is understanding how scripting is used in FlightGear to create the simulation. If you are struggling as a newcomer to understand FlightGear's C++ code, understanding Nasal's role in driving parts of the simulation and the way it interacts with C++ code is probably one of the first things to do. It's what I'll be doing next.&lt;br /&gt;
== FlightGear's DataFlow Diagram == &lt;br /&gt;
&lt;br /&gt;
There isn't one.&lt;br /&gt;
&lt;br /&gt;
Part of understanding any body of code is to be able to identify how data flows through the application. Dataflows are usually represented as arrows of various widths. The arrows are messages flowing between parts of an application. The larger the arrow, the more data items in that data flow.  &lt;br /&gt;
&lt;br /&gt;
In FlightGear's C++ code, there are, of course, classes and objects that represent some dataflows. There's a problem, though. Many of the classes are about processing data into ad-hoc structures within the property tree. &lt;br /&gt;
&lt;br /&gt;
There is no C++ class for an Altimeter or a Heading Indicator. Instead, these are represented by a set of properties and data loaded via XML and other formats. The numerical data, stored in the property tree has a path indicating that the properties underneath a node are for the altimeter or the heading indicator. The actual paths in this case are /instrumentation/altimeter and /instrumentation/heading-indicator. Each node in the tree can have properties as child nodes, as well as child nodes that contain additional properties, such as /instrumentation/heading-indicator/gyro. Usually, only the lear nodes of th e tree &lt;br /&gt;
&lt;br /&gt;
Properties are created on the fly, once the property tree's root node is instantiated. Properties are specified in XML data, created by a Nasal script, or by C++ code. The actual property mechanism is implemented in a C++ class.&lt;br /&gt;
&lt;br /&gt;
After they are created, properties are used as needed from Nasal scripts and C++ code, and finally destroyed by a destructor in C++. However, none of that is traceable as a data flow. IDEs are great at connecting elements of code to their definitions and usage, but when we use a data store like the property tree, the connection can't be found by the IDE. These data flows through the property tree mechanisms are a real part of the FlightGear Application, but we have no easy way to visualise them. Any visualization is mentally constructed over time by developers' experiences, as they examine and step through code.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[http://wiki.flightgear.org/User:Callahanp/goals What's up with Pat]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=142005</id>
		<title>User:Callahanp</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=142005"/>
		<updated>2025-06-21T05:26:47Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The problem with FlightGear is its size, complexity, and the lack of a detailed guide to exploring that complexity.  Several factors contribute to that complexity.  Understanding FlightGear requires knowledge of many applicaiton domains, C++, an internal  scripting language, a global data store, application features driven by XML or scripts, network protocols and data formats, some custom, some obscure and from the era of mainframe computers.&lt;br /&gt;
&lt;br /&gt;
I'll examine each of these complexity realms with a view to providing a guideline for new FlightGear developers, me for instance, with path to follow leading to regular contributions to the FlightGear C++, Nasal and XML codebases.&lt;br /&gt;
&lt;br /&gt;
  First, the application uses C++.  Second, Flight Simulation involves numerous application domains. Among them are aerodynamics, graphics, geography, geodesy, environment, navigation, networks, audio, video, and human languages. FlightGear addresses all of them and more.  Next, in addition to the complexity introduced by C++ and the application domains, there's Nasal. Finally to tie it all togehter, loosely, the property tree. a global object, with individual data items of a key-value store actually stored in a tree because they are conceptually related.  The property tree introduced compexity because items in it are not &amp;quot;owned&amp;quot;, they're simply created at some point, in either C++, XML processing or Nasal and used wherever the data item is &amp;quot;needed&amp;quot;.  Connecting the dots through all the code based on identifying individual properties is not all that easy.&lt;br /&gt;
&lt;br /&gt;
It's not clear from existing documentation the central role of Nasal scripting in the simulation.  It's not just C++, Nasal, and the interface between them, understood as computer languages.   Knowing the languages and interfaces themselves is vital, but even more important is understanding how scripting is used in FlightGear to create the simulation.  If you are struggling as a newcomer to understand FlightGear's C++ code, understanding Nasal's role in driving parts of the simulation and the way it interacts with C++ code is probably one of the first things to do.  It's what I'll be doing next.&lt;br /&gt;
&lt;br /&gt;
Part of understanding any body of code is to be able to identify how data flows through the application. Dataflows are usually represented as arrows of various widths. The arrows are messages flowing between parts of an application.  The larger the arrow, the more data items in that data flow.  &lt;br /&gt;
&lt;br /&gt;
In FlightGear's C++ code, there are, of course, classes and objects that represent some dataflows.  There's a problem, though.  Many of the classes are about processing data into ad-hoc structures within the property tree. &lt;br /&gt;
&lt;br /&gt;
There is no C++ class for an Altimeter or a Heading Indicator.  Instead, these are represented by a set of properties, with a path indicating that the properties underneath a node are for the altimeter or the heading indicator.  The actual paths in this case are /instrumentation/altimeter and /instrumentation/heading-indicator.  Each node in the tree can have properties as child nodes, as well as child nodes that contain additional properties, such as /instrumentation/heading-indicator/gyro.  &lt;br /&gt;
&lt;br /&gt;
Properties are created on the fly, once the property tree's root node is instantiated.  Properties are specified in XML data, created by a Nasal script, or by C++ code.  The actual property mechanism is implemented in a C++ class.&lt;br /&gt;
&lt;br /&gt;
After they are created, properties are used as needed from Nasal scripts and C++ code, and finally destroyed by a destructor in C++.  However, none of that is traceable as a data flow. IDEs are great at connecting elements of code to their definitions and usage, but when we use a data store like the property tree, the connection can't be found by the IDE.  These data flows through the property tree mechanisms are a real part of the FlightGear Application, but we have no easy way to visualise them.  Any visualization is mentally constructed over time by developers' experiences, as they examine and step through code.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[http://wiki.flightgear.org/User:Callahanp/goals What's up with Pat]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=142000</id>
		<title>User:Callahanp</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=142000"/>
		<updated>2025-06-20T22:00:36Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: Getting it together&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The problem with FlightGear is its size, complexity, and the lack of a detailed guide to exploring that complexity.  Several factors contribute to that complexity.  Understanding FlightGear requires knowledge of many applicaiton domains, C++, an internal  scripting language, a global data store, application features driven by XML or scripts, network protocols and data formats, some custom, some obscure and from the era of mainframe computers.&lt;br /&gt;
&lt;br /&gt;
I'll examine each of these complexity realms with a view to providing a guideline for new FlightGear developers, me for instance, with path to follow leading to regular contributions to the FlightGear C++, Nasal and XML codebases.&lt;br /&gt;
&lt;br /&gt;
  First, the application uses C++.  Second, Flight Simulation involves numerous application domains. Among them are aerodynamics, graphics, geography, geodesy, environment, navigation, networks, audio, video, and human languages. FlightGear addresses all of them and more.  Next, in addition to the complexity introduced by C++ and the application domains, there's Nasal. Finally to tie it all togehter, loosely, the property tree. a global object, with individual data items of a key-value store actually stored in a tree because they are conceptually related.  The property tree introduced compexity because items in it are not &amp;quot;owned&amp;quot;, they're simply created at some point, in either C++, XML processing or Nasal and used wherever the data item is &amp;quot;needed&amp;quot;.  Connecting the dots through all the code based on identifying individual properties is not all that easy.&lt;br /&gt;
&lt;br /&gt;
It's not clear from existing documentation the central role of Nasal scripting in the simulation.  It's not just C++, Nasal, and the interface between them, understood as computer languages.   Knowing the languages and interfaces themselves is vital, but even more important is understanding how scripting is used in FlightGear to create the simulation.  If you are struggling as a newcomer to understand FlightGear's C++ code, understanding Nasal's role in driving parts of the simulation and the way it interacts with C++ code is probably one of the first things to do.  It's what I'll be doing next.&lt;br /&gt;
&lt;br /&gt;
Part of understanding any body of code is to be able to identify how data flows through the application. Dataflows are usually represented as arrows representing messages flowing between parts of an application.  The larger the arrow, the more data items in that flow.  One of the problems with Flightgear, is that for the most part there is no visible structure for those larger arrows, and nothing to indicate  where such an arrow starts and ends.   Anything can add a data item to the property tree, and any code can access it, but nothing is keeping track of what added the item and what wants to read it, update it or destroy it.  There's nothing written into the code to connect the individual items to a specific data flow.  the position in the hierarchy of properties represented as a path gives you a clue, but it's not usually enough to pin things down.  IDEs are great at connecting elements of code to their definitions and usage, but when we use a data store like the property tree, the connection can't be found by the IDE.  These data flows through the property tree mechanisms are a real part of the Flighgear Applicaiton, but we have no easy way to visualise them.  Any visualization is constructed over time by developers experiences examining and stepping through code.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
th Radon. Nvidia or Intel graphicson recent or older or less powerful graphics&lt;br /&gt;
&lt;br /&gt;
[http://wiki.flightgear.org/User:Callahanp/goals What's up with Pat]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=FlightGear_screenshot_gallery&amp;diff=141816</id>
		<title>FlightGear screenshot gallery</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=FlightGear_screenshot_gallery&amp;diff=141816"/>
		<updated>2025-05-02T13:15:49Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: Add C172P 1982 Instrument Panel Image&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is my new, dedicated gallery for [[FlightGear]] screenshots. Feel free to add more!&lt;br /&gt;
&lt;br /&gt;
[[File:P51_vs_FW190.png]]&lt;br /&gt;
[[File:P51vs_fw190.png]]&lt;br /&gt;
[[File:Twin otter rembrandt.png]]&lt;br /&gt;
[[File:Twin otter clouds.png]]&lt;br /&gt;
[[File:Twin otter fog.png]]&lt;br /&gt;
[[File:Cessna-C172P-1982-Instrument-Panel.png]]&lt;br /&gt;
&lt;br /&gt;
[[Category:FlightGear]]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=File:Cessna-C172P-1982-Instrument-Panel.png&amp;diff=141771</id>
		<title>File:Cessna-C172P-1982-Instrument-Panel.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=File:Cessna-C172P-1982-Instrument-Panel.png&amp;diff=141771"/>
		<updated>2025-04-26T17:11:35Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: Uploaded own work with UploadWizard&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=={{int:filedesc}}==&lt;br /&gt;
{{Information&lt;br /&gt;
|description={{en|1=A screenshot of the C172P 1982 Panel with the Yoke Hidden}}&lt;br /&gt;
|date=2025-04-26&lt;br /&gt;
|source={{own}}&lt;br /&gt;
|author=[[User:Callahanp|Callahanp]]&lt;br /&gt;
|permission=&lt;br /&gt;
|other versions=&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=={{int:license-header}}==&lt;br /&gt;
{{self|cc-by-sa-4.0}}&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=FlightGear_screenshot_gallery&amp;diff=141770</id>
		<title>FlightGear screenshot gallery</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=FlightGear_screenshot_gallery&amp;diff=141770"/>
		<updated>2025-04-26T17:10:08Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is my new, dedicated gallery for [[FlightGear]] screenshots. Feel free to add more!&lt;br /&gt;
&lt;br /&gt;
[[File:P51_vs_FW190.png]]&lt;br /&gt;
[[File:P51vs_fw190.png]]&lt;br /&gt;
[[File:Twin otter rembrandt.png]]&lt;br /&gt;
[[File:Twin otter clouds.png]]&lt;br /&gt;
[[File:Twin otter fog.png]]&lt;br /&gt;
[[File:Cessna C172P 1982 Instrument Panel]]&lt;br /&gt;
&lt;br /&gt;
[[Category:FlightGear]]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=141739</id>
		<title>User:Callahanp</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=141739"/>
		<updated>2025-04-12T22:19:48Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Flightgear Versions&lt;br /&gt;
|-&lt;br /&gt;
! 2020.3 !! 2024.1 !! Next&lt;br /&gt;
|-&lt;br /&gt;
| HDR Not Applicable || HDR - Command Line Option|| HDR - By Default&lt;br /&gt;
|-&lt;br /&gt;
| Scenery WS 2.0 || Scenery WS 2.0 by default \n WS 3.0 in separate directory || Scenery WS 2.0 by default&lt;br /&gt;
WS 3.0 in separate directory&lt;br /&gt;
|- &lt;br /&gt;
| Broken || Broken || Broken&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
What is different between next and Release/2024.1?&lt;br /&gt;
What is&lt;br /&gt;
- about to happen-&lt;br /&gt;
is broken&lt;br /&gt;
- on  Release/2024.1 &lt;br /&gt;
or next&lt;br /&gt;
&lt;br /&gt;
this Week, this Month, this YearWhat special stepscommand line optionsnternal settingsenvironment variable valuesor directory paths should I use to run Flightgear Release 2020.3Release 2024.1next (2024.2)in various scenarios:&lt;br /&gt;
with or without HDR  using WS 2.0, WS3.0, Photosceneryon Windows, macOS, Linux, FreeBSD...with Radon. Nvidia or Intel graphicson recent or older or less powerful graphics&lt;br /&gt;
&lt;br /&gt;
[http://wiki.flightgear.org/User:Callahanp/goals What's up with Pat]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=141738</id>
		<title>User:Callahanp</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=141738"/>
		<updated>2025-04-12T22:13:46Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;	&lt;br /&gt;
[http://wiki.flightgear.org/User:Callahanp/goals What's up with Pat]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Callahanp/goals&amp;diff=141737</id>
		<title>User:Callahanp/goals</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Callahanp/goals&amp;diff=141737"/>
		<updated>2025-04-12T19:46:59Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: Created page with &amp;quot;=== This Week??? Probably not === 11-Aug-2024 - 17-Aug-2024  * initial commit for flightgear [https://sourceforge.net/p/flightgear/codetickets/2890/ tickets/2890 - Upgrade Mongoose Web Server]  * plan to refactor MongooseHttpd, MongooseConnection and the Handlers * initiate work on test_suite/unit_tests/Network/test_httpd.cxx  19-Aug-2024 -   * Build &amp;amp; run test_suite/unit_tests/Network/test_httpd.cxx *  === Reading List: ===  ==== Start With ==== */cmake.org/getting-st...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== This Week??? Probably not ===&lt;br /&gt;
11-Aug-2024 - 17-Aug-2024&lt;br /&gt;
&lt;br /&gt;
* initial commit for flightgear [https://sourceforge.net/p/flightgear/codetickets/2890/ tickets/2890 - Upgrade Mongoose Web Server] &lt;br /&gt;
* plan to refactor MongooseHttpd, MongooseConnection and the Handlers&lt;br /&gt;
* initiate work on test_suite/unit_tests/Network/test_httpd.cxx&lt;br /&gt;
&lt;br /&gt;
19-Aug-2024 - &lt;br /&gt;
&lt;br /&gt;
* Build &amp;amp; run test_suite/unit_tests/Network/test_httpd.cxx&lt;br /&gt;
*&lt;br /&gt;
&lt;br /&gt;
=== Reading List: ===&lt;br /&gt;
&lt;br /&gt;
==== Start With ====&lt;br /&gt;
*[[/cmake.org/getting-started/|https://cmake.org/getting-started/]] -- Build using g++ and clang.&lt;br /&gt;
*[[/learn.microsoft.com/en-us/vcpkg/|https://learn.microsoft.com/en-us/vcpkg/]] -- cross-platform C/C++ package manager&lt;br /&gt;
*[[https://www.jenkins.io/ -- Automation Server&lt;br /&gt;
*[[/www.sourceware.org/gdb/|https://www.sourceware.org/gdb/]] or [[/lldb.llvm.org/|https://lldb.llvm.org/]] -- Debuggers&lt;br /&gt;
*[[/github.com/google/sanitizers|https://github.com/google/sanitizers]] -- Read about each of the available sanitizers&lt;br /&gt;
*[[/valgrind.org/docs/manual/quick-start.html|https://valgrind.org/docs/manual/quick-start.html]] -- A suite of debugging and profiling tools&lt;br /&gt;
*A review of all the options for each tool you want to acquire.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Reading Lists ====&lt;br /&gt;
&lt;br /&gt;
=== Overviews ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Topic !! Overview  !! Options !! Progress !! Notes !!&lt;br /&gt;
|-&lt;br /&gt;
| vcpkg || https://learn.microsoft.com/en-us/vcpkg/  || &lt;br /&gt;
|- &lt;br /&gt;
| apt || https://wiki.debian.org/Apt || &lt;br /&gt;
|- &lt;br /&gt;
| cmake || https://cmake.org/getting-started/ ||&lt;br /&gt;
|-&lt;br /&gt;
| g++ || https://www.gnu.org/software/gcc/ ||&lt;br /&gt;
|-&lt;br /&gt;
| gdb || https://www.sourceware.org/gdb/ ||&lt;br /&gt;
|-&lt;br /&gt;
| llvm || https://llvm.org ||&lt;br /&gt;
|-&lt;br /&gt;
| clang || https://clang.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| lldb || https://lldb.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| valgrind || https://valgrind.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| lcov || https://github.com/linux-test-project/lcov || -DENABLE_COVERAGE=1&lt;br /&gt;
if (ENABLE_COVERAGE)&lt;br /&gt;
  set(CMAKE_BUILD_TYPE &amp;quot;Debug&amp;quot; CACHE STRING&lt;br /&gt;
    &amp;quot;set the build type.&amp;quot; FORCE)&lt;br /&gt;
  include(CodeCoverage.cmake)&lt;br /&gt;
  append_coverage_compiler_flags()&lt;br /&gt;
endif()&lt;br /&gt;
&lt;br /&gt;
add_executable&lt;br /&gt;
target_link_libraries( a.exe  test_a.cpp CPPUnit::CPPUnit&lt;br /&gt;
 if (ENABLE_COVERAGE)&lt;br /&gt;
   setup_target_for_coverage_lcov(&lt;br /&gt;
      NAME coverage&lt;br /&gt;
      EXECUTABLE ${cmake_current_binarey_dir}/test_a&lt;br /&gt;
      LCOV_ARGS --rc lcov_branch_coverage=1&lt;br /&gt;
      GENHTML_ARGS --legend --branch-coveragbe&lt;br /&gt;
      DEPENDENCIES test_a)&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| sanitizers || https://github.com/google/sanitizers&lt;br /&gt;
https://www.cl.cam.ac.uk/~nk480/C1819/lecture5.pdf&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| asan || https://github.com/google/sanitizers/wiki/AddressSanitizer ||gdb &amp;amp; clang:&lt;br /&gt;
CMAKE_CXX_FLAGS -fsanitize=address&lt;br /&gt;
CMAKE_EXE_LINKER_FLAGS -fsanitize=address&lt;br /&gt;
|-&lt;br /&gt;
| msan || https://github.com/google/sanitizers/wiki/MemorySanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| tsan || https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual ||&lt;br /&gt;
|-&lt;br /&gt;
| ubsan || https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html || gdb &amp;amp; clang:&lt;br /&gt;
CMAKE_CXX_FLAGS -fsanitize=undefined&lt;br /&gt;
CMAKE_EXE_LINKER_FLAGS -fsanitize=undefined&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Start With==&lt;br /&gt;
&lt;br /&gt;
*[[/cmake.org/getting-started/|https://cmake.org/getting-started/]] -- Build using g++ and clang.&lt;br /&gt;
*[[/learn.microsoft.com/en-us/vcpkg/|https://learn.microsoft.com/en-us/vcpkg/]] -- cross-platform C/C++ package manager&lt;br /&gt;
*[[/www.sourceware.org/gdb/|https://www.sourceware.org/gdb/]] or [[/lldb.llvm.org/|https://lldb.llvm.org/]] -- Debuggers&lt;br /&gt;
*[[/github.com/google/sanitizers|https://github.com/google/sanitizers]] -- Read about each of the available sanitizers&lt;br /&gt;
*[[/valgrind.org/docs/manual/quick-start.html|https://valgrind.org/docs/manual/quick-start.html]] -- A suite of debugging and profiling tools&lt;br /&gt;
*A review of all the options for each tool you want to acquire.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Reading Lists ==&lt;br /&gt;
&lt;br /&gt;
=== Overviews ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Topic !! Overview  !! Options !! Progress !! Notes !!&lt;br /&gt;
|-&lt;br /&gt;
| vcpkg || https://learn.microsoft.com/en-us/vcpkg/  || &lt;br /&gt;
|- &lt;br /&gt;
| apt || https://wiki.debian.org/Apt || &lt;br /&gt;
|- &lt;br /&gt;
| cmake || https://cmake.org/getting-started/ ||&lt;br /&gt;
|-&lt;br /&gt;
| g++ || https://www.gnu.org/software/gcc/ ||&lt;br /&gt;
|-&lt;br /&gt;
| gdb || https://www.sourceware.org/gdb/ ||&lt;br /&gt;
|-&lt;br /&gt;
| llvm || https://llvm.org ||&lt;br /&gt;
|-&lt;br /&gt;
| clang || https://clang.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| lldb || https://lldb.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| valgrind || https://valgrind.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| sanitizers || https://github.com/google/sanitizers&lt;br /&gt;
https://www.cl.cam.ac.uk/~nk480/C1819/lecture5.pdf&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| asan || https://github.com/google/sanitizers/wiki/AddressSanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| msan || https://github.com/google/sanitizers/wiki/MemorySanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| tsan || https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual ||&lt;br /&gt;
|-&lt;br /&gt;
| ubsan || https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html ||&lt;br /&gt;
 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Start With ====&lt;br /&gt;
*[[/cmake.org/getting-started/|https://cmake.org/getting-started/]] -- Build using g++ and clang.&lt;br /&gt;
*[[/learn.microsoft.com/en-us/vcpkg/|https://learn.microsoft.com/en-us/vcpkg/]] -- cross-platform C/C++ package manager&lt;br /&gt;
*[[/www.sourceware.org/gdb/|https://www.sourceware.org/gdb/]] or [[/lldb.llvm.org/|https://lldb.llvm.org/]] -- Debuggers&lt;br /&gt;
*[[/github.com/google/sanitizers|https://github.com/google/sanitizers]] -- Read about each of the available sanitizers&lt;br /&gt;
*[[/valgrind.org/docs/manual/quick-start.html|https://valgrind.org/docs/manual/quick-start.html]] -- A suite of debugging and profiling tools&lt;br /&gt;
*A review of all the options for each tool you want to acquire.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Reading Lists ====&lt;br /&gt;
&lt;br /&gt;
=== Overviews ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Topic !! Overview  !! Options !! Progress !! Notes !!&lt;br /&gt;
|-&lt;br /&gt;
| vcpkg || https://learn.microsoft.com/en-us/vcpkg/  || &lt;br /&gt;
|- &lt;br /&gt;
| apt || https://wiki.debian.org/Apt || &lt;br /&gt;
|- &lt;br /&gt;
| cmake || https://cmake.org/getting-started/ ||&lt;br /&gt;
|-&lt;br /&gt;
| g++ || https://www.gnu.org/software/gcc/ ||&lt;br /&gt;
|-&lt;br /&gt;
| gdb || https://www.sourceware.org/gdb/ ||&lt;br /&gt;
|-&lt;br /&gt;
| llvm || https://llvm.org ||&lt;br /&gt;
|-&lt;br /&gt;
| clang || https://clang.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| lldb || https://lldb.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| valgrind || https://valgrind.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| sanitizers || https://github.com/google/sanitizers&lt;br /&gt;
https://www.cl.cam.ac.uk/~nk480/C1819/lecture5.pdf&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| asan || https://github.com/google/sanitizers/wiki/AddressSanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| msan || https://github.com/google/sanitizers/wiki/MemorySanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| tsan || https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual ||&lt;br /&gt;
|-&lt;br /&gt;
| ubsan || https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html ||&lt;br /&gt;
 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Integration ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Topic !! Download_and_compile.sh !! dev1&lt;br /&gt;
|-&lt;br /&gt;
| vcpkg ||   || &lt;br /&gt;
|- &lt;br /&gt;
| apt || || &lt;br /&gt;
|- &lt;br /&gt;
| cmake || ||&lt;br /&gt;
|-&lt;br /&gt;
| g++ ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| gdb || ||&lt;br /&gt;
|-&lt;br /&gt;
| llvm ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| clang ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| lldb ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| valgrind ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| sanitizers ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| asan ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| msan ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| tsan || ||&lt;br /&gt;
|-&lt;br /&gt;
| ubsan || ||&lt;br /&gt;
 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Follow-on Questions ====&lt;br /&gt;
* Does g++ support each of these sanitizers?&lt;br /&gt;
* What other tools should I research besides gdb, lldb, valgrind, UBSAN, ASAN, TSAN, and MSAN?&lt;br /&gt;
* Are there tools other than sanitizers and debuggers I should know about?&lt;br /&gt;
* Are there obsolete tools I should ignore?&lt;br /&gt;
* Are there books that cover C++ topics beyond writing C++? How about how-to guides? (I'll be searching for these next, but do you happen to know any particularly useful and easy to read?&lt;br /&gt;
* Crash dumps and crash dump tools. I don't know much about them. What good resources on this topic are there for Linux, Windows, and Mac?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Background ====&lt;br /&gt;
I'm about to start going through the list above for myself. It may take a while.&lt;br /&gt;
&lt;br /&gt;
I'm currently involved in a project with about half a million existing lines of C++ code and want to know what tools I need to work in this environment properly. The application has multi-threaded parts.&lt;br /&gt;
&lt;br /&gt;
I can do basic g++, Debug, DebWithRelInfo, and Release builds using cmake or a pre-defined build script and step through code line-by-line with the gdb in VSCode, but want to become familiar with gdb at the command line.&lt;br /&gt;
&lt;br /&gt;
I want to come up to speed with clang and lldb in vscode.&lt;br /&gt;
&lt;br /&gt;
[[/stackoverflow.com/questions/63978029/setup-lldb-debugging-with-cpp-extension-in-vscode-linux|https://stackoverflow.com/questions/63978029/setup-lldb-debugging-with-cpp-extension-in-vscode-linux]]&lt;br /&gt;
&lt;br /&gt;
== Other Thoughts ==&lt;br /&gt;
&lt;br /&gt;
I need to familiarize myself with other tools available, learn how to enable particular tools in a build, and learn how to use the tool's output.&lt;br /&gt;
&lt;br /&gt;
I want to learn to use tools like UBSAN, ASAN, TSAN, and MSAN effectively and how to switch from g++ to clang when appropriate. I want to learn what tools other than the sanitizers and debuggers above are available.&lt;br /&gt;
&lt;br /&gt;
There's no such thing as free beer! Someone pays for flightgear cloud infrastructure that I personallly benefit from.  So I contribute a little at:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;https://liberapay.com/t3r&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Currently working on:&lt;br /&gt;
&lt;br /&gt;
Git Worktrees with download_and_compile.sh  (done &amp;amp; working)&lt;br /&gt;
&lt;br /&gt;
Web Socket Refactor &amp;amp; Fix.  &lt;br /&gt;
&lt;br /&gt;
OSM (Open Street Map) Scenery Build (on hold)&lt;br /&gt;
&lt;br /&gt;
Goals (Maybe)&lt;br /&gt;
&lt;br /&gt;
*Download Scenery from Current Scenery Developers&lt;br /&gt;
*Build Scripts for Scenery Land Class, Elevation, and OSM processing&lt;br /&gt;
*Understand the underlying formats in Flightgear Scenery&lt;br /&gt;
*Understand the processing of Scenery data between tiles in the build process and the running simulator&lt;br /&gt;
*Assist Scenery Developers with technical support.&lt;br /&gt;
*full explanation of the advantages and disadvantages of the worktree approach.&lt;br /&gt;
&lt;br /&gt;
[[Hackathon Proposal: Property Subscription Improvements|Hackathon-2023-Proposal-Websocket-Property-Subscription-Improvements]]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=141736</id>
		<title>User:Callahanp</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=141736"/>
		<updated>2025-04-12T19:45:43Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: Replaced content with &amp;quot;	 [http://wiki.flightgear.org/User:Callahanp/goals ]&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;	&lt;br /&gt;
[http://wiki.flightgear.org/User:Callahanp/goals ]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Software_testing&amp;diff=140276</id>
		<title>Software testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Software_testing&amp;diff=140276"/>
		<updated>2024-08-20T20:42:34Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: /* Structure of a CPPUnit test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Note|There’s already the test_suite in {{fg src file|path=test_suite}} using [[Cppunit effort|CppUnit]], thanks to some hard work by [[User:Bugman|Edward]]. We need more tests written for it; submissions are welcome. (Pick an area of interest)&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36972720/&amp;lt;/ref&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{See also|Cppunit effort}}&lt;br /&gt;
&lt;br /&gt;
FlightGear developers use various testing tools. This includes automated testing via unit tests in [[SimGear]] and a full test suite with multiple test categories in the [[FlightGear Git|flightgear repository]], as well as manual in-sim testing. Writing tests is one of the best ways to jump into FlightGear development.&lt;br /&gt;
&lt;br /&gt;
One improving area is unit testing: certain areas and features (e.g., carrier start) now 'can't break.' As we add testing in additional areas (e.g., Multi-player, AI, protocols, and replay are all possible), we increase the baseline quality and have a clearer idea when we make incompatible changes. (The idea is that we capture the 'supported API' in the tests: when an aircraft deviates from that, we can decide to add another test case, fix the aircraft, etc). Of course, there are some pretty significant areas where Automated Testing Is Hard (TM).&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/37078825/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== SimGear ==&lt;br /&gt;
&lt;br /&gt;
Unit testing for the [[SimGear]] sources uses the CMake CTest unit testing infrastructure. Several tests use the BOOST unit testing infrastructure tied to the build system using CTest; however, the FlightGear developers are shifting towards eliminating BOOST, so CPPUnit and CTest tests are preferred.&lt;br /&gt;
&lt;br /&gt;
=== Building and running the SimGear tests ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ make&lt;br /&gt;
$ ctest&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== FlightGear ==&lt;br /&gt;
&lt;br /&gt;
Testing of the [[FlightGear Git|flightgear sources]] is via a comprehensive test suite implemented using [https://www.freedesktop.org/wiki/Software/cppunit/ CppUnit], a port of the famous JUnit framework.&lt;br /&gt;
&lt;br /&gt;
=== Building the test suite ===&lt;br /&gt;
&lt;br /&gt;
You must build FlightGear from the source using cmake to run the tests. See [[Building FlightGear]] for details.&lt;br /&gt;
&lt;br /&gt;
Once you have your cmake build environment, do the following:&lt;br /&gt;
# Change to your FlightGear build* directory&lt;br /&gt;
# Enable building the tests by setting a cmake variable:  &amp;lt;code&amp;gt;cmake -DBUILD_TESTING=ON .&amp;lt;/code&amp;gt;&lt;br /&gt;
# Ensure the &amp;lt;code&amp;gt;[[$FG ROOT|$FG_ROOT]]&amp;lt;/code&amp;gt; environment variable points to fgdata e.g. &amp;lt;code&amp;gt;$FG_INSTALL_DIR/share/fgdata&amp;lt;/code&amp;gt;&lt;br /&gt;
# Build the test suite:  &amp;lt;code&amp;gt;make test_suite&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Building the test suite will also run a test because you will typically want to write a test and then immediately compile and run it.&lt;br /&gt;
&lt;br /&gt;
 * ls in this directory should include CMakeCache.txt, cmake_install, and others. You do not want to run cmake in the flightgear sources directory, which includes files such as AUTHORS, COPYING, INSTALL, etc.&lt;br /&gt;
&lt;br /&gt;
On a Windows MSVC-based build environment, after generating files with cmake, run the following code:&lt;br /&gt;
# cmake --build . --config RelWithDebInfo --target test_suite/test_suite&lt;br /&gt;
&lt;br /&gt;
=== Running the test suite ===&lt;br /&gt;
&lt;br /&gt;
To run the test suite, simply run &amp;lt;code&amp;gt;./test_suite/fgfs_test_suite&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Executing fgfs_test_suite will run the entire test suite and print a Synopsis of results, as shown below.&lt;br /&gt;
&lt;br /&gt;
 Synopsis&lt;br /&gt;
 ========&lt;br /&gt;
 &lt;br /&gt;
 System/functional tests ....................................... [ OK ]&lt;br /&gt;
 Unit tests .................................................... [ OK ]&lt;br /&gt;
 Simgear unit tests ............................................ [ OK ]&lt;br /&gt;
 FGData tests .................................................. [ OK ]&lt;br /&gt;
 Synopsis ...................................................... [ OK ]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also run individual test cases. Run &amp;lt;code&amp;gt;./test_suite/fgfs_test_suite -h&amp;lt;/code&amp;gt; to see the various options&lt;br /&gt;
&lt;br /&gt;
For example, fgfs_test_suite --log-level=alert -d -u GPSTests will run the GPS unit tests while displaying the output.&lt;br /&gt;
&lt;br /&gt;
=== Why write unit tests? ===&lt;br /&gt;
&lt;br /&gt;
A well-tested piece of software will have a much lower bug count/load. An extensive test suite with &amp;quot;'unit tests,'&amp;quot; system/functional tests, GUI tests, installer tests, and other categories of tests can significantly help in this regard.&lt;br /&gt;
&lt;br /&gt;
The benefits of not just chasing clear &amp;quot;wins&amp;quot; are great: An excellent learning experience for new developers; the ability to catch latent, unreported bugs; making it easier to refactor current code by creating a safety net; making it easier for current developers to accept new contributions (when accompanied with passing tests); helping other test writers by contributing to the standard test suite infrastructure; and being able to check for memory leaks or other issues via Valgrind easily.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36977686/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you are a new developer, jump in and write any test! It does not need to catch a bug. Do whatever you wish! Just dive into this shallow end, and you'll see that the water is not cold.&lt;br /&gt;
&lt;br /&gt;
You are writing a test as a safety net. You write the test to pass, make your changes, and then make sure that the test still passes. Then, you push both the test and core changes.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36977465/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It'd be better to work in a specific area of interest to you and submit merge requests. When reviewed, that would usually trigger some C++ feedback, but we aren't looking for perfection here. The feedback you receive during the open and public review process increases our overall pool of knowledge of what best practice looks like, even if a given commit is less than perfect.&lt;br /&gt;
&lt;br /&gt;
Having 10 or 20 people actively contributing correct and reasonable code is more important than three people contributing perfect, micro-optimised C++. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36951247/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Benefits of unit testing ===&lt;br /&gt;
There are lots of benefits to writing tests that pass.&lt;br /&gt;
&lt;br /&gt;
Benefits include :&lt;br /&gt;
&lt;br /&gt;
* Learning! New developers can learn a ton from writing several passing tests in the area they are interested in. This is one of the quickest ways to learn about a pre-existing and mature code base. You have zero worries about breaking things.&lt;br /&gt;
&lt;br /&gt;
* Latent bug uncovering. One will probably fail every ten tests you write, expecting them to pass. Tests may uncover unexpected behavior that a developer can improve.&lt;br /&gt;
&lt;br /&gt;
* Refactoring. If we had 10,000 passing tests (assuming universal test coverage), large-scale refactoring of the entire code base would be quick and reliable. It would enable refactoring on a scale currently unimaginable. I cannot emphasize enough how much of a benefit this would be.&lt;br /&gt;
&lt;br /&gt;
* Developer turnover. Again, if we had 10,000 passing tests (assuming universal test coverage), it would encourage new developers, giving them confidence that their changes will not cause problems. It is a safety net. It also would provide existing developers peace of mind when a new developer works in one of the dark parts of FlightGear that no current developer understands (there are plenty of those).&lt;br /&gt;
&lt;br /&gt;
* Test suite infrastructure. The more passing tests written, the better the test suite infrastructure will become. We can already do a lot, but adding more passing tests will help other test writers.&lt;br /&gt;
&lt;br /&gt;
* Memory checking. Running a single test through Valgrind is fantastic. Running FlightGear through Valgrind is close to impossible. One can write tests that pass but are useful under Valgrind to catch memory leaks!&lt;br /&gt;
&lt;br /&gt;
* Code quality and standards. If a test compiles on all OSes without warning, it passes, and Valgrind gives you an ok, it is good enough. You don't need to be a C++ expert to dive into this shallow end of the pool.&lt;br /&gt;
&lt;br /&gt;
=== Bootstrapping completely new tests ===&lt;br /&gt;
To start diving straight into the test suite code, firstly copy what has been done in this commit:  {{repo link&lt;br /&gt;
| site   = sf&lt;br /&gt;
| user = edauvergne&lt;br /&gt;
| repo   = flightgear&lt;br /&gt;
| commit = 8474df&lt;br /&gt;
| view   = commit&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Just modify all names for a JSBSim test (or any other test fixture you&lt;br /&gt;
want to code). You should then be able to compile and check that your&lt;br /&gt;
new test dummy () test passes as expected. You can then slowly build up&lt;br /&gt;
from this basic infrastructure as you learn the fgfs internals, c++,&lt;br /&gt;
and git skills required for implementing your test on your fork's new&lt;br /&gt;
development branch :)&lt;br /&gt;
&lt;br /&gt;
For a step by step description of how to add new tests &lt;br /&gt;
 see: [[Software Testing/Adding CPPUnit Tests]]&lt;br /&gt;
&lt;br /&gt;
For a detailed explanation of everything in the flightgear/test_suite folder, top to bottom level, &lt;br /&gt;
 see: [[Software Testing/Flightgear Test Suite Details]]&lt;br /&gt;
&lt;br /&gt;
===Headless testing===&lt;br /&gt;
{{Main article|FlightGear Headless}}&lt;br /&gt;
&lt;br /&gt;
For an FDM+systems test, we should run FG without a renderer (which is what the test_suite does) to benchmark the pure C++ performance of whatever system we care about (FDM or whatever). But a few hours playing with 'perf' on Linux or Instruments on macOS will show you that OSG + the GL drivers use 80% of our CPU time, and hence Amdhal's law will always get you.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36977666/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Graphics testing===&lt;br /&gt;
{{See also|FlightGear Benchmark}}&lt;br /&gt;
&lt;br /&gt;
Create test-case scenes where you can quickly measure differences and compare via screenshots. The brain/eye/memory are terrible at this stuff, setup something you can load from the command line via a script to test old/new versions, if possible. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36959002/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, a test would use several rc files (.[[fgfsrc]] variants, with different renderers and threading modes, including static values for:&lt;br /&gt;
*c172p at some parking in a detailed airport&lt;br /&gt;
*camera set with a specific direction and field of view&lt;br /&gt;
*AW with specific METARs around (if not possible, BW with specific METAR)&lt;br /&gt;
*fixed rendering settings ( &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36975122/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We can load a [[Instant Replay|replay tape]] on startup. Since the FDM and User interface are unavailable, replays are suitable for testing rendering and performance.&lt;br /&gt;
&lt;br /&gt;
But essentially, small amounts of shell script + Nasal hacking, can implement any of these methods,  and any of them would be welcome additions. The unit-test framework is excellent for lower-level tests run by developers (i.e., 'Does the API call produce the right results in the system?'), but a smoke test that regular users can run would be ideal. &lt;br /&gt;
&lt;br /&gt;
A rendering performance would likely do the following:&lt;br /&gt;
&lt;br /&gt;
*Select some particular rendering settings (clouds, draw distance, etc)&lt;br /&gt;
*Run a saved fgtape recording&lt;br /&gt;
* Record the mean/min/max FPS during this and save it in some text file/copy to the clipboard&lt;br /&gt;
&lt;br /&gt;
So yes, if anyone wants to work on the above, the code is all there. Please jump in and start hacking. I don't think it needs any more from the core code, but as always, please ask if it does.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36975213/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, when describing a /rendering/ test (to establish FPS), the advantage of a replay tape is that the actual position (and, therefore, the rendered scene) will be 100% consistent across different computers.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that the CPU use of the FDM+systems is typically &amp;lt; 10% of our total CPU use, even when running OSG single-threaded, so for a rendering performance test, whether the FD is run or not is probably noise compared to other things that do run (Nasal, Canvas for example)&lt;br /&gt;
&lt;br /&gt;
Also, the Multi-monitor setup is an area that could use additional unit testing. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36904782/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Fgdata==&lt;br /&gt;
===Nasal scripting (comments)===&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
The now builtin CppUnit framework can solve all the issues&lt;br /&gt;
identified in the old [[Nasal Unit Testing Framework]] wiki article and the discussions it points to&lt;br /&gt;
and provide the full framework required.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36990615/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have some very simple tests running now for the route manager, which relies on Nasal. We're skipping a few of the bigger Nasal modules (local weather, jetways) and have a few lingering issues in some other modules, but the basic concept is working. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
An exciting further step, which you might wish to discuss with Edward, is writing test checks *in* Nasal since this could be quite a fast way to test some areas of the code. There are several ways that could work, and I don't know if Edward has always planned something around this, so I won't preempt that conversation.&lt;br /&gt;
&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36764781/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
we have route-manager tests which validate route_manager.nas is working correctly, and we have Canavs tests ({{fg src file|path=test_suite/simgear_tests/canvas|}}) which poke the Nasal API. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36991200/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We need more FGData testing via the test suite.&lt;br /&gt;
&lt;br /&gt;
James has suggested adding CppUnit assertions to Nasal so others can write tests in pure Nasal. James would make these changes in C++.  &lt;br /&gt;
In addition, some C++ code in a test would scan a directory for files matching a pattern, e.g., test_XYZ.nas, and run each of those automatically.&lt;br /&gt;
&lt;br /&gt;
The idea for testing Nasal would be that you write a small CppUnit&lt;br /&gt;
interface in C++ in $FG_SRC/test_suite/*_tests/ (the FGData Nasal&lt;br /&gt;
testing would be in a fgdata_tests/ directory). This would register&lt;br /&gt;
each test which points to the script in&lt;br /&gt;
$FG_SRC/test_suite/shared_data/nasal/, and the setUp() and tearDown()&lt;br /&gt;
functions would use helper functions in the fgtest namespace to start&lt;br /&gt;
and stop Nasal. The Nasal scripts could then call the CppUnit&lt;br /&gt;
assertion macros wrapped up as Nasal functions for communicating&lt;br /&gt;
failures and errors to the test suite. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36991150/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Scanning for scripts is a great idea. Then, developers (core and content) could write tests using pure Nasal.&lt;br /&gt;
&lt;br /&gt;
However, all scripts found and executed will be seen as a single test within the test suite. So maybe we should have a $FG_SRC/test_suite/nasal_staging/ directory for the initial development of such auto-scanned scripts. But then we have someone shift them into $FG_SRC/test_suite/system_tests/, $FG_SRC/test_suite/unit_tests/, or $FG_SRC/test_suite/fgdata_tests/ later on?  That would give better diagnostics and would avoid long-term clutter.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36991198/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*First, we should probably hard code tests into the C++ framework. For this, the CppUnit assertion macros will have to be wrapped up as Nasal functions.&lt;br /&gt;
*Implement the scanning code as we need some CMake magic (probably using file(COPY, ...)).&lt;br /&gt;
*Finally, we must determine if and how to improve the Nnasaldebugging output.&lt;br /&gt;
&lt;br /&gt;
the code could go into a subdirectory in $FG_SRC/test_suite/fgdata_tests/, and the Nasal script in $FG_SRC/test_suite/shared_data/nasal/.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Core development]]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Software_Testing/Flightgear_Test_Suite_Details&amp;diff=140275</id>
		<title>Software Testing/Flightgear Test Suite Details</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Software_Testing/Flightgear_Test_Suite_Details&amp;diff=140275"/>
		<updated>2024-08-20T19:02:47Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Definitions =&lt;br /&gt;
&lt;br /&gt;
==Test Case==&lt;br /&gt;
 A single assertion about one or two variable values that is testable.&lt;br /&gt;
==Test Fixture==&lt;br /&gt;
 In CppUnit, a group of tests is called a TestFixture. A TestFixture provides a common environment for multiple test cases.&lt;br /&gt;
==App Component==&lt;br /&gt;
 Major parts of the application, usually corresponding to folders in flightgear/src or simgear/simgear&lt;br /&gt;
==Test Category== &lt;br /&gt;
 The type of testing: unit, system and simgear (library) tests&lt;br /&gt;
==Test Suite==&lt;br /&gt;
 All the tests and everything needed to support them&lt;br /&gt;
&lt;br /&gt;
= Top Level flightgear/test_suite folder =&lt;br /&gt;
&lt;br /&gt;
Take a look at the '''flightgear/test_suite''' folder in a file browser preferably one that allows you to see the folders on multiple levels such as a code editor like VsCode. Start in the top level of flightgear's repo sources look for a directory named '''test_suite'''.  Note that test_suite is not part of '''flightgear/src'''.&lt;br /&gt;
&lt;br /&gt;
'''flightgear/test_suite''' contains two kinds of testing resources. &lt;br /&gt;
&lt;br /&gt;
* '''Programs and data used in tests'''&lt;br /&gt;
* '''Groups of CPPUnit tests'''&lt;br /&gt;
&lt;br /&gt;
==Programs and data used in test modules==&lt;br /&gt;
&lt;br /&gt;
* individual files directly under test_suite&lt;br /&gt;
* test_data folder&lt;br /&gt;
* FGTestApi folder&lt;br /&gt;
* Groups of CPPUnit tests&lt;br /&gt;
&lt;br /&gt;
==Test Categories==&lt;br /&gt;
&lt;br /&gt;
* fgdata_tests - placeholder&lt;br /&gt;
* gui_tests - placeholder&lt;br /&gt;
* simgear_tests&lt;br /&gt;
* system_tests&lt;br /&gt;
* unit_tests&lt;br /&gt;
&lt;br /&gt;
Each of the last three test_suite/*_tests folders contain sub-folders covering some part of Flightgear's code.  They may roughly correspond to the folders under flightgear/src, but that is not a requirement.    Some areas may be covered in more than one *_tests folder.  FDM for example in unit_tests and system_tests.  &lt;br /&gt;
&lt;br /&gt;
== Folder Levels ==&lt;br /&gt;
&lt;br /&gt;
Note at this point that the maximum Folder depth is 3:&lt;br /&gt;
&lt;br /&gt;
# flightgear/test_suite Folder.&lt;br /&gt;
# Test-category folders ex: unit_tests, system_tests, simgear_tests&lt;br /&gt;
# App Component folders ex: FDM, Network, canvas.  These roughly correspond to specific flightgear/src folders, &lt;br /&gt;
&lt;br /&gt;
Expand the '''unit_tests''' test category folder&lt;br /&gt;
Expand the '''Network''' app component folder&lt;br /&gt;
&lt;br /&gt;
CPPUNIT test fixtures are implemented in test_*.cxx and test_*.hhx files int the Component category folders.&lt;br /&gt;
&lt;br /&gt;
== CMakeLists.txt, testSuite.cxx and TestSuite.cxx files ==&lt;br /&gt;
&lt;br /&gt;
CMakeLists.txt files exist at every level&lt;br /&gt;
TestSuite.cxx files are in each application component folders (bottom level)&lt;br /&gt;
testSuite.cxx is only at the top level&lt;br /&gt;
&lt;br /&gt;
# '''test_suite/CMakeLists.txt''' &amp;amp; test_suite/testSuite.cxx&lt;br /&gt;
# '''test_suite/[test-category]/CMakeLists.txt''' &lt;br /&gt;
# '''test_suite/[test-category]/[app-component]/CMakeLists.txt'''  and '''Test_suite.cxx'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
More to follow {{WIP}}&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Software_Testing/Flightgear_Test_Suite_Details&amp;diff=140274</id>
		<title>Software Testing/Flightgear Test Suite Details</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Software_Testing/Flightgear_Test_Suite_Details&amp;diff=140274"/>
		<updated>2024-08-20T18:59:08Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: Created page with &amp;quot;= Detailed Structure the Flightgear Test Suite =  Software Testing/Flightgear Test Suite Details == Definitions ==  ===Test Case===  A single assertion about one or two variable values that is testable. ===Test Fixture===  In CppUnit, a group of tests is called a TestFixture. A TestFixture provides a common environment for multiple test cases. ===App Component===  Major parts of the application, usually corresponding to folders in flightgear/src or simgear/simgear ==...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Detailed Structure the Flightgear Test Suite =&lt;br /&gt;
&lt;br /&gt;
[[Software Testing/Flightgear Test Suite Details]]&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
===Test Case===&lt;br /&gt;
 A single assertion about one or two variable values that is testable.&lt;br /&gt;
===Test Fixture===&lt;br /&gt;
 In CppUnit, a group of tests is called a TestFixture. A TestFixture provides a common environment for multiple test cases.&lt;br /&gt;
===App Component===&lt;br /&gt;
 Major parts of the application, usually corresponding to folders in flightgear/src or simgear/simgear&lt;br /&gt;
===Test Category=== &lt;br /&gt;
 The type of testing: unit, system and simgear (library) tests&lt;br /&gt;
===Test Suite===&lt;br /&gt;
 All the tests and everything needed to support them&lt;br /&gt;
&lt;br /&gt;
== Top Level flightgear/test_suite folder ==&lt;br /&gt;
&lt;br /&gt;
Take a look at the '''flightgear/test_suite''' folder in a file browser preferably one that allows you to see the folders on multiple levels such as a code editor like VsCode. Start in the top level of flightgear's repo sources look for a directory named '''test_suite'''.  Note that test_suite is not part of '''flightgear/src'''.&lt;br /&gt;
&lt;br /&gt;
'''flightgear/test_suite''' contains two kinds of testing resources. &lt;br /&gt;
&lt;br /&gt;
* '''Programs and data used in tests'''&lt;br /&gt;
* '''Groups of CPPUnit tests'''&lt;br /&gt;
&lt;br /&gt;
===Programs and data used in test modules===&lt;br /&gt;
&lt;br /&gt;
* individual files directly under test_suite&lt;br /&gt;
* test_data folder&lt;br /&gt;
* FGTestApi folder&lt;br /&gt;
* Groups of CPPUnit tests&lt;br /&gt;
&lt;br /&gt;
=====Test Categories=====&lt;br /&gt;
&lt;br /&gt;
* fgdata_tests - placeholder&lt;br /&gt;
* gui_tests - placeholder&lt;br /&gt;
* simgear_tests&lt;br /&gt;
* system_tests&lt;br /&gt;
* unit_tests&lt;br /&gt;
&lt;br /&gt;
Each of the last three test_suite/*_tests folders contain sub-folders covering some part of Flightgear's code.  They may roughly correspond to the folders under flightgear/src, but that is not a requirement.    Some areas may be covered in more than one *_tests folder.  FDM for example in unit_tests and system_tests.  &lt;br /&gt;
&lt;br /&gt;
==== Folder Levels ====&lt;br /&gt;
&lt;br /&gt;
Note at this point that the maximum Folder depth is 3:&lt;br /&gt;
&lt;br /&gt;
# flightgear/test_suite Folder.&lt;br /&gt;
# Test-category folders ex: unit_tests, system_tests, simgear_tests&lt;br /&gt;
# App Component folders ex: FDM, Network, canvas.  These roughly correspond to specific flightgear/src folders, &lt;br /&gt;
&lt;br /&gt;
Expand the '''unit_tests''' test category folder&lt;br /&gt;
Expand the '''Network''' app component folder&lt;br /&gt;
&lt;br /&gt;
CPPUNIT test fixtures are implemented in test_*.cxx and test_*.hhx files int the Component category folders.&lt;br /&gt;
&lt;br /&gt;
==== CMakeLists.txt, testSuite.cxx and TestSuite.cxx files ====&lt;br /&gt;
&lt;br /&gt;
CMakeLists.txt files exist at every level&lt;br /&gt;
TestSuite.cxx files are in each application component folders (bottom level)&lt;br /&gt;
testSuite.cxx is only at the top level&lt;br /&gt;
&lt;br /&gt;
# '''test_suite/CMakeLists.txt''' &amp;amp; test_suite/testSuite.cxx&lt;br /&gt;
# '''test_suite/[test-category]/CMakeLists.txt''' &lt;br /&gt;
# '''test_suite/[test-category]/[app-component]/CMakeLists.txt'''  and '''Test_suite.cxx'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
More to follow {{WIP}}&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Software_testing&amp;diff=140271</id>
		<title>Software testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Software_testing&amp;diff=140271"/>
		<updated>2024-08-20T18:39:38Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: /* Definitions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Note|There’s already the test_suite in {{fg src file|path=test_suite}} using [[Cppunit effort|CppUnit]], thanks to some hard work by [[User:Bugman|Edward]]. We need more tests written for it; submissions are welcome. (Pick an area of interest)&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36972720/&amp;lt;/ref&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{See also|Cppunit effort}}&lt;br /&gt;
&lt;br /&gt;
FlightGear developers use various testing tools. This includes automated testing via unit tests in [[SimGear]] and a full test suite with multiple test categories in the [[FlightGear Git|flightgear repository]], as well as manual in-sim testing. Writing tests is one of the best ways to jump into FlightGear development.&lt;br /&gt;
&lt;br /&gt;
One improving area is unit testing: certain areas and features (e.g., carrier start) now 'can't break.' As we add testing in additional areas (e.g., Multi-player, AI, protocols, and replay are all possible), we increase the baseline quality and have a clearer idea when we make incompatible changes. (The idea is that we capture the 'supported API' in the tests: when an aircraft deviates from that, we can decide to add another test case, fix the aircraft, etc). Of course, there are some pretty significant areas where Automated Testing Is Hard (TM).&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/37078825/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== SimGear ==&lt;br /&gt;
&lt;br /&gt;
Unit testing for the [[SimGear]] sources uses the CMake CTest unit testing infrastructure. Several tests use the BOOST unit testing infrastructure tied to the build system using CTest; however, the FlightGear developers are shifting towards eliminating BOOST, so CPPUnit and CTest tests are preferred.&lt;br /&gt;
&lt;br /&gt;
=== Building and running the SimGear tests ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ make&lt;br /&gt;
$ ctest&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== FlightGear ==&lt;br /&gt;
&lt;br /&gt;
Testing of the [[FlightGear Git|flightgear sources]] is via a comprehensive test suite implemented using [https://www.freedesktop.org/wiki/Software/cppunit/ CppUnit], a port of the famous JUnit framework.&lt;br /&gt;
&lt;br /&gt;
=== Building the test suite ===&lt;br /&gt;
&lt;br /&gt;
You must build FlightGear from the source using cmake to run the tests. See [[Building FlightGear]] for details.&lt;br /&gt;
&lt;br /&gt;
Once you have your cmake build environment, do the following:&lt;br /&gt;
# Change to your FlightGear build* directory&lt;br /&gt;
# Enable building the tests by setting a cmake variable:  &amp;lt;code&amp;gt;cmake -DBUILD_TESTING=ON .&amp;lt;/code&amp;gt;&lt;br /&gt;
# Ensure the &amp;lt;code&amp;gt;[[$FG ROOT|$FG_ROOT]]&amp;lt;/code&amp;gt; environment variable points to fgdata e.g. &amp;lt;code&amp;gt;$FG_INSTALL_DIR/share/fgdata&amp;lt;/code&amp;gt;&lt;br /&gt;
# Build the test suite:  &amp;lt;code&amp;gt;make test_suite&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Building the test suite will also run a test because you will typically want to write a test and then immediately compile and run it.&lt;br /&gt;
&lt;br /&gt;
 * ls in this directory should include CMakeCache.txt, cmake_install, and others. You do not want to run cmake in the flightgear sources directory, which includes files such as AUTHORS, COPYING, INSTALL, etc.&lt;br /&gt;
&lt;br /&gt;
On a Windows MSVC-based build environment, after generating files with cmake, run the following code:&lt;br /&gt;
# cmake --build . --config RelWithDebInfo --target test_suite/test_suite&lt;br /&gt;
&lt;br /&gt;
=== Running the test suite ===&lt;br /&gt;
&lt;br /&gt;
To run the test suite, simply run &amp;lt;code&amp;gt;./test_suite/fgfs_test_suite&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Executing fgfs_test_suite will run the entire test suite and print a Synopsis of results, as shown below.&lt;br /&gt;
&lt;br /&gt;
 Synopsis&lt;br /&gt;
 ========&lt;br /&gt;
 &lt;br /&gt;
 System/functional tests ....................................... [ OK ]&lt;br /&gt;
 Unit tests .................................................... [ OK ]&lt;br /&gt;
 Simgear unit tests ............................................ [ OK ]&lt;br /&gt;
 FGData tests .................................................. [ OK ]&lt;br /&gt;
 Synopsis ...................................................... [ OK ]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also run individual test cases. Run &amp;lt;code&amp;gt;./test_suite/fgfs_test_suite -h&amp;lt;/code&amp;gt; to see the various options&lt;br /&gt;
&lt;br /&gt;
For example, fgfs_test_suite --log-level=alert -d -u GPSTests will run the GPS unit tests while displaying the output.&lt;br /&gt;
&lt;br /&gt;
=== Why write unit tests? ===&lt;br /&gt;
&lt;br /&gt;
A well-tested piece of software will have a much lower bug count/load. An extensive test suite with &amp;quot;'unit tests,'&amp;quot; system/functional tests, GUI tests, installer tests, and other categories of tests can significantly help in this regard.&lt;br /&gt;
&lt;br /&gt;
The benefits of not just chasing clear &amp;quot;wins&amp;quot; are great: An excellent learning experience for new developers; the ability to catch latent, unreported bugs; making it easier to refactor current code by creating a safety net; making it easier for current developers to accept new contributions (when accompanied with passing tests); helping other test writers by contributing to the standard test suite infrastructure; and being able to check for memory leaks or other issues via Valgrind easily.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36977686/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you are a new developer, jump in and write any test! It does not need to catch a bug. Do whatever you wish! Just dive into this shallow end, and you'll see that the water is not cold.&lt;br /&gt;
&lt;br /&gt;
You are writing a test as a safety net. You write the test to pass, make your changes, and then make sure that the test still passes. Then, you push both the test and core changes.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36977465/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It'd be better to work in a specific area of interest to you and submit merge requests. When reviewed, that would usually trigger some C++ feedback, but we aren't looking for perfection here. The feedback you receive during the open and public review process increases our overall pool of knowledge of what best practice looks like, even if a given commit is less than perfect.&lt;br /&gt;
&lt;br /&gt;
Having 10 or 20 people actively contributing correct and reasonable code is more important than three people contributing perfect, micro-optimised C++. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36951247/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Benefits of unit testing ===&lt;br /&gt;
There are lots of benefits to writing tests that pass.&lt;br /&gt;
&lt;br /&gt;
Benefits include :&lt;br /&gt;
&lt;br /&gt;
* Learning! New developers can learn a ton from writing several passing tests in the area they are interested in. This is one of the quickest ways to learn about a pre-existing and mature code base. You have zero worries about breaking things.&lt;br /&gt;
&lt;br /&gt;
* Latent bug uncovering. One will probably fail every ten tests you write, expecting them to pass. Tests may uncover unexpected behavior that a developer can improve.&lt;br /&gt;
&lt;br /&gt;
* Refactoring. If we had 10,000 passing tests (assuming universal test coverage), large-scale refactoring of the entire code base would be quick and reliable. It would enable refactoring on a scale currently unimaginable. I cannot emphasize enough how much of a benefit this would be.&lt;br /&gt;
&lt;br /&gt;
* Developer turnover. Again, if we had 10,000 passing tests (assuming universal test coverage), it would encourage new developers, giving them confidence that their changes will not cause problems. It is a safety net. It also would provide existing developers peace of mind when a new developer works in one of the dark parts of FlightGear that no current developer understands (there are plenty of those).&lt;br /&gt;
&lt;br /&gt;
* Test suite infrastructure. The more passing tests written, the better the test suite infrastructure will become. We can already do a lot, but adding more passing tests will help other test writers.&lt;br /&gt;
&lt;br /&gt;
* Memory checking. Running a single test through Valgrind is fantastic. Running FlightGear through Valgrind is close to impossible. One can write tests that pass but are useful under Valgrind to catch memory leaks!&lt;br /&gt;
&lt;br /&gt;
* Code quality and standards. If a test compiles on all OSes without warning, it passes, and Valgrind gives you an ok, it is good enough. You don't need to be a C++ expert to dive into this shallow end of the pool.&lt;br /&gt;
&lt;br /&gt;
=== Bootstrapping completely new tests ===&lt;br /&gt;
To start diving straight into the test suite code, firstly copy what has been done in this commit:  {{repo link&lt;br /&gt;
| site   = sf&lt;br /&gt;
| user = edauvergne&lt;br /&gt;
| repo   = flightgear&lt;br /&gt;
| commit = 8474df&lt;br /&gt;
| view   = commit&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Just modify all names for a JSBSim test (or any other test fixture you&lt;br /&gt;
want to code). You should then be able to compile and check that your&lt;br /&gt;
new test dummy () test passes as expected. You can then slowly build up&lt;br /&gt;
from this basic infrastructure as you learn the fgfs internals, c++,&lt;br /&gt;
and git skills required for implementing your test on your fork's new&lt;br /&gt;
development branch :)&lt;br /&gt;
&lt;br /&gt;
=== Structure of a CPPUnit test ===&lt;br /&gt;
&lt;br /&gt;
==== Definitions ====&lt;br /&gt;
&lt;br /&gt;
=====Test Case=====&lt;br /&gt;
 A single assertion about one or two variable values that is testable.&lt;br /&gt;
=====Test Fixture=====&lt;br /&gt;
 In CppUnit, a group of tests is called a TestFixture. A TestFixture provides a common environment for multiple test cases.&lt;br /&gt;
=====App Component=====&lt;br /&gt;
 Major parts of the application, usually corresponding to folders in flightgear/src or simgear/simgear&lt;br /&gt;
=====Test Category===== &lt;br /&gt;
 The type of testing: unit, system and simgear (library) tests&lt;br /&gt;
=====Test Suite=====&lt;br /&gt;
 All the tests and everything needed to support them&lt;br /&gt;
&lt;br /&gt;
==== Top Level Test Folder ====&lt;br /&gt;
&lt;br /&gt;
Take a look at the '''flightgear/test_suite''' folder in a file browser preferably one that allows you to see the folders on multiple levels such as a code editor like VsCode. Start in the top level of flightgear's repo sources look for a directory named '''test_suite'''.  Note that test_suite is not part of '''flightgear/src'''.&lt;br /&gt;
&lt;br /&gt;
====flightgear/test_suite folder====&lt;br /&gt;
&lt;br /&gt;
'''flightgear/test_suite''' contains two kinds of testing resources. &lt;br /&gt;
&lt;br /&gt;
* Programs and data used in tests&lt;br /&gt;
* Groups of CPPUnit tests&lt;br /&gt;
&lt;br /&gt;
=====Programs and data used in test modules=====&lt;br /&gt;
&lt;br /&gt;
* individual files directly under test_suite&lt;br /&gt;
* test_data folder&lt;br /&gt;
* FGTestApi folder&lt;br /&gt;
* Groups of CPPUnit tests&lt;br /&gt;
&lt;br /&gt;
=====Test Categories=====&lt;br /&gt;
&lt;br /&gt;
* fgdata_tests - placeholder&lt;br /&gt;
* gui_tests - placeholder&lt;br /&gt;
* simgear_tests&lt;br /&gt;
* system_tests&lt;br /&gt;
* unit_tests&lt;br /&gt;
&lt;br /&gt;
Each of the last three test_suite/*_tests folders contain sub-folders covering some part of Flightgear's code.  They may roughly correspond to the folders under flightgear/src, but that is not a requirement.    Some areas may be covered in more than one *_tests folder.  FDM for example in unit_tests and system_tests.  &lt;br /&gt;
&lt;br /&gt;
==== Folder Levels ====&lt;br /&gt;
&lt;br /&gt;
Note at this point that the maximum Folder depth is 3:&lt;br /&gt;
&lt;br /&gt;
# flightgear/test_suite Folder.&lt;br /&gt;
# Test-category folders ex: unit_tests, system_tests, simgear_tests&lt;br /&gt;
# App Component folders ex: FDM, Network, canvas.  These roughly correspond to specific flightgear/src folders, &lt;br /&gt;
&lt;br /&gt;
Expand the '''unit_tests''' test category folder&lt;br /&gt;
Expand the '''Network''' app component folder&lt;br /&gt;
&lt;br /&gt;
CPPUNIT test fixtures are implemented in test_*.cxx and test_*.hhx files int the Component category folders.&lt;br /&gt;
&lt;br /&gt;
==== CMakeLists.txt, testSuite.cxx and TestSuite.cxx files ====&lt;br /&gt;
&lt;br /&gt;
CMakeLists.txt files exist at every level&lt;br /&gt;
TestSuite.cxx files are in each application component folders (bottom level)&lt;br /&gt;
testSuite.cxx is only at the top level&lt;br /&gt;
&lt;br /&gt;
# '''test_suite/CMakeLists.txt''' &amp;amp; test_suite/testSuite.cxx&lt;br /&gt;
# '''test_suite/[test-category]/CMakeLists.txt''' &lt;br /&gt;
# '''test_suite/[test-category]/[app-component]/CMakeLists.txt'''  and '''Test_suite.cxx'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
More to follow {{WIP}}&lt;br /&gt;
&lt;br /&gt;
===Headless testing===&lt;br /&gt;
{{Main article|FlightGear Headless}}&lt;br /&gt;
&lt;br /&gt;
For an FDM+systems test, we should run FG without a renderer (which is what the test_suite does) to benchmark the pure C++ performance of whatever system we care about (FDM or whatever). But a few hours playing with 'perf' on Linux or Instruments on macOS will show you that OSG + the GL drivers use 80% of our CPU time, and hence Amdhal's law will always get you.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36977666/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Graphics testing===&lt;br /&gt;
{{See also|FlightGear Benchmark}}&lt;br /&gt;
&lt;br /&gt;
Create test-case scenes where you can quickly measure differences and compare via screenshots. The brain/eye/memory are terrible at this stuff, setup something you can load from the command line via a script to test old/new versions, if possible. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36959002/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, a test would use several rc files (.[[fgfsrc]] variants, with different renderers and threading modes, including static values for:&lt;br /&gt;
*c172p at some parking in a detailed airport&lt;br /&gt;
*camera set with a specific direction and field of view&lt;br /&gt;
*AW with specific METARs around (if not possible, BW with specific METAR)&lt;br /&gt;
*fixed rendering settings ( &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36975122/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We can load a [[Instant Replay|replay tape]] on startup. Since the FDM and User interface are unavailable, replays are suitable for testing rendering and performance.&lt;br /&gt;
&lt;br /&gt;
But essentially, small amounts of shell script + Nasal hacking, can implement any of these methods,  and any of them would be welcome additions. The unit-test framework is excellent for lower-level tests run by developers (i.e., 'Does the API call produce the right results in the system?'), but a smoke test that regular users can run would be ideal. &lt;br /&gt;
&lt;br /&gt;
A rendering performance would likely do the following:&lt;br /&gt;
&lt;br /&gt;
*Select some particular rendering settings (clouds, draw distance, etc)&lt;br /&gt;
*Run a saved fgtape recording&lt;br /&gt;
* Record the mean/min/max FPS during this and save it in some text file/copy to the clipboard&lt;br /&gt;
&lt;br /&gt;
So yes, if anyone wants to work on the above, the code is all there. Please jump in and start hacking. I don't think it needs any more from the core code, but as always, please ask if it does.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36975213/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, when describing a /rendering/ test (to establish FPS), the advantage of a replay tape is that the actual position (and, therefore, the rendered scene) will be 100% consistent across different computers.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that the CPU use of the FDM+systems is typically &amp;lt; 10% of our total CPU use, even when running OSG single-threaded, so for a rendering performance test, whether the FD is run or not is probably noise compared to other things that do run (Nasal, Canvas for example)&lt;br /&gt;
&lt;br /&gt;
Also, the Multi-monitor setup is an area that could use additional unit testing. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36904782/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Fgdata==&lt;br /&gt;
===Nasal scripting (comments)===&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
The now builtin CppUnit framework can solve all the issues&lt;br /&gt;
identified in the old [[Nasal Unit Testing Framework]] wiki article and the discussions it points to&lt;br /&gt;
and provide the full framework required.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36990615/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have some very simple tests running now for the route manager, which relies on Nasal. We're skipping a few of the bigger Nasal modules (local weather, jetways) and have a few lingering issues in some other modules, but the basic concept is working. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
An exciting further step, which you might wish to discuss with Edward, is writing test checks *in* Nasal since this could be quite a fast way to test some areas of the code. There are several ways that could work, and I don't know if Edward has always planned something around this, so I won't preempt that conversation.&lt;br /&gt;
&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36764781/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
we have route-manager tests which validate route_manager.nas is working correctly, and we have Canavs tests ({{fg src file|path=test_suite/simgear_tests/canvas|}}) which poke the Nasal API. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36991200/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We need more FGData testing via the test suite.&lt;br /&gt;
&lt;br /&gt;
James has suggested adding CppUnit assertions to Nasal so others can write tests in pure Nasal. James would make these changes in C++.  &lt;br /&gt;
In addition, some C++ code in a test would scan a directory for files matching a pattern, e.g., test_XYZ.nas, and run each of those automatically.&lt;br /&gt;
&lt;br /&gt;
The idea for testing Nasal would be that you write a small CppUnit&lt;br /&gt;
interface in C++ in $FG_SRC/test_suite/*_tests/ (the FGData Nasal&lt;br /&gt;
testing would be in a fgdata_tests/ directory). This would register&lt;br /&gt;
each test which points to the script in&lt;br /&gt;
$FG_SRC/test_suite/shared_data/nasal/, and the setUp() and tearDown()&lt;br /&gt;
functions would use helper functions in the fgtest namespace to start&lt;br /&gt;
and stop Nasal. The Nasal scripts could then call the CppUnit&lt;br /&gt;
assertion macros wrapped up as Nasal functions for communicating&lt;br /&gt;
failures and errors to the test suite. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36991150/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Scanning for scripts is a great idea. Then, developers (core and content) could write tests using pure Nasal.&lt;br /&gt;
&lt;br /&gt;
However, all scripts found and executed will be seen as a single test within the test suite. So maybe we should have a $FG_SRC/test_suite/nasal_staging/ directory for the initial development of such auto-scanned scripts. But then we have someone shift them into $FG_SRC/test_suite/system_tests/, $FG_SRC/test_suite/unit_tests/, or $FG_SRC/test_suite/fgdata_tests/ later on?  That would give better diagnostics and would avoid long-term clutter.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36991198/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*First, we should probably hard code tests into the C++ framework. For this, the CppUnit assertion macros will have to be wrapped up as Nasal functions.&lt;br /&gt;
*Implement the scanning code as we need some CMake magic (probably using file(COPY, ...)).&lt;br /&gt;
*Finally, we must determine if and how to improve the Nnasaldebugging output.&lt;br /&gt;
&lt;br /&gt;
the code could go into a subdirectory in $FG_SRC/test_suite/fgdata_tests/, and the Nasal script in $FG_SRC/test_suite/shared_data/nasal/.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Core development]]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Software_testing&amp;diff=140269</id>
		<title>Software testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Software_testing&amp;diff=140269"/>
		<updated>2024-08-20T18:37:22Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: /* Definitions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Note|There’s already the test_suite in {{fg src file|path=test_suite}} using [[Cppunit effort|CppUnit]], thanks to some hard work by [[User:Bugman|Edward]]. We need more tests written for it; submissions are welcome. (Pick an area of interest)&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36972720/&amp;lt;/ref&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{See also|Cppunit effort}}&lt;br /&gt;
&lt;br /&gt;
FlightGear developers use various testing tools. This includes automated testing via unit tests in [[SimGear]] and a full test suite with multiple test categories in the [[FlightGear Git|flightgear repository]], as well as manual in-sim testing. Writing tests is one of the best ways to jump into FlightGear development.&lt;br /&gt;
&lt;br /&gt;
One improving area is unit testing: certain areas and features (e.g., carrier start) now 'can't break.' As we add testing in additional areas (e.g., Multi-player, AI, protocols, and replay are all possible), we increase the baseline quality and have a clearer idea when we make incompatible changes. (The idea is that we capture the 'supported API' in the tests: when an aircraft deviates from that, we can decide to add another test case, fix the aircraft, etc). Of course, there are some pretty significant areas where Automated Testing Is Hard (TM).&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/37078825/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== SimGear ==&lt;br /&gt;
&lt;br /&gt;
Unit testing for the [[SimGear]] sources uses the CMake CTest unit testing infrastructure. Several tests use the BOOST unit testing infrastructure tied to the build system using CTest; however, the FlightGear developers are shifting towards eliminating BOOST, so CPPUnit and CTest tests are preferred.&lt;br /&gt;
&lt;br /&gt;
=== Building and running the SimGear tests ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ make&lt;br /&gt;
$ ctest&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== FlightGear ==&lt;br /&gt;
&lt;br /&gt;
Testing of the [[FlightGear Git|flightgear sources]] is via a comprehensive test suite implemented using [https://www.freedesktop.org/wiki/Software/cppunit/ CppUnit], a port of the famous JUnit framework.&lt;br /&gt;
&lt;br /&gt;
=== Building the test suite ===&lt;br /&gt;
&lt;br /&gt;
You must build FlightGear from the source using cmake to run the tests. See [[Building FlightGear]] for details.&lt;br /&gt;
&lt;br /&gt;
Once you have your cmake build environment, do the following:&lt;br /&gt;
# Change to your FlightGear build* directory&lt;br /&gt;
# Enable building the tests by setting a cmake variable:  &amp;lt;code&amp;gt;cmake -DBUILD_TESTING=ON .&amp;lt;/code&amp;gt;&lt;br /&gt;
# Ensure the &amp;lt;code&amp;gt;[[$FG ROOT|$FG_ROOT]]&amp;lt;/code&amp;gt; environment variable points to fgdata e.g. &amp;lt;code&amp;gt;$FG_INSTALL_DIR/share/fgdata&amp;lt;/code&amp;gt;&lt;br /&gt;
# Build the test suite:  &amp;lt;code&amp;gt;make test_suite&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Building the test suite will also run a test because you will typically want to write a test and then immediately compile and run it.&lt;br /&gt;
&lt;br /&gt;
 * ls in this directory should include CMakeCache.txt, cmake_install, and others. You do not want to run cmake in the flightgear sources directory, which includes files such as AUTHORS, COPYING, INSTALL, etc.&lt;br /&gt;
&lt;br /&gt;
On a Windows MSVC-based build environment, after generating files with cmake, run the following code:&lt;br /&gt;
# cmake --build . --config RelWithDebInfo --target test_suite/test_suite&lt;br /&gt;
&lt;br /&gt;
=== Running the test suite ===&lt;br /&gt;
&lt;br /&gt;
To run the test suite, simply run &amp;lt;code&amp;gt;./test_suite/fgfs_test_suite&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Executing fgfs_test_suite will run the entire test suite and print a Synopsis of results, as shown below.&lt;br /&gt;
&lt;br /&gt;
 Synopsis&lt;br /&gt;
 ========&lt;br /&gt;
 &lt;br /&gt;
 System/functional tests ....................................... [ OK ]&lt;br /&gt;
 Unit tests .................................................... [ OK ]&lt;br /&gt;
 Simgear unit tests ............................................ [ OK ]&lt;br /&gt;
 FGData tests .................................................. [ OK ]&lt;br /&gt;
 Synopsis ...................................................... [ OK ]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also run individual test cases. Run &amp;lt;code&amp;gt;./test_suite/fgfs_test_suite -h&amp;lt;/code&amp;gt; to see the various options&lt;br /&gt;
&lt;br /&gt;
For example, fgfs_test_suite --log-level=alert -d -u GPSTests will run the GPS unit tests while displaying the output.&lt;br /&gt;
&lt;br /&gt;
=== Why write unit tests? ===&lt;br /&gt;
&lt;br /&gt;
A well-tested piece of software will have a much lower bug count/load. An extensive test suite with &amp;quot;'unit tests,'&amp;quot; system/functional tests, GUI tests, installer tests, and other categories of tests can significantly help in this regard.&lt;br /&gt;
&lt;br /&gt;
The benefits of not just chasing clear &amp;quot;wins&amp;quot; are great: An excellent learning experience for new developers; the ability to catch latent, unreported bugs; making it easier to refactor current code by creating a safety net; making it easier for current developers to accept new contributions (when accompanied with passing tests); helping other test writers by contributing to the standard test suite infrastructure; and being able to check for memory leaks or other issues via Valgrind easily.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36977686/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you are a new developer, jump in and write any test! It does not need to catch a bug. Do whatever you wish! Just dive into this shallow end, and you'll see that the water is not cold.&lt;br /&gt;
&lt;br /&gt;
You are writing a test as a safety net. You write the test to pass, make your changes, and then make sure that the test still passes. Then, you push both the test and core changes.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36977465/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It'd be better to work in a specific area of interest to you and submit merge requests. When reviewed, that would usually trigger some C++ feedback, but we aren't looking for perfection here. The feedback you receive during the open and public review process increases our overall pool of knowledge of what best practice looks like, even if a given commit is less than perfect.&lt;br /&gt;
&lt;br /&gt;
Having 10 or 20 people actively contributing correct and reasonable code is more important than three people contributing perfect, micro-optimised C++. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36951247/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Benefits of unit testing ===&lt;br /&gt;
There are lots of benefits to writing tests that pass.&lt;br /&gt;
&lt;br /&gt;
Benefits include :&lt;br /&gt;
&lt;br /&gt;
* Learning! New developers can learn a ton from writing several passing tests in the area they are interested in. This is one of the quickest ways to learn about a pre-existing and mature code base. You have zero worries about breaking things.&lt;br /&gt;
&lt;br /&gt;
* Latent bug uncovering. One will probably fail every ten tests you write, expecting them to pass. Tests may uncover unexpected behavior that a developer can improve.&lt;br /&gt;
&lt;br /&gt;
* Refactoring. If we had 10,000 passing tests (assuming universal test coverage), large-scale refactoring of the entire code base would be quick and reliable. It would enable refactoring on a scale currently unimaginable. I cannot emphasize enough how much of a benefit this would be.&lt;br /&gt;
&lt;br /&gt;
* Developer turnover. Again, if we had 10,000 passing tests (assuming universal test coverage), it would encourage new developers, giving them confidence that their changes will not cause problems. It is a safety net. It also would provide existing developers peace of mind when a new developer works in one of the dark parts of FlightGear that no current developer understands (there are plenty of those).&lt;br /&gt;
&lt;br /&gt;
* Test suite infrastructure. The more passing tests written, the better the test suite infrastructure will become. We can already do a lot, but adding more passing tests will help other test writers.&lt;br /&gt;
&lt;br /&gt;
* Memory checking. Running a single test through Valgrind is fantastic. Running FlightGear through Valgrind is close to impossible. One can write tests that pass but are useful under Valgrind to catch memory leaks!&lt;br /&gt;
&lt;br /&gt;
* Code quality and standards. If a test compiles on all OSes without warning, it passes, and Valgrind gives you an ok, it is good enough. You don't need to be a C++ expert to dive into this shallow end of the pool.&lt;br /&gt;
&lt;br /&gt;
=== Bootstrapping completely new tests ===&lt;br /&gt;
To start diving straight into the test suite code, firstly copy what has been done in this commit:  {{repo link&lt;br /&gt;
| site   = sf&lt;br /&gt;
| user = edauvergne&lt;br /&gt;
| repo   = flightgear&lt;br /&gt;
| commit = 8474df&lt;br /&gt;
| view   = commit&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Just modify all names for a JSBSim test (or any other test fixture you&lt;br /&gt;
want to code). You should then be able to compile and check that your&lt;br /&gt;
new test dummy () test passes as expected. You can then slowly build up&lt;br /&gt;
from this basic infrastructure as you learn the fgfs internals, c++,&lt;br /&gt;
and git skills required for implementing your test on your fork's new&lt;br /&gt;
development branch :)&lt;br /&gt;
&lt;br /&gt;
=== Structure of a CPPUnit test ===&lt;br /&gt;
&lt;br /&gt;
==== Definitions ====&lt;br /&gt;
&lt;br /&gt;
=====Test Case=====&lt;br /&gt;
A single assertion about one or two variable values that is testable.&lt;br /&gt;
=====Test Fixture=====&lt;br /&gt;
In CppUnit, a group of tests is called a TestFixture. A TestFixture provides a common environment for multiple test cases.&lt;br /&gt;
=====App Component Category=====&lt;br /&gt;
Major parts of the application, usually corresponding to folders in flightgear/src or simgear/simgear&lt;br /&gt;
=====Test Category===== &lt;br /&gt;
The type of testing: unit, system and simgear (library) tests&lt;br /&gt;
=====Test Suite=====&lt;br /&gt;
All the tests and everything needed to support them &lt;br /&gt;
&lt;br /&gt;
==== Top Level Test Folder ====&lt;br /&gt;
&lt;br /&gt;
Take a look at the '''flightgear/test_suite''' folder in a file browser preferably one that allows you to see the folders on multiple levels such as a code editor like VsCode. Start in the top level of flightgear's repo sources look for a directory named '''test_suite'''.  Note that test_suite is not part of '''flightgear/src'''.&lt;br /&gt;
&lt;br /&gt;
====flightgear/test_suite folder====&lt;br /&gt;
&lt;br /&gt;
'''flightgear/test_suite''' contains two kinds of testing resources. &lt;br /&gt;
&lt;br /&gt;
* Programs and data used in tests&lt;br /&gt;
* Groups of CPPUnit tests&lt;br /&gt;
&lt;br /&gt;
=====Programs and data used in test modules=====&lt;br /&gt;
&lt;br /&gt;
* individual files directly under test_suite&lt;br /&gt;
* test_data folder&lt;br /&gt;
* FGTestApi folder&lt;br /&gt;
* Groups of CPPUnit tests&lt;br /&gt;
&lt;br /&gt;
=====Test Categories=====&lt;br /&gt;
&lt;br /&gt;
* fgdata_tests - placeholder&lt;br /&gt;
* gui_tests - placeholder&lt;br /&gt;
* simgear_tests&lt;br /&gt;
* system_tests&lt;br /&gt;
* unit_tests&lt;br /&gt;
&lt;br /&gt;
Each of the last three test_suite/*_tests folders contain sub-folders covering some part of Flightgear's code.  They may roughly correspond to the folders under flightgear/src, but that is not a requirement.    Some areas may be covered in more than one *_tests folder.  FDM for example in unit_tests and system_tests.  &lt;br /&gt;
&lt;br /&gt;
==== Folder Levels ====&lt;br /&gt;
&lt;br /&gt;
Note at this point that the maximum Folder depth is 3:&lt;br /&gt;
&lt;br /&gt;
# flightgear/test_suite Folder.&lt;br /&gt;
# Test-category folders ex: unit_tests, system_tests, simgear_tests&lt;br /&gt;
# App Component folders ex: FDM, Network, canvas.  These roughly correspond to specific flightgear/src folders, &lt;br /&gt;
&lt;br /&gt;
Expand the '''unit_tests''' test category folder&lt;br /&gt;
Expand the '''Network''' app component folder&lt;br /&gt;
&lt;br /&gt;
CPPUNIT test fixtures are implemented in test_*.cxx and test_*.hhx files int the Component category folders.&lt;br /&gt;
&lt;br /&gt;
==== CMakeLists.txt, testSuite.cxx and TestSuite.cxx files ====&lt;br /&gt;
&lt;br /&gt;
CMakeLists.txt files exist at every level&lt;br /&gt;
TestSuite.cxx files are in each application component folders (bottom level)&lt;br /&gt;
testSuite.cxx is only at the top level&lt;br /&gt;
&lt;br /&gt;
# '''test_suite/CMakeLists.txt''' &amp;amp; test_suite/testSuite.cxx&lt;br /&gt;
# '''test_suite/[test-category]/CMakeLists.txt''' &lt;br /&gt;
# '''test_suite/[test-category]/[app-component]/CMakeLists.txt'''  and '''Test_suite.cxx'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
More to follow {{WIP}}&lt;br /&gt;
&lt;br /&gt;
===Headless testing===&lt;br /&gt;
{{Main article|FlightGear Headless}}&lt;br /&gt;
&lt;br /&gt;
For an FDM+systems test, we should run FG without a renderer (which is what the test_suite does) to benchmark the pure C++ performance of whatever system we care about (FDM or whatever). But a few hours playing with 'perf' on Linux or Instruments on macOS will show you that OSG + the GL drivers use 80% of our CPU time, and hence Amdhal's law will always get you.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36977666/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Graphics testing===&lt;br /&gt;
{{See also|FlightGear Benchmark}}&lt;br /&gt;
&lt;br /&gt;
Create test-case scenes where you can quickly measure differences and compare via screenshots. The brain/eye/memory are terrible at this stuff, setup something you can load from the command line via a script to test old/new versions, if possible. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36959002/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, a test would use several rc files (.[[fgfsrc]] variants, with different renderers and threading modes, including static values for:&lt;br /&gt;
*c172p at some parking in a detailed airport&lt;br /&gt;
*camera set with a specific direction and field of view&lt;br /&gt;
*AW with specific METARs around (if not possible, BW with specific METAR)&lt;br /&gt;
*fixed rendering settings ( &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36975122/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We can load a [[Instant Replay|replay tape]] on startup. Since the FDM and User interface are unavailable, replays are suitable for testing rendering and performance.&lt;br /&gt;
&lt;br /&gt;
But essentially, small amounts of shell script + Nasal hacking, can implement any of these methods,  and any of them would be welcome additions. The unit-test framework is excellent for lower-level tests run by developers (i.e., 'Does the API call produce the right results in the system?'), but a smoke test that regular users can run would be ideal. &lt;br /&gt;
&lt;br /&gt;
A rendering performance would likely do the following:&lt;br /&gt;
&lt;br /&gt;
*Select some particular rendering settings (clouds, draw distance, etc)&lt;br /&gt;
*Run a saved fgtape recording&lt;br /&gt;
* Record the mean/min/max FPS during this and save it in some text file/copy to the clipboard&lt;br /&gt;
&lt;br /&gt;
So yes, if anyone wants to work on the above, the code is all there. Please jump in and start hacking. I don't think it needs any more from the core code, but as always, please ask if it does.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36975213/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, when describing a /rendering/ test (to establish FPS), the advantage of a replay tape is that the actual position (and, therefore, the rendered scene) will be 100% consistent across different computers.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that the CPU use of the FDM+systems is typically &amp;lt; 10% of our total CPU use, even when running OSG single-threaded, so for a rendering performance test, whether the FD is run or not is probably noise compared to other things that do run (Nasal, Canvas for example)&lt;br /&gt;
&lt;br /&gt;
Also, the Multi-monitor setup is an area that could use additional unit testing. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36904782/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Fgdata==&lt;br /&gt;
===Nasal scripting (comments)===&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
The now builtin CppUnit framework can solve all the issues&lt;br /&gt;
identified in the old [[Nasal Unit Testing Framework]] wiki article and the discussions it points to&lt;br /&gt;
and provide the full framework required.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36990615/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have some very simple tests running now for the route manager, which relies on Nasal. We're skipping a few of the bigger Nasal modules (local weather, jetways) and have a few lingering issues in some other modules, but the basic concept is working. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
An exciting further step, which you might wish to discuss with Edward, is writing test checks *in* Nasal since this could be quite a fast way to test some areas of the code. There are several ways that could work, and I don't know if Edward has always planned something around this, so I won't preempt that conversation.&lt;br /&gt;
&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36764781/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
we have route-manager tests which validate route_manager.nas is working correctly, and we have Canavs tests ({{fg src file|path=test_suite/simgear_tests/canvas|}}) which poke the Nasal API. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36991200/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We need more FGData testing via the test suite.&lt;br /&gt;
&lt;br /&gt;
James has suggested adding CppUnit assertions to Nasal so others can write tests in pure Nasal. James would make these changes in C++.  &lt;br /&gt;
In addition, some C++ code in a test would scan a directory for files matching a pattern, e.g., test_XYZ.nas, and run each of those automatically.&lt;br /&gt;
&lt;br /&gt;
The idea for testing Nasal would be that you write a small CppUnit&lt;br /&gt;
interface in C++ in $FG_SRC/test_suite/*_tests/ (the FGData Nasal&lt;br /&gt;
testing would be in a fgdata_tests/ directory). This would register&lt;br /&gt;
each test which points to the script in&lt;br /&gt;
$FG_SRC/test_suite/shared_data/nasal/, and the setUp() and tearDown()&lt;br /&gt;
functions would use helper functions in the fgtest namespace to start&lt;br /&gt;
and stop Nasal. The Nasal scripts could then call the CppUnit&lt;br /&gt;
assertion macros wrapped up as Nasal functions for communicating&lt;br /&gt;
failures and errors to the test suite. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36991150/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Scanning for scripts is a great idea. Then, developers (core and content) could write tests using pure Nasal.&lt;br /&gt;
&lt;br /&gt;
However, all scripts found and executed will be seen as a single test within the test suite. So maybe we should have a $FG_SRC/test_suite/nasal_staging/ directory for the initial development of such auto-scanned scripts. But then we have someone shift them into $FG_SRC/test_suite/system_tests/, $FG_SRC/test_suite/unit_tests/, or $FG_SRC/test_suite/fgdata_tests/ later on?  That would give better diagnostics and would avoid long-term clutter.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36991198/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*First, we should probably hard code tests into the C++ framework. For this, the CppUnit assertion macros will have to be wrapped up as Nasal functions.&lt;br /&gt;
*Implement the scanning code as we need some CMake magic (probably using file(COPY, ...)).&lt;br /&gt;
*Finally, we must determine if and how to improve the Nnasaldebugging output.&lt;br /&gt;
&lt;br /&gt;
the code could go into a subdirectory in $FG_SRC/test_suite/fgdata_tests/, and the Nasal script in $FG_SRC/test_suite/shared_data/nasal/.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Core development]]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Software_testing&amp;diff=140267</id>
		<title>Software testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Software_testing&amp;diff=140267"/>
		<updated>2024-08-20T18:30:49Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: /* Structure of a CPPUnit test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Note|There’s already the test_suite in {{fg src file|path=test_suite}} using [[Cppunit effort|CppUnit]], thanks to some hard work by [[User:Bugman|Edward]]. We need more tests written for it; submissions are welcome. (Pick an area of interest)&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36972720/&amp;lt;/ref&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{See also|Cppunit effort}}&lt;br /&gt;
&lt;br /&gt;
FlightGear developers use various testing tools. This includes automated testing via unit tests in [[SimGear]] and a full test suite with multiple test categories in the [[FlightGear Git|flightgear repository]], as well as manual in-sim testing. Writing tests is one of the best ways to jump into FlightGear development.&lt;br /&gt;
&lt;br /&gt;
One improving area is unit testing: certain areas and features (e.g., carrier start) now 'can't break.' As we add testing in additional areas (e.g., Multi-player, AI, protocols, and replay are all possible), we increase the baseline quality and have a clearer idea when we make incompatible changes. (The idea is that we capture the 'supported API' in the tests: when an aircraft deviates from that, we can decide to add another test case, fix the aircraft, etc). Of course, there are some pretty significant areas where Automated Testing Is Hard (TM).&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/37078825/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== SimGear ==&lt;br /&gt;
&lt;br /&gt;
Unit testing for the [[SimGear]] sources uses the CMake CTest unit testing infrastructure. Several tests use the BOOST unit testing infrastructure tied to the build system using CTest; however, the FlightGear developers are shifting towards eliminating BOOST, so CPPUnit and CTest tests are preferred.&lt;br /&gt;
&lt;br /&gt;
=== Building and running the SimGear tests ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ make&lt;br /&gt;
$ ctest&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== FlightGear ==&lt;br /&gt;
&lt;br /&gt;
Testing of the [[FlightGear Git|flightgear sources]] is via a comprehensive test suite implemented using [https://www.freedesktop.org/wiki/Software/cppunit/ CppUnit], a port of the famous JUnit framework.&lt;br /&gt;
&lt;br /&gt;
=== Building the test suite ===&lt;br /&gt;
&lt;br /&gt;
You must build FlightGear from the source using cmake to run the tests. See [[Building FlightGear]] for details.&lt;br /&gt;
&lt;br /&gt;
Once you have your cmake build environment, do the following:&lt;br /&gt;
# Change to your FlightGear build* directory&lt;br /&gt;
# Enable building the tests by setting a cmake variable:  &amp;lt;code&amp;gt;cmake -DBUILD_TESTING=ON .&amp;lt;/code&amp;gt;&lt;br /&gt;
# Ensure the &amp;lt;code&amp;gt;[[$FG ROOT|$FG_ROOT]]&amp;lt;/code&amp;gt; environment variable points to fgdata e.g. &amp;lt;code&amp;gt;$FG_INSTALL_DIR/share/fgdata&amp;lt;/code&amp;gt;&lt;br /&gt;
# Build the test suite:  &amp;lt;code&amp;gt;make test_suite&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Building the test suite will also run a test because you will typically want to write a test and then immediately compile and run it.&lt;br /&gt;
&lt;br /&gt;
 * ls in this directory should include CMakeCache.txt, cmake_install, and others. You do not want to run cmake in the flightgear sources directory, which includes files such as AUTHORS, COPYING, INSTALL, etc.&lt;br /&gt;
&lt;br /&gt;
On a Windows MSVC-based build environment, after generating files with cmake, run the following code:&lt;br /&gt;
# cmake --build . --config RelWithDebInfo --target test_suite/test_suite&lt;br /&gt;
&lt;br /&gt;
=== Running the test suite ===&lt;br /&gt;
&lt;br /&gt;
To run the test suite, simply run &amp;lt;code&amp;gt;./test_suite/fgfs_test_suite&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Executing fgfs_test_suite will run the entire test suite and print a Synopsis of results, as shown below.&lt;br /&gt;
&lt;br /&gt;
 Synopsis&lt;br /&gt;
 ========&lt;br /&gt;
 &lt;br /&gt;
 System/functional tests ....................................... [ OK ]&lt;br /&gt;
 Unit tests .................................................... [ OK ]&lt;br /&gt;
 Simgear unit tests ............................................ [ OK ]&lt;br /&gt;
 FGData tests .................................................. [ OK ]&lt;br /&gt;
 Synopsis ...................................................... [ OK ]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also run individual test cases. Run &amp;lt;code&amp;gt;./test_suite/fgfs_test_suite -h&amp;lt;/code&amp;gt; to see the various options&lt;br /&gt;
&lt;br /&gt;
For example, fgfs_test_suite --log-level=alert -d -u GPSTests will run the GPS unit tests while displaying the output.&lt;br /&gt;
&lt;br /&gt;
=== Why write unit tests? ===&lt;br /&gt;
&lt;br /&gt;
A well-tested piece of software will have a much lower bug count/load. An extensive test suite with &amp;quot;'unit tests,'&amp;quot; system/functional tests, GUI tests, installer tests, and other categories of tests can significantly help in this regard.&lt;br /&gt;
&lt;br /&gt;
The benefits of not just chasing clear &amp;quot;wins&amp;quot; are great: An excellent learning experience for new developers; the ability to catch latent, unreported bugs; making it easier to refactor current code by creating a safety net; making it easier for current developers to accept new contributions (when accompanied with passing tests); helping other test writers by contributing to the standard test suite infrastructure; and being able to check for memory leaks or other issues via Valgrind easily.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36977686/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you are a new developer, jump in and write any test! It does not need to catch a bug. Do whatever you wish! Just dive into this shallow end, and you'll see that the water is not cold.&lt;br /&gt;
&lt;br /&gt;
You are writing a test as a safety net. You write the test to pass, make your changes, and then make sure that the test still passes. Then, you push both the test and core changes.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36977465/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It'd be better to work in a specific area of interest to you and submit merge requests. When reviewed, that would usually trigger some C++ feedback, but we aren't looking for perfection here. The feedback you receive during the open and public review process increases our overall pool of knowledge of what best practice looks like, even if a given commit is less than perfect.&lt;br /&gt;
&lt;br /&gt;
Having 10 or 20 people actively contributing correct and reasonable code is more important than three people contributing perfect, micro-optimised C++. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36951247/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Benefits of unit testing ===&lt;br /&gt;
There are lots of benefits to writing tests that pass.&lt;br /&gt;
&lt;br /&gt;
Benefits include :&lt;br /&gt;
&lt;br /&gt;
* Learning! New developers can learn a ton from writing several passing tests in the area they are interested in. This is one of the quickest ways to learn about a pre-existing and mature code base. You have zero worries about breaking things.&lt;br /&gt;
&lt;br /&gt;
* Latent bug uncovering. One will probably fail every ten tests you write, expecting them to pass. Tests may uncover unexpected behavior that a developer can improve.&lt;br /&gt;
&lt;br /&gt;
* Refactoring. If we had 10,000 passing tests (assuming universal test coverage), large-scale refactoring of the entire code base would be quick and reliable. It would enable refactoring on a scale currently unimaginable. I cannot emphasize enough how much of a benefit this would be.&lt;br /&gt;
&lt;br /&gt;
* Developer turnover. Again, if we had 10,000 passing tests (assuming universal test coverage), it would encourage new developers, giving them confidence that their changes will not cause problems. It is a safety net. It also would provide existing developers peace of mind when a new developer works in one of the dark parts of FlightGear that no current developer understands (there are plenty of those).&lt;br /&gt;
&lt;br /&gt;
* Test suite infrastructure. The more passing tests written, the better the test suite infrastructure will become. We can already do a lot, but adding more passing tests will help other test writers.&lt;br /&gt;
&lt;br /&gt;
* Memory checking. Running a single test through Valgrind is fantastic. Running FlightGear through Valgrind is close to impossible. One can write tests that pass but are useful under Valgrind to catch memory leaks!&lt;br /&gt;
&lt;br /&gt;
* Code quality and standards. If a test compiles on all OSes without warning, it passes, and Valgrind gives you an ok, it is good enough. You don't need to be a C++ expert to dive into this shallow end of the pool.&lt;br /&gt;
&lt;br /&gt;
=== Bootstrapping completely new tests ===&lt;br /&gt;
To start diving straight into the test suite code, firstly copy what has been done in this commit:  {{repo link&lt;br /&gt;
| site   = sf&lt;br /&gt;
| user = edauvergne&lt;br /&gt;
| repo   = flightgear&lt;br /&gt;
| commit = 8474df&lt;br /&gt;
| view   = commit&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Just modify all names for a JSBSim test (or any other test fixture you&lt;br /&gt;
want to code). You should then be able to compile and check that your&lt;br /&gt;
new test dummy () test passes as expected. You can then slowly build up&lt;br /&gt;
from this basic infrastructure as you learn the fgfs internals, c++,&lt;br /&gt;
and git skills required for implementing your test on your fork's new&lt;br /&gt;
development branch :)&lt;br /&gt;
&lt;br /&gt;
=== Structure of a CPPUnit test ===&lt;br /&gt;
&lt;br /&gt;
==== Definitions ====&lt;br /&gt;
&lt;br /&gt;
=====Test Case===== - A single assertion about one or two variable values that is testable.&lt;br /&gt;
=====Test Fixture===== - In CppUnit, a group of tests is called a TestFixture. A TestFixture provides a common environment for multiple test cases.&lt;br /&gt;
=====App Component Category=====- Major parts of the application, usually corresponding to folders in flightgear/src or simgear/simgear&lt;br /&gt;
=====Test Category===== - The type of testing: unit, system and simgear (library) tests&lt;br /&gt;
=====Test Suite=====-  All the tests.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Take a look at the '''flightgear/test_suite''' folder in a file browser preferably one that allows you to see the folders on multiple levels such as a code editor like VsCode. Start in the top level of flightgear's repo sources look for a directory named '''test_suite'''.  Note that test_suite is not part of '''flightgear/src'''.&lt;br /&gt;
&lt;br /&gt;
====flightgear/test_suite folder====&lt;br /&gt;
&lt;br /&gt;
'''flightgear/test_suite''' contains two kinds of testing resources. &lt;br /&gt;
&lt;br /&gt;
* Programs and data used in tests&lt;br /&gt;
* Groups of CPPUnit tests&lt;br /&gt;
&lt;br /&gt;
=====Programs and data used in test modules=====&lt;br /&gt;
&lt;br /&gt;
* individual files directly under test_suite&lt;br /&gt;
* test_data folder&lt;br /&gt;
* FGTestApi folder&lt;br /&gt;
* Groups of CPPUnit tests&lt;br /&gt;
&lt;br /&gt;
=====Test Categories=====&lt;br /&gt;
&lt;br /&gt;
* fgdata_tests - placeholder&lt;br /&gt;
* gui_tests - placeholder&lt;br /&gt;
* simgear_tests&lt;br /&gt;
* system_tests&lt;br /&gt;
* unit_tests&lt;br /&gt;
&lt;br /&gt;
Each of the last three test_suite/*_tests folders contain sub-folders covering some part of Flightgear's code.  They may roughly correspond to the folders under flightgear/src, but that is not a requirement.    Some areas may be covered in more than one *_tests folder.  FDM for example in unit_tests and system_tests.  &lt;br /&gt;
&lt;br /&gt;
==== Folder Levels ====&lt;br /&gt;
&lt;br /&gt;
Note at this point that the maximum Folder depth is 3:&lt;br /&gt;
&lt;br /&gt;
# flightgear/test_suite Folder.&lt;br /&gt;
# Test-category folders ex: unit_tests, system_tests, simgear_tests&lt;br /&gt;
# App Component folders ex: FDM, Network, canvas.  These roughly correspond to specific flightgear/src folders, &lt;br /&gt;
&lt;br /&gt;
Expand the '''unit_tests''' test category folder&lt;br /&gt;
Expand the '''Network''' app component folder&lt;br /&gt;
&lt;br /&gt;
CPPUNIT test fixtures are implemented in test_*.cxx and test_*.hhx files int the Component category folders.&lt;br /&gt;
&lt;br /&gt;
==== CMakeLists.txt, testSuite.cxx and TestSuite.cxx files ====&lt;br /&gt;
&lt;br /&gt;
CMakeLists.txt files exist at every level&lt;br /&gt;
TestSuite.cxx files are in each application component folders (bottom level)&lt;br /&gt;
testSuite.cxx is only at the top level&lt;br /&gt;
&lt;br /&gt;
# '''test_suite/CMakeLists.txt''' &amp;amp; test_suite/testSuite.cxx&lt;br /&gt;
# '''test_suite/[test-category]/CMakeLists.txt''' &lt;br /&gt;
# '''test_suite/[test-category]/[app-component]/CMakeLists.txt'''  and '''Test_suite.cxx'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
More to follow {{WIP}}&lt;br /&gt;
&lt;br /&gt;
===Headless testing===&lt;br /&gt;
{{Main article|FlightGear Headless}}&lt;br /&gt;
&lt;br /&gt;
For an FDM+systems test, we should run FG without a renderer (which is what the test_suite does) to benchmark the pure C++ performance of whatever system we care about (FDM or whatever). But a few hours playing with 'perf' on Linux or Instruments on macOS will show you that OSG + the GL drivers use 80% of our CPU time, and hence Amdhal's law will always get you.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36977666/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Graphics testing===&lt;br /&gt;
{{See also|FlightGear Benchmark}}&lt;br /&gt;
&lt;br /&gt;
Create test-case scenes where you can quickly measure differences and compare via screenshots. The brain/eye/memory are terrible at this stuff, setup something you can load from the command line via a script to test old/new versions, if possible. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36959002/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, a test would use several rc files (.[[fgfsrc]] variants, with different renderers and threading modes, including static values for:&lt;br /&gt;
*c172p at some parking in a detailed airport&lt;br /&gt;
*camera set with a specific direction and field of view&lt;br /&gt;
*AW with specific METARs around (if not possible, BW with specific METAR)&lt;br /&gt;
*fixed rendering settings ( &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36975122/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We can load a [[Instant Replay|replay tape]] on startup. Since the FDM and User interface are unavailable, replays are suitable for testing rendering and performance.&lt;br /&gt;
&lt;br /&gt;
But essentially, small amounts of shell script + Nasal hacking, can implement any of these methods,  and any of them would be welcome additions. The unit-test framework is excellent for lower-level tests run by developers (i.e., 'Does the API call produce the right results in the system?'), but a smoke test that regular users can run would be ideal. &lt;br /&gt;
&lt;br /&gt;
A rendering performance would likely do the following:&lt;br /&gt;
&lt;br /&gt;
*Select some particular rendering settings (clouds, draw distance, etc)&lt;br /&gt;
*Run a saved fgtape recording&lt;br /&gt;
* Record the mean/min/max FPS during this and save it in some text file/copy to the clipboard&lt;br /&gt;
&lt;br /&gt;
So yes, if anyone wants to work on the above, the code is all there. Please jump in and start hacking. I don't think it needs any more from the core code, but as always, please ask if it does.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36975213/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, when describing a /rendering/ test (to establish FPS), the advantage of a replay tape is that the actual position (and, therefore, the rendered scene) will be 100% consistent across different computers.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that the CPU use of the FDM+systems is typically &amp;lt; 10% of our total CPU use, even when running OSG single-threaded, so for a rendering performance test, whether the FD is run or not is probably noise compared to other things that do run (Nasal, Canvas for example)&lt;br /&gt;
&lt;br /&gt;
Also, the Multi-monitor setup is an area that could use additional unit testing. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36904782/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Fgdata==&lt;br /&gt;
===Nasal scripting (comments)===&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
The now builtin CppUnit framework can solve all the issues&lt;br /&gt;
identified in the old [[Nasal Unit Testing Framework]] wiki article and the discussions it points to&lt;br /&gt;
and provide the full framework required.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36990615/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have some very simple tests running now for the route manager, which relies on Nasal. We're skipping a few of the bigger Nasal modules (local weather, jetways) and have a few lingering issues in some other modules, but the basic concept is working. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
An exciting further step, which you might wish to discuss with Edward, is writing test checks *in* Nasal since this could be quite a fast way to test some areas of the code. There are several ways that could work, and I don't know if Edward has always planned something around this, so I won't preempt that conversation.&lt;br /&gt;
&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36764781/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
we have route-manager tests which validate route_manager.nas is working correctly, and we have Canavs tests ({{fg src file|path=test_suite/simgear_tests/canvas|}}) which poke the Nasal API. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36991200/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We need more FGData testing via the test suite.&lt;br /&gt;
&lt;br /&gt;
James has suggested adding CppUnit assertions to Nasal so others can write tests in pure Nasal. James would make these changes in C++.  &lt;br /&gt;
In addition, some C++ code in a test would scan a directory for files matching a pattern, e.g., test_XYZ.nas, and run each of those automatically.&lt;br /&gt;
&lt;br /&gt;
The idea for testing Nasal would be that you write a small CppUnit&lt;br /&gt;
interface in C++ in $FG_SRC/test_suite/*_tests/ (the FGData Nasal&lt;br /&gt;
testing would be in a fgdata_tests/ directory). This would register&lt;br /&gt;
each test which points to the script in&lt;br /&gt;
$FG_SRC/test_suite/shared_data/nasal/, and the setUp() and tearDown()&lt;br /&gt;
functions would use helper functions in the fgtest namespace to start&lt;br /&gt;
and stop Nasal. The Nasal scripts could then call the CppUnit&lt;br /&gt;
assertion macros wrapped up as Nasal functions for communicating&lt;br /&gt;
failures and errors to the test suite. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36991150/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Scanning for scripts is a great idea. Then, developers (core and content) could write tests using pure Nasal.&lt;br /&gt;
&lt;br /&gt;
However, all scripts found and executed will be seen as a single test within the test suite. So maybe we should have a $FG_SRC/test_suite/nasal_staging/ directory for the initial development of such auto-scanned scripts. But then we have someone shift them into $FG_SRC/test_suite/system_tests/, $FG_SRC/test_suite/unit_tests/, or $FG_SRC/test_suite/fgdata_tests/ later on?  That would give better diagnostics and would avoid long-term clutter.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36991198/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*First, we should probably hard code tests into the C++ framework. For this, the CppUnit assertion macros will have to be wrapped up as Nasal functions.&lt;br /&gt;
*Implement the scanning code as we need some CMake magic (probably using file(COPY, ...)).&lt;br /&gt;
*Finally, we must determine if and how to improve the Nnasaldebugging output.&lt;br /&gt;
&lt;br /&gt;
the code could go into a subdirectory in $FG_SRC/test_suite/fgdata_tests/, and the Nasal script in $FG_SRC/test_suite/shared_data/nasal/.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Core development]]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Software_testing&amp;diff=140260</id>
		<title>Software testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Software_testing&amp;diff=140260"/>
		<updated>2024-08-20T07:01:58Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: /* Structure of a CPPUnit test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Note|There’s already the test_suite in {{fg src file|path=test_suite}} using [[Cppunit effort|CppUnit]], thanks to some hard work by [[User:Bugman|Edward]]. We need more tests written for it; submissions are welcome. (Pick an area of interest)&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36972720/&amp;lt;/ref&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{See also|Cppunit effort}}&lt;br /&gt;
&lt;br /&gt;
FlightGear developers use various testing tools. This includes automated testing via unit tests in [[SimGear]] and a full test suite with multiple test categories in the [[FlightGear Git|flightgear repository]], as well as manual in-sim testing. Writing tests is one of the best ways to jump into FlightGear development.&lt;br /&gt;
&lt;br /&gt;
One improving area is unit testing: certain areas and features (e.g., carrier start) now 'can't break.' As we add testing in additional areas (e.g., Multi-player, AI, protocols, and replay are all possible), we increase the baseline quality and have a clearer idea when we make incompatible changes. (The idea is that we capture the 'supported API' in the tests: when an aircraft deviates from that, we can decide to add another test case, fix the aircraft, etc). Of course, there are some pretty significant areas where Automated Testing Is Hard (TM).&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/37078825/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== SimGear ==&lt;br /&gt;
&lt;br /&gt;
Unit testing for the [[SimGear]] sources uses the CMake CTest unit testing infrastructure. Several tests use the BOOST unit testing infrastructure tied to the build system using CTest; however, the FlightGear developers are shifting towards eliminating BOOST, so CPPUnit and CTest tests are preferred.&lt;br /&gt;
&lt;br /&gt;
=== Building and running the SimGear tests ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ make&lt;br /&gt;
$ ctest&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== FlightGear ==&lt;br /&gt;
&lt;br /&gt;
Testing of the [[FlightGear Git|flightgear sources]] is via a comprehensive test suite implemented using [https://www.freedesktop.org/wiki/Software/cppunit/ CppUnit], a port of the famous JUnit framework.&lt;br /&gt;
&lt;br /&gt;
=== Building the test suite ===&lt;br /&gt;
&lt;br /&gt;
You must build FlightGear from the source using cmake to run the tests. See [[Building FlightGear]] for details.&lt;br /&gt;
&lt;br /&gt;
Once you have your cmake build environment, do the following:&lt;br /&gt;
# Change to your FlightGear build* directory&lt;br /&gt;
# Enable building the tests by setting a cmake variable:  &amp;lt;code&amp;gt;cmake -DBUILD_TESTING=ON .&amp;lt;/code&amp;gt;&lt;br /&gt;
# Ensure the &amp;lt;code&amp;gt;[[$FG ROOT|$FG_ROOT]]&amp;lt;/code&amp;gt; environment variable points to fgdata e.g. &amp;lt;code&amp;gt;$FG_INSTALL_DIR/share/fgdata&amp;lt;/code&amp;gt;&lt;br /&gt;
# Build the test suite:  &amp;lt;code&amp;gt;make test_suite&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Building the test suite will also run a test because you will typically want to write a test and then immediately compile and run it.&lt;br /&gt;
&lt;br /&gt;
 * ls in this directory should include CMakeCache.txt, cmake_install, and others. You do not want to run cmake in the flightgear sources directory, which includes files such as AUTHORS, COPYING, INSTALL, etc.&lt;br /&gt;
&lt;br /&gt;
On a Windows MSVC-based build environment, after generating files with cmake, run the following code:&lt;br /&gt;
# cmake --build . --config RelWithDebInfo --target test_suite/test_suite&lt;br /&gt;
&lt;br /&gt;
=== Running the test suite ===&lt;br /&gt;
&lt;br /&gt;
To run the test suite, simply run &amp;lt;code&amp;gt;./test_suite/fgfs_test_suite&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Executing fgfs_test_suite will run the entire test suite and print a Synopsis of results, as shown below.&lt;br /&gt;
&lt;br /&gt;
 Synopsis&lt;br /&gt;
 ========&lt;br /&gt;
 &lt;br /&gt;
 System/functional tests ....................................... [ OK ]&lt;br /&gt;
 Unit tests .................................................... [ OK ]&lt;br /&gt;
 Simgear unit tests ............................................ [ OK ]&lt;br /&gt;
 FGData tests .................................................. [ OK ]&lt;br /&gt;
 Synopsis ...................................................... [ OK ]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also run individual test cases. Run &amp;lt;code&amp;gt;./test_suite/fgfs_test_suite -h&amp;lt;/code&amp;gt; to see the various options&lt;br /&gt;
&lt;br /&gt;
For example, fgfs_test_suite --log-level=alert -d -u GPSTests will run the GPS unit tests while displaying the output.&lt;br /&gt;
&lt;br /&gt;
=== Why write unit tests? ===&lt;br /&gt;
&lt;br /&gt;
A well-tested piece of software will have a much lower bug count/load. An extensive test suite with &amp;quot;'unit tests,'&amp;quot; system/functional tests, GUI tests, installer tests, and other categories of tests can significantly help in this regard.&lt;br /&gt;
&lt;br /&gt;
The benefits of not just chasing clear &amp;quot;wins&amp;quot; are great: An excellent learning experience for new developers; the ability to catch latent, unreported bugs; making it easier to refactor current code by creating a safety net; making it easier for current developers to accept new contributions (when accompanied with passing tests); helping other test writers by contributing to the standard test suite infrastructure; and being able to check for memory leaks or other issues via Valgrind easily.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36977686/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you are a new developer, jump in and write any test! It does not need to catch a bug. Do whatever you wish! Just dive into this shallow end, and you'll see that the water is not cold.&lt;br /&gt;
&lt;br /&gt;
You are writing a test as a safety net. You write the test to pass, make your changes, and then make sure that the test still passes. Then, you push both the test and core changes.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36977465/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It'd be better to work in a specific area of interest to you and submit merge requests. When reviewed, that would usually trigger some C++ feedback, but we aren't looking for perfection here. The feedback you receive during the open and public review process increases our overall pool of knowledge of what best practice looks like, even if a given commit is less than perfect.&lt;br /&gt;
&lt;br /&gt;
Having 10 or 20 people actively contributing correct and reasonable code is more important than three people contributing perfect, micro-optimised C++. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36951247/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Benefits of unit testing ===&lt;br /&gt;
There are lots of benefits to writing tests that pass.&lt;br /&gt;
&lt;br /&gt;
Benefits include :&lt;br /&gt;
&lt;br /&gt;
* Learning! New developers can learn a ton from writing several passing tests in the area they are interested in. This is one of the quickest ways to learn about a pre-existing and mature code base. You have zero worries about breaking things.&lt;br /&gt;
&lt;br /&gt;
* Latent bug uncovering. One will probably fail every ten tests you write, expecting them to pass. Tests may uncover unexpected behavior that a developer can improve.&lt;br /&gt;
&lt;br /&gt;
* Refactoring. If we had 10,000 passing tests (assuming universal test coverage), large-scale refactoring of the entire code base would be quick and reliable. It would enable refactoring on a scale currently unimaginable. I cannot emphasize enough how much of a benefit this would be.&lt;br /&gt;
&lt;br /&gt;
* Developer turnover. Again, if we had 10,000 passing tests (assuming universal test coverage), it would encourage new developers, giving them confidence that their changes will not cause problems. It is a safety net. It also would provide existing developers peace of mind when a new developer works in one of the dark parts of FlightGear that no current developer understands (there are plenty of those).&lt;br /&gt;
&lt;br /&gt;
* Test suite infrastructure. The more passing tests written, the better the test suite infrastructure will become. We can already do a lot, but adding more passing tests will help other test writers.&lt;br /&gt;
&lt;br /&gt;
* Memory checking. Running a single test through Valgrind is fantastic. Running FlightGear through Valgrind is close to impossible. One can write tests that pass but are useful under Valgrind to catch memory leaks!&lt;br /&gt;
&lt;br /&gt;
* Code quality and standards. If a test compiles on all OSes without warning, it passes, and Valgrind gives you an ok, it is good enough. You don't need to be a C++ expert to dive into this shallow end of the pool.&lt;br /&gt;
&lt;br /&gt;
=== Bootstrapping completely new tests ===&lt;br /&gt;
To start diving straight into the test suite code, firstly copy what has been done in this commit:  {{repo link&lt;br /&gt;
| site   = sf&lt;br /&gt;
| user = edauvergne&lt;br /&gt;
| repo   = flightgear&lt;br /&gt;
| commit = 8474df&lt;br /&gt;
| view   = commit&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Just modify all names for a JSBSim test (or any other test fixture you&lt;br /&gt;
want to code). You should then be able to compile and check that your&lt;br /&gt;
new test dummy () test passes as expected. You can then slowly build up&lt;br /&gt;
from this basic infrastructure as you learn the fgfs internals, c++,&lt;br /&gt;
and git skills required for implementing your test on your fork's new&lt;br /&gt;
development branch :)&lt;br /&gt;
&lt;br /&gt;
=== Structure of a CPPUnit test ===&lt;br /&gt;
&lt;br /&gt;
You're going to create a new test, by &lt;br /&gt;
* Naming a few things  &lt;br /&gt;
* Creating a class in .cxx and .hxx files. In the .hxx file the format is class TestObjective {};&lt;br /&gt;
* Include some CPPUNIT boilerplate code, common to all the tests&lt;br /&gt;
* Modifying CMakeLists.txt files to ensure your new class is built&lt;br /&gt;
* Adding a registration entry for your new class in the chosen directory's TestSuite.cxx file.  &lt;br /&gt;
&lt;br /&gt;
These are the test group directories&lt;br /&gt;
&lt;br /&gt;
* flightgear/test_suite/fgdata_tests&lt;br /&gt;
* flightgear/test_suite/gui_tests&lt;br /&gt;
* flightgear/test_suite/simgear_tests&lt;br /&gt;
* flightgear/test_suite/system_tests&lt;br /&gt;
* flightgear/test_suite/unit_tests&lt;br /&gt;
&lt;br /&gt;
Under each of these directories, are topic directory&lt;br /&gt;
For example, under flightgear/test_suite/unit_tests, you'll find directory names (topics) that roughly correspond to the directories under flightgear/src.&lt;br /&gt;
&lt;br /&gt;
 └── unit_tests&lt;br /&gt;
    ├── Add-ons&lt;br /&gt;
    ├── AI&lt;br /&gt;
    ├── Airports&lt;br /&gt;
    ├── Autopilot&lt;br /&gt;
    ├── CMakeLists.txt&lt;br /&gt;
    ├── FDM&lt;br /&gt;
    ├── general&lt;br /&gt;
    ├── Input&lt;br /&gt;
    ├── Instrumentation&lt;br /&gt;
    ├── Main&lt;br /&gt;
    ├── Navaids&lt;br /&gt;
    ├── Network&lt;br /&gt;
    └── Scripting&lt;br /&gt;
For this example we'll look at the steps taken to add the httpd tests under test_suite/Network.&lt;br /&gt;
&lt;br /&gt;
Steps:&lt;br /&gt;
* Choose where you are placing your tests. Choose a group and topic within the group. in our case it was test_suite/unit_tests/Network.  Unit tests is the group and Network is the Topic&lt;br /&gt;
* Name what you are testing in general, I was testing  httpd.cxx/hxx  format for the class name: HttpdTests&lt;br /&gt;
* Name the specific things covered. If only one, use the general wording,but in the format: testHttpd&lt;br /&gt;
* place the following boilerplate a file named test_httpd.hxx&lt;br /&gt;
&lt;br /&gt;
syntaxhighlight lang=&amp;quot;C++&amp;quot; line start=&amp;quot;&amp;quot; highlight=&amp;quot;&amp;quot; inline&amp;gt;&lt;br /&gt;
  /*&lt;br /&gt;
  * SPDX-FileCopyrightText: (C) '''2024 Patrick Callahan &amp;lt;pat.callahan5@gmail.com&amp;gt;'''&lt;br /&gt;
  * SPDX-License-Identifier: GPL-2.0-or-later&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  #pragma once&lt;br /&gt;
&lt;br /&gt;
  #include &amp;lt;cppunit/TestFixture.h&amp;gt;&lt;br /&gt;
  #include &amp;lt;cppunit/extensions/HelperMacros.h&amp;gt;&lt;br /&gt;
  #define private public&lt;br /&gt;
  class '''HttpdTest''' : public CppUnit::TestFixture&lt;br /&gt;
  {&lt;br /&gt;
      // Set up the test suite.&lt;br /&gt;
      CPPUNIT_TEST_SUITE('''HttpdTest''');&lt;br /&gt;
      CPPUNIT_TEST('''testHttpd''');&lt;br /&gt;
      CPPUNIT_TEST_SUITE_END();&lt;br /&gt;
&lt;br /&gt;
  public:&lt;br /&gt;
      // Set up function for each test.&lt;br /&gt;
      void setUp();&lt;br /&gt;
&lt;br /&gt;
      // Clean up after each test.&lt;br /&gt;
      void tearDown();&lt;br /&gt;
&lt;br /&gt;
      // Test&lt;br /&gt;
      void '''testHttpd'''();&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* modify the SPDX-FileCopyrightText, changing the date, name and e-mail to your own.&lt;br /&gt;
* modify the name of the class&lt;br /&gt;
* modify the name of the test function testHttpd&lt;br /&gt;
&lt;br /&gt;
* Add the following boilerplate to test_httpd.cxx&lt;br /&gt;
syntaxhighlight lang=&amp;quot;C++&amp;quot; line start=&amp;quot;&amp;quot; highlight=&amp;quot;&amp;quot; inline&amp;gt;&lt;br /&gt;
  /*&lt;br /&gt;
  * SPDX-FileCopyrightText: (C) '''2022 Lars Toenning &amp;lt;dev@ltoenning.de&amp;gt;'''&lt;br /&gt;
  * SPDX-License-Identifier: GPL-2.0-or-later&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  #include &amp;quot;test_httpd.hxx&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  #include &amp;quot;test_suite/FGTestApi/testGlobals.hxx&amp;quot;&lt;br /&gt;
  #define private public&lt;br /&gt;
  #include &amp;quot;Network/http/httpd.hxx&amp;quot;&lt;br /&gt;
  #include &amp;lt;Main/fg_props.hxx&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  void HttpdTest::setUp()&lt;br /&gt;
  {&lt;br /&gt;
      FGTestApi::setUp::initTestGlobals(&amp;quot;httpd&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      // Setup properties&lt;br /&gt;
      fgSetBool(&amp;quot;/sim/freeze/master&amp;quot;, true);&lt;br /&gt;
      fgSetDouble(&amp;quot;/position/latitude-deg&amp;quot;, 50.12);&lt;br /&gt;
      fgSetDouble(&amp;quot;/position/longitude-deg&amp;quot;, 6.3);&lt;br /&gt;
      fgSetDouble(&amp;quot;/position/altitude-ft&amp;quot;, 12000.0);&lt;br /&gt;
      fgSetDouble(&amp;quot;/position/altitude-agl-ft&amp;quot;, 1020.0);&lt;br /&gt;
      fgSetDouble(&amp;quot;/velocities/groundspeed-kt&amp;quot;, 242.0);&lt;br /&gt;
      fgSetDouble(&amp;quot;/orientation/pitch-deg&amp;quot;, 3.0);&lt;br /&gt;
      fgSetDouble(&amp;quot;/orientation/roll-deg&amp;quot;, 1.0);&lt;br /&gt;
      fgSetDouble(&amp;quot;/orientation/heading-deg&amp;quot;, 230.0);&lt;br /&gt;
      fgSetBool(&amp;quot;/gear/gear/wow&amp;quot;, false);&lt;br /&gt;
      fgSetDouble(&amp;quot;/instrumentation/comm/frequencies/selected-mhz&amp;quot;, 122.8);&lt;br /&gt;
      fgSetDouble(&amp;quot;/instrumentation/comm/frequencies/standby-mhz&amp;quot;, 135.65);&lt;br /&gt;
      fgSetDouble(&amp;quot;/instrumentation/comm[1]/frequencies/selected-mhz&amp;quot;, 121.5);&lt;br /&gt;
      fgSetDouble(&amp;quot;/instrumentation/comm[1]/frequencies/standby-mhz&amp;quot;, 118.3);&lt;br /&gt;
      fgSetInt(&amp;quot;/instrumentation/transponder/id-code&amp;quot;, 1234);&lt;br /&gt;
      fgSetInt(&amp;quot;/instrumentation/transponder/inputs/knob-mode&amp;quot;, 1);&lt;br /&gt;
      fgSetBool(&amp;quot;/instrumentation/transponder/ident&amp;quot;, true);&lt;br /&gt;
      fgSetBool(&amp;quot;/controls/lighting/beacon&amp;quot;, true);&lt;br /&gt;
      fgSetBool(&amp;quot;/controls/lighting/landing-lights&amp;quot;, false);&lt;br /&gt;
      fgSetBool(&amp;quot;/controls/lighting/nav-lights&amp;quot;, true);&lt;br /&gt;
      fgSetBool(&amp;quot;/controls/lighting/strobe&amp;quot;, true);&lt;br /&gt;
      fgSetBool(&amp;quot;/controls/lighting/taxi-light&amp;quot;, false);&lt;br /&gt;
      fgSetBool(&amp;quot;/instrumentation/altimeter/serviceable&amp;quot;, true);&lt;br /&gt;
      fgSetDouble(&amp;quot;/instrumentation/altimeter/pressure-alt-ft&amp;quot;, 24000.0);&lt;br /&gt;
      fgSetDouble(&amp;quot;/surface-positions/flap-pos-norm&amp;quot;, 0.0);&lt;br /&gt;
      fgSetDouble(&amp;quot;/gear/gear/position-norm&amp;quot;, 0.7);&lt;br /&gt;
      fgSetDouble(&amp;quot;/surface-positions/speedbrake-pos-norm&amp;quot;, 0.4);&lt;br /&gt;
      fgSetString(&amp;quot;/sim/aircraft&amp;quot;, &amp;quot;glider&amp;quot;);&lt;br /&gt;
      fgSetDouble(&amp;quot;/position/ground-elev-m&amp;quot;, 778.0);&lt;br /&gt;
      fgSetDouble(&amp;quot;/velocities/speed-east-fps&amp;quot;, 20.0);&lt;br /&gt;
      fgSetDouble(&amp;quot;/velocities/speed-down-fps&amp;quot;, -30.0);&lt;br /&gt;
      fgSetDouble(&amp;quot;/velocities/speed-north-fps&amp;quot;, -10.2);&lt;br /&gt;
      fgSetDouble(&amp;quot;/orientation/roll-rate-degps&amp;quot;, 1.0);&lt;br /&gt;
      fgSetDouble(&amp;quot;/orientation/pitch-rate-degps&amp;quot;, 0.0);&lt;br /&gt;
      fgSetDouble(&amp;quot;/orientation/yaw-rate-degps&amp;quot;, -2.0);&lt;br /&gt;
      fgSetDouble(&amp;quot;/instrumentation/comm/volume&amp;quot;, 42.0);&lt;br /&gt;
      fgSetDouble(&amp;quot;/instrumentation/comm[1]/volume&amp;quot;, 100.0);&lt;br /&gt;
      fgSetString(&amp;quot;/sim/http/options/document-root&amp;quot;, &amp;quot;Phi&amp;quot;);&lt;br /&gt;
      fgSetString(&amp;quot;/sim/http/options/enable-directory-listing&amp;quot;, &amp;quot;yes&amp;quot;);&lt;br /&gt;
      fgSetString(&amp;quot;/sim/http/options/extra-mime-types&amp;quot;, &amp;quot;.appcache=text/cache-manifest&amp;quot;);&lt;br /&gt;
      fgSetString(&amp;quot;/sim/http/options/idle-timeout-ms&amp;quot;, &amp;quot;30000&amp;quot;);&lt;br /&gt;
      fgSetString(&amp;quot;/sim/http/options/index-files&amp;quot;, &amp;quot;index.html&amp;quot;);&lt;br /&gt;
      fgSetString(&amp;quot;/sim/http/options/url-rewrites&amp;quot;, &amp;quot;/fonts=Fonts/&amp;quot;);&lt;br /&gt;
      fgSetString(&amp;quot;/sim/http/options/listening-port&amp;quot;, &amp;quot;5321&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  void HttpdTest::tearDown()&lt;br /&gt;
  {&lt;br /&gt;
      FGTestApi::tearDown::shutdownTestGlobals();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  void HttpdTest::testHttpd()&lt;br /&gt;
  {&lt;br /&gt;
      SGPropertyNode* config_node = fgGetNode(&amp;quot;/sim/http&amp;quot;, true);&lt;br /&gt;
      flightgear::http::MongooseHttpd * httpd = static_cast&amp;lt;flightgear::http::MongooseHttpd *&amp;gt;(flightgear::http::FGHttpd::createInstance(config_node));&lt;br /&gt;
        httpd-&amp;gt;init();&lt;br /&gt;
        CPPUNIT_ASSERT_EQUAL(static_cast&amp;lt;string&amp;gt;(&amp;quot;Phi&amp;quot;), httpd-&amp;gt;docRoot);&lt;br /&gt;
&lt;br /&gt;
        // ToDo: Implement a client that can go after properties, among other things.&lt;br /&gt;
&lt;br /&gt;
        // //    CPPUNIT_ASSERT(httpd.isPaused());&lt;br /&gt;
        // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getLatitude(), 50.12, 0.1);&lt;br /&gt;
        // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getLongitude(), 6.3, 0.1);&lt;br /&gt;
        // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getAltitudeMSL(), 12000.0, 0.1);&lt;br /&gt;
        // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getHeightAGL(), 1020.0, 0.1);&lt;br /&gt;
        // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getGroundSpeed(), 242.0, 0.1);&lt;br /&gt;
        // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getPitch(), 3.0, 0.1);&lt;br /&gt;
        // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getRoll(), 1.0, 0.1);&lt;br /&gt;
        // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getTrueHeading(), 230.0, 0.1);&lt;br /&gt;
        // CPPUNIT_ASSERT(!httpd.getAllWheelsOnGround());&lt;br /&gt;
        // CPPUNIT_ASSERT_EQUAL(httpd.getCom1Active(), 122800);&lt;br /&gt;
        // CPPUNIT_ASSERT_EQUAL(httpd.getCom1Standby(), 135650);&lt;br /&gt;
        // CPPUNIT_ASSERT_EQUAL(httpd.getCom2Active(), 121500);&lt;br /&gt;
        // CPPUNIT_ASSERT_EQUAL(httpd.getCom2Standby(), 118300);&lt;br /&gt;
&lt;br /&gt;
        // CPPUNIT_ASSERT_EQUAL(httpd.getTransponderCode(), 1234);&lt;br /&gt;
        // CPPUNIT_ASSERT_EQUAL(httpd.getTransponderMode(), 1);&lt;br /&gt;
        // CPPUNIT_ASSERT(httpd.getTransponderIdent());&lt;br /&gt;
        // CPPUNIT_ASSERT(httpd.getBeaconLightsOn());&lt;br /&gt;
        // CPPUNIT_ASSERT(!httpd.getLandingLightsOn());&lt;br /&gt;
        // CPPUNIT_ASSERT(httpd.getNavLightsOn());&lt;br /&gt;
        // CPPUNIT_ASSERT(httpd.getStrobeLightsOn());&lt;br /&gt;
        // CPPUNIT_ASSERT(!httpd.getTaxiLightsOn());&lt;br /&gt;
&lt;br /&gt;
        // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getFlapsDeployRatio(), 0.0, 0.1);&lt;br /&gt;
        // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getGearDeployRatio(), 0.7, 0.1);&lt;br /&gt;
        // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getSpeedBrakeRatio(), 0.4, 0.1);&lt;br /&gt;
&lt;br /&gt;
        // CPPUNIT_ASSERT_EQUAL(httpd.getAircraftName(), std::string(&amp;quot;glider&amp;quot;));&lt;br /&gt;
&lt;br /&gt;
        // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getGroundElevation(), 778.0, 0.1);&lt;br /&gt;
        // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getVelocityX(), 20.0 * SG_FEET_TO_METER, 0.1);&lt;br /&gt;
        // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getVelocityY(), -30.0 * SG_FEET_TO_METER * -1, 0.1);&lt;br /&gt;
        // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getVelocityZ(), -10.2 * SG_FEET_TO_METER, 0.1);&lt;br /&gt;
&lt;br /&gt;
        // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getRollRate(), 1.0 * SG_DEGREES_TO_RADIANS, 0.1);&lt;br /&gt;
        // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getPitchRate(), 0.0 * SG_DEGREES_TO_RADIANS, 0.1);&lt;br /&gt;
        // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getYawRate(), -2.0 * SG_DEGREES_TO_RADIANS, 0.1);&lt;br /&gt;
&lt;br /&gt;
        // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getCom1Volume(), 42.0, 0.1);&lt;br /&gt;
        // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getCom2Volume(), 100.0, 0.1);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getPressAlt(), 24000.0, 0.1);&lt;br /&gt;
        // fgSetBool(&amp;quot;/instrumentation/altimeter/serviceable&amp;quot;, false);&lt;br /&gt;
        // // Fallback if altimeter is not serviceable&lt;br /&gt;
        // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getPressAlt(), httpd.getAltitudeMSL(), 0.1);&lt;br /&gt;
&lt;br /&gt;
        // // Test setter&lt;br /&gt;
        // httpd.setCom1Active(128550);&lt;br /&gt;
        // CPPUNIT_ASSERT_EQUAL(httpd.getCom1Active(), 128550);&lt;br /&gt;
        // CPPUNIT_ASSERT_DOUBLES_EQUAL(fgGetDouble(&amp;quot;/instrumentation/comm/frequencies/selected-mhz&amp;quot;), 128.550, 0.1);&lt;br /&gt;
&lt;br /&gt;
        // httpd.setCom1Standby(128650);&lt;br /&gt;
        // CPPUNIT_ASSERT_EQUAL(httpd.getCom1Standby(), 128650);&lt;br /&gt;
        // CPPUNIT_ASSERT_DOUBLES_EQUAL(fgGetDouble(&amp;quot;/instrumentation/comm/frequencies/standby-mhz&amp;quot;), 128.650, 0.1);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        // httpd.setCom2Active(121900);&lt;br /&gt;
        // CPPUNIT_ASSERT_EQUAL(httpd.getCom2Active(), 121900);&lt;br /&gt;
        // CPPUNIT_ASSERT_DOUBLES_EQUAL(fgGetDouble(&amp;quot;/instrumentation/comm[1]/frequencies/selected-mhz&amp;quot;), 121.900, 0.1);&lt;br /&gt;
&lt;br /&gt;
        // httpd.setCom2Standby(121600);&lt;br /&gt;
        // CPPUNIT_ASSERT_EQUAL(httpd.getCom2Standby(), 121600);&lt;br /&gt;
        // CPPUNIT_ASSERT_DOUBLES_EQUAL(fgGetDouble(&amp;quot;/instrumentation/comm[1]/frequencies/standby-mhz&amp;quot;), 121.600, 0.1);&lt;br /&gt;
&lt;br /&gt;
        // httpd.setTransponderCode(2000);&lt;br /&gt;
        // CPPUNIT_ASSERT_EQUAL(httpd.getTransponderCode(), 2000);&lt;br /&gt;
        // CPPUNIT_ASSERT_EQUAL(fgGetInt(&amp;quot;/instrumentation/transponder/id-code&amp;quot;), 2000);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        // httpd.setTransponderMode(0);&lt;br /&gt;
        // CPPUNIT_ASSERT_EQUAL(httpd.getTransponderMode(), 0);&lt;br /&gt;
        // CPPUNIT_ASSERT_EQUAL(fgGetInt(&amp;quot;/instrumentation/transponder/inputs/knob-mode&amp;quot;), 0);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
More to follow {{WIP}}&lt;br /&gt;
&lt;br /&gt;
===Headless testing===&lt;br /&gt;
{{Main article|FlightGear Headless}}&lt;br /&gt;
&lt;br /&gt;
For an FDM+systems test, we should run FG without a renderer (which is what the test_suite does) to benchmark the pure C++ performance of whatever system we care about (FDM or whatever). But a few hours playing with 'perf' on Linux or Instruments on macOS will show you that OSG + the GL drivers use 80% of our CPU time, and hence Amdhal's law will always get you.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36977666/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Graphics testing===&lt;br /&gt;
{{See also|FlightGear Benchmark}}&lt;br /&gt;
&lt;br /&gt;
Create test-case scenes where you can quickly measure differences and compare via screenshots. The brain/eye/memory are terrible at this stuff, setup something you can load from the command line via a script to test old/new versions, if possible. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36959002/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, a test would use several rc files (.[[fgfsrc]] variants, with different renderers and threading modes, including static values for:&lt;br /&gt;
*c172p at some parking in a detailed airport&lt;br /&gt;
*camera set with a specific direction and field of view&lt;br /&gt;
*AW with specific METARs around (if not possible, BW with specific METAR)&lt;br /&gt;
*fixed rendering settings ( &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36975122/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We can load a [[Instant Replay|replay tape]] on startup. Since the FDM and User interface are unavailable, replays are suitable for testing rendering and performance.&lt;br /&gt;
&lt;br /&gt;
But essentially, small amounts of shell script + Nasal hacking, can implement any of these methods,  and any of them would be welcome additions. The unit-test framework is excellent for lower-level tests run by developers (i.e., 'Does the API call produce the right results in the system?'), but a smoke test that regular users can run would be ideal. &lt;br /&gt;
&lt;br /&gt;
A rendering performance would likely do the following:&lt;br /&gt;
&lt;br /&gt;
*Select some particular rendering settings (clouds, draw distance, etc)&lt;br /&gt;
*Run a saved fgtape recording&lt;br /&gt;
* Record the mean/min/max FPS during this and save it in some text file/copy to the clipboard&lt;br /&gt;
&lt;br /&gt;
So yes, if anyone wants to work on the above, the code is all there. Please jump in and start hacking. I don't think it needs any more from the core code, but as always, please ask if it does.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36975213/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, when describing a /rendering/ test (to establish FPS), the advantage of a replay tape is that the actual position (and, therefore, the rendered scene) will be 100% consistent across different computers.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that the CPU use of the FDM+systems is typically &amp;lt; 10% of our total CPU use, even when running OSG single-threaded, so for a rendering performance test, whether the FD is run or not is probably noise compared to other things that do run (Nasal, Canvas for example)&lt;br /&gt;
&lt;br /&gt;
Also, the Multi-monitor setup is an area that could use additional unit testing. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36904782/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Fgdata==&lt;br /&gt;
===Nasal scripting (comments)===&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
The now builtin CppUnit framework can solve all the issues&lt;br /&gt;
identified in the old [[Nasal Unit Testing Framework]] wiki article and the discussions it points to&lt;br /&gt;
and provide the full framework required.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36990615/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have some very simple tests running now for the route manager, which relies on Nasal. We're skipping a few of the bigger Nasal modules (local weather, jetways) and have a few lingering issues in some other modules, but the basic concept is working. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
An exciting further step, which you might wish to discuss with Edward, is writing test checks *in* Nasal since this could be quite a fast way to test some areas of the code. There are several ways that could work, and I don't know if Edward has always planned something around this, so I won't preempt that conversation.&lt;br /&gt;
&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36764781/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
we have route-manager tests which validate route_manager.nas is working correctly, and we have Canavs tests ({{fg src file|path=test_suite/simgear_tests/canvas|}}) which poke the Nasal API. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36991200/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We need more FGData testing via the test suite.&lt;br /&gt;
&lt;br /&gt;
James has suggested adding CppUnit assertions to Nasal so others can write tests in pure Nasal. James would make these changes in C++.  &lt;br /&gt;
In addition, some C++ code in a test would scan a directory for files matching a pattern, e.g., test_XYZ.nas, and run each of those automatically.&lt;br /&gt;
&lt;br /&gt;
The idea for testing Nasal would be that you write a small CppUnit&lt;br /&gt;
interface in C++ in $FG_SRC/test_suite/*_tests/ (the FGData Nasal&lt;br /&gt;
testing would be in a fgdata_tests/ directory). This would register&lt;br /&gt;
each test which points to the script in&lt;br /&gt;
$FG_SRC/test_suite/shared_data/nasal/, and the setUp() and tearDown()&lt;br /&gt;
functions would use helper functions in the fgtest namespace to start&lt;br /&gt;
and stop Nasal. The Nasal scripts could then call the CppUnit&lt;br /&gt;
assertion macros wrapped up as Nasal functions for communicating&lt;br /&gt;
failures and errors to the test suite. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36991150/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Scanning for scripts is a great idea. Then, developers (core and content) could write tests using pure Nasal.&lt;br /&gt;
&lt;br /&gt;
However, all scripts found and executed will be seen as a single test within the test suite. So maybe we should have a $FG_SRC/test_suite/nasal_staging/ directory for the initial development of such auto-scanned scripts. But then we have someone shift them into $FG_SRC/test_suite/system_tests/, $FG_SRC/test_suite/unit_tests/, or $FG_SRC/test_suite/fgdata_tests/ later on?  That would give better diagnostics and would avoid long-term clutter.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36991198/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*First, we should probably hard code tests into the C++ framework. For this, the CppUnit assertion macros will have to be wrapped up as Nasal functions.&lt;br /&gt;
*Implement the scanning code as we need some CMake magic (probably using file(COPY, ...)).&lt;br /&gt;
*Finally, we must determine if and how to improve the Nnasaldebugging output.&lt;br /&gt;
&lt;br /&gt;
the code could go into a subdirectory in $FG_SRC/test_suite/fgdata_tests/, and the Nasal script in $FG_SRC/test_suite/shared_data/nasal/.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Core development]]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Software_testing&amp;diff=140259</id>
		<title>Software testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Software_testing&amp;diff=140259"/>
		<updated>2024-08-20T06:04:16Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: /* Structure of a CPPUnit test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Note|There’s already the test_suite in {{fg src file|path=test_suite}} using [[Cppunit effort|CppUnit]], thanks to some hard work by [[User:Bugman|Edward]]. We need more tests written for it; submissions are welcome. (Pick an area of interest)&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36972720/&amp;lt;/ref&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{See also|Cppunit effort}}&lt;br /&gt;
&lt;br /&gt;
FlightGear developers use various testing tools. This includes automated testing via unit tests in [[SimGear]] and a full test suite with multiple test categories in the [[FlightGear Git|flightgear repository]], as well as manual in-sim testing. Writing tests is one of the best ways to jump into FlightGear development.&lt;br /&gt;
&lt;br /&gt;
One improving area is unit testing: certain areas and features (e.g., carrier start) now 'can't break.' As we add testing in additional areas (e.g., Multi-player, AI, protocols, and replay are all possible), we increase the baseline quality and have a clearer idea when we make incompatible changes. (The idea is that we capture the 'supported API' in the tests: when an aircraft deviates from that, we can decide to add another test case, fix the aircraft, etc). Of course, there are some pretty significant areas where Automated Testing Is Hard (TM).&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/37078825/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== SimGear ==&lt;br /&gt;
&lt;br /&gt;
Unit testing for the [[SimGear]] sources uses the CMake CTest unit testing infrastructure. Several tests use the BOOST unit testing infrastructure tied to the build system using CTest; however, the FlightGear developers are shifting towards eliminating BOOST, so CPPUnit and CTest tests are preferred.&lt;br /&gt;
&lt;br /&gt;
=== Building and running the SimGear tests ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ make&lt;br /&gt;
$ ctest&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== FlightGear ==&lt;br /&gt;
&lt;br /&gt;
Testing of the [[FlightGear Git|flightgear sources]] is via a comprehensive test suite implemented using [https://www.freedesktop.org/wiki/Software/cppunit/ CppUnit], a port of the famous JUnit framework.&lt;br /&gt;
&lt;br /&gt;
=== Building the test suite ===&lt;br /&gt;
&lt;br /&gt;
You must build FlightGear from the source using cmake to run the tests. See [[Building FlightGear]] for details.&lt;br /&gt;
&lt;br /&gt;
Once you have your cmake build environment, do the following:&lt;br /&gt;
# Change to your FlightGear build* directory&lt;br /&gt;
# Enable building the tests by setting a cmake variable:  &amp;lt;code&amp;gt;cmake -DBUILD_TESTING=ON .&amp;lt;/code&amp;gt;&lt;br /&gt;
# Ensure the &amp;lt;code&amp;gt;[[$FG ROOT|$FG_ROOT]]&amp;lt;/code&amp;gt; environment variable points to fgdata e.g. &amp;lt;code&amp;gt;$FG_INSTALL_DIR/share/fgdata&amp;lt;/code&amp;gt;&lt;br /&gt;
# Build the test suite:  &amp;lt;code&amp;gt;make test_suite&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Building the test suite will also run a test because you will typically want to write a test and then immediately compile and run it.&lt;br /&gt;
&lt;br /&gt;
 * ls in this directory should include CMakeCache.txt, cmake_install, and others. You do not want to run cmake in the flightgear sources directory, which includes files such as AUTHORS, COPYING, INSTALL, etc.&lt;br /&gt;
&lt;br /&gt;
On a Windows MSVC-based build environment, after generating files with cmake, run the following code:&lt;br /&gt;
# cmake --build . --config RelWithDebInfo --target test_suite/test_suite&lt;br /&gt;
&lt;br /&gt;
=== Running the test suite ===&lt;br /&gt;
&lt;br /&gt;
To run the test suite, simply run &amp;lt;code&amp;gt;./test_suite/fgfs_test_suite&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Executing fgfs_test_suite will run the entire test suite and print a Synopsis of results, as shown below.&lt;br /&gt;
&lt;br /&gt;
 Synopsis&lt;br /&gt;
 ========&lt;br /&gt;
 &lt;br /&gt;
 System/functional tests ....................................... [ OK ]&lt;br /&gt;
 Unit tests .................................................... [ OK ]&lt;br /&gt;
 Simgear unit tests ............................................ [ OK ]&lt;br /&gt;
 FGData tests .................................................. [ OK ]&lt;br /&gt;
 Synopsis ...................................................... [ OK ]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also run individual test cases. Run &amp;lt;code&amp;gt;./test_suite/fgfs_test_suite -h&amp;lt;/code&amp;gt; to see the various options&lt;br /&gt;
&lt;br /&gt;
For example, fgfs_test_suite --log-level=alert -d -u GPSTests will run the GPS unit tests while displaying the output.&lt;br /&gt;
&lt;br /&gt;
=== Why write unit tests? ===&lt;br /&gt;
&lt;br /&gt;
A well-tested piece of software will have a much lower bug count/load. An extensive test suite with &amp;quot;'unit tests,'&amp;quot; system/functional tests, GUI tests, installer tests, and other categories of tests can significantly help in this regard.&lt;br /&gt;
&lt;br /&gt;
The benefits of not just chasing clear &amp;quot;wins&amp;quot; are great: An excellent learning experience for new developers; the ability to catch latent, unreported bugs; making it easier to refactor current code by creating a safety net; making it easier for current developers to accept new contributions (when accompanied with passing tests); helping other test writers by contributing to the standard test suite infrastructure; and being able to check for memory leaks or other issues via Valgrind easily.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36977686/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you are a new developer, jump in and write any test! It does not need to catch a bug. Do whatever you wish! Just dive into this shallow end, and you'll see that the water is not cold.&lt;br /&gt;
&lt;br /&gt;
You are writing a test as a safety net. You write the test to pass, make your changes, and then make sure that the test still passes. Then, you push both the test and core changes.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36977465/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It'd be better to work in a specific area of interest to you and submit merge requests. When reviewed, that would usually trigger some C++ feedback, but we aren't looking for perfection here. The feedback you receive during the open and public review process increases our overall pool of knowledge of what best practice looks like, even if a given commit is less than perfect.&lt;br /&gt;
&lt;br /&gt;
Having 10 or 20 people actively contributing correct and reasonable code is more important than three people contributing perfect, micro-optimised C++. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36951247/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Benefits of unit testing ===&lt;br /&gt;
There are lots of benefits to writing tests that pass.&lt;br /&gt;
&lt;br /&gt;
Benefits include :&lt;br /&gt;
&lt;br /&gt;
* Learning! New developers can learn a ton from writing several passing tests in the area they are interested in. This is one of the quickest ways to learn about a pre-existing and mature code base. You have zero worries about breaking things.&lt;br /&gt;
&lt;br /&gt;
* Latent bug uncovering. One will probably fail every ten tests you write, expecting them to pass. Tests may uncover unexpected behavior that a developer can improve.&lt;br /&gt;
&lt;br /&gt;
* Refactoring. If we had 10,000 passing tests (assuming universal test coverage), large-scale refactoring of the entire code base would be quick and reliable. It would enable refactoring on a scale currently unimaginable. I cannot emphasize enough how much of a benefit this would be.&lt;br /&gt;
&lt;br /&gt;
* Developer turnover. Again, if we had 10,000 passing tests (assuming universal test coverage), it would encourage new developers, giving them confidence that their changes will not cause problems. It is a safety net. It also would provide existing developers peace of mind when a new developer works in one of the dark parts of FlightGear that no current developer understands (there are plenty of those).&lt;br /&gt;
&lt;br /&gt;
* Test suite infrastructure. The more passing tests written, the better the test suite infrastructure will become. We can already do a lot, but adding more passing tests will help other test writers.&lt;br /&gt;
&lt;br /&gt;
* Memory checking. Running a single test through Valgrind is fantastic. Running FlightGear through Valgrind is close to impossible. One can write tests that pass but are useful under Valgrind to catch memory leaks!&lt;br /&gt;
&lt;br /&gt;
* Code quality and standards. If a test compiles on all OSes without warning, it passes, and Valgrind gives you an ok, it is good enough. You don't need to be a C++ expert to dive into this shallow end of the pool.&lt;br /&gt;
&lt;br /&gt;
=== Bootstrapping completely new tests ===&lt;br /&gt;
To start diving straight into the test suite code, firstly copy what has been done in this commit:  {{repo link&lt;br /&gt;
| site   = sf&lt;br /&gt;
| user = edauvergne&lt;br /&gt;
| repo   = flightgear&lt;br /&gt;
| commit = 8474df&lt;br /&gt;
| view   = commit&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Just modify all names for a JSBSim test (or any other test fixture you&lt;br /&gt;
want to code). You should then be able to compile and check that your&lt;br /&gt;
new test dummy () test passes as expected. You can then slowly build up&lt;br /&gt;
from this basic infrastructure as you learn the fgfs internals, c++,&lt;br /&gt;
and git skills required for implementing your test on your fork's new&lt;br /&gt;
development branch :)&lt;br /&gt;
&lt;br /&gt;
=== Structure of a CPPUnit test ===&lt;br /&gt;
&lt;br /&gt;
You're going to create a new test, by &lt;br /&gt;
* Choosing an appropriate test group directory and an appropriate topic directory for the new test&lt;br /&gt;
* Creating a class in .cxx and .hxx files, &lt;br /&gt;
* Add some CPPUNIT boilerplate code, common to all the tests&lt;br /&gt;
* Modifying CMakeLists.txt files to ensure your new class is built&lt;br /&gt;
* Adding a registration entry for your new class in the chosen directory's TestSuite.cxx file.  &lt;br /&gt;
&lt;br /&gt;
These are the test group directories&lt;br /&gt;
&lt;br /&gt;
* flightgear/test_suite/fgdata_tests&lt;br /&gt;
* flightgear/test_suite/gui_tests&lt;br /&gt;
* flightgear/test_suite/simgear_tests&lt;br /&gt;
* flightgear/test_suite/system_tests&lt;br /&gt;
* flightgear/test_suite/unit_tests&lt;br /&gt;
&lt;br /&gt;
Under each of these directories, are topic directory&lt;br /&gt;
For example, under flightgear/test_suite/unit_tests, you'll find directory names (topics) that roughly correspond to the directories under flightgear/src.└── unit_tests&lt;br /&gt;
    ├── Add-ons&lt;br /&gt;
    ├── AI&lt;br /&gt;
    ├── Airports&lt;br /&gt;
    ├── Autopilot&lt;br /&gt;
    ├── CMakeLists.txt&lt;br /&gt;
    ├── FDM&lt;br /&gt;
    ├── general&lt;br /&gt;
    ├── Input&lt;br /&gt;
    ├── Instrumentation&lt;br /&gt;
    ├── Main&lt;br /&gt;
    ├── Navaids&lt;br /&gt;
    ├── Network&lt;br /&gt;
    └── Scripting&lt;br /&gt;
For this example we'll look at the steps taken to add the httpd tests under test_suite/Network.&lt;br /&gt;
&lt;br /&gt;
Steps:&lt;br /&gt;
*Create two new files: test_suite/Network/test_httpd.cxx and test_httpd.hxx. Note that these filenames start with test_. That's a Flightgear standard.&lt;br /&gt;
*Add the appropriate license files and boilerplate code &lt;br /&gt;
*Modify two names in the boilerplate &lt;br /&gt;
    ├── Add-ons&lt;br /&gt;
    ├── AI&lt;br /&gt;
    ├── Airports&lt;br /&gt;
    ├── Autopilot&lt;br /&gt;
    ├── CMakeLists.txt&lt;br /&gt;
    ├── FDM&lt;br /&gt;
    ├── general&lt;br /&gt;
    ├── Input&lt;br /&gt;
    ├── Instrumentation&lt;br /&gt;
    ├── Main&lt;br /&gt;
    ├── Navaids&lt;br /&gt;
    ├── Network&lt;br /&gt;
    └── Scripting&lt;br /&gt;
For this example we'll look at the steps taken to add the httpd tests under test_suite/Network.&lt;br /&gt;
&lt;br /&gt;
Steps:&lt;br /&gt;
#&amp;lt;blockquote&amp;gt;class HttpdTest : public CppUnit::TestFixture {  // Set up the test suite.  CPPUNIT_TEST_SUITE(HttpdTest);  CPPUNIT_TEST(testHttpd);  CPPUNIT_TEST_SUITE_END();  public:  // Set up function for each test.  void setUp();  // Clean up after each test.  void tearDown();  // Test  void testHttpd();  };&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
#&amp;lt;blockquote&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
===Headless testing===&lt;br /&gt;
{{Main article|FlightGear Headless}}&lt;br /&gt;
&lt;br /&gt;
For an FDM+systems test, we should run FG without a renderer (which is what the test_suite does) to benchmark the pure C++ performance of whatever system we care about (FDM or whatever). But a few hours playing with 'perf' on Linux or Instruments on macOS will show you that OSG + the GL drivers use 80% of our CPU time, and hence Amdhal's law will always get you.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36977666/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Graphics testing===&lt;br /&gt;
{{See also|FlightGear Benchmark}}&lt;br /&gt;
&lt;br /&gt;
Create test-case scenes where you can quickly measure differences and compare via screenshots. The brain/eye/memory are terrible at this stuff, setup something you can load from the command line via a script to test old/new versions, if possible. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36959002/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, a test would use several rc files (.[[fgfsrc]] variants, with different renderers and threading modes, including static values for:&lt;br /&gt;
*c172p at some parking in a detailed airport&lt;br /&gt;
*camera set with a specific direction and field of view&lt;br /&gt;
*AW with specific METARs around (if not possible, BW with specific METAR)&lt;br /&gt;
*fixed rendering settings ( &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36975122/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We can load a [[Instant Replay|replay tape]] on startup. Since the FDM and User interface are unavailable, replays are suitable for testing rendering and performance.&lt;br /&gt;
&lt;br /&gt;
But essentially, small amounts of shell script + Nasal hacking, can implement any of these methods,  and any of them would be welcome additions. The unit-test framework is excellent for lower-level tests run by developers (i.e., 'Does the API call produce the right results in the system?'), but a smoke test that regular users can run would be ideal. &lt;br /&gt;
&lt;br /&gt;
A rendering performance would likely do the following:&lt;br /&gt;
&lt;br /&gt;
*Select some particular rendering settings (clouds, draw distance, etc)&lt;br /&gt;
*Run a saved fgtape recording&lt;br /&gt;
* Record the mean/min/max FPS during this and save it in some text file/copy to the clipboard&lt;br /&gt;
&lt;br /&gt;
So yes, if anyone wants to work on the above, the code is all there. Please jump in and start hacking. I don't think it needs any more from the core code, but as always, please ask if it does.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36975213/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, when describing a /rendering/ test (to establish FPS), the advantage of a replay tape is that the actual position (and, therefore, the rendered scene) will be 100% consistent across different computers.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that the CPU use of the FDM+systems is typically &amp;lt; 10% of our total CPU use, even when running OSG single-threaded, so for a rendering performance test, whether the FD is run or not is probably noise compared to other things that do run (Nasal, Canvas for example)&lt;br /&gt;
&lt;br /&gt;
Also, the Multi-monitor setup is an area that could use additional unit testing. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36904782/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Fgdata==&lt;br /&gt;
===Nasal scripting (comments)===&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
The now builtin CppUnit framework can solve all the issues&lt;br /&gt;
identified in the old [[Nasal Unit Testing Framework]] wiki article and the discussions it points to&lt;br /&gt;
and provide the full framework required.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36990615/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have some very simple tests running now for the route manager, which relies on Nasal. We're skipping a few of the bigger Nasal modules (local weather, jetways) and have a few lingering issues in some other modules, but the basic concept is working. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
An exciting further step, which you might wish to discuss with Edward, is writing test checks *in* Nasal since this could be quite a fast way to test some areas of the code. There are several ways that could work, and I don't know if Edward has always planned something around this, so I won't preempt that conversation.&lt;br /&gt;
&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36764781/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
we have route-manager tests which validate route_manager.nas is working correctly, and we have Canavs tests ({{fg src file|path=test_suite/simgear_tests/canvas|}}) which poke the Nasal API. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36991200/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We need more FGData testing via the test suite.&lt;br /&gt;
&lt;br /&gt;
James has suggested adding CppUnit assertions to Nasal so others can write tests in pure Nasal. James would make these changes in C++.  &lt;br /&gt;
In addition, some C++ code in a test would scan a directory for files matching a pattern, e.g., test_XYZ.nas, and run each of those automatically.&lt;br /&gt;
&lt;br /&gt;
The idea for testing Nasal would be that you write a small CppUnit&lt;br /&gt;
interface in C++ in $FG_SRC/test_suite/*_tests/ (the FGData Nasal&lt;br /&gt;
testing would be in a fgdata_tests/ directory). This would register&lt;br /&gt;
each test which points to the script in&lt;br /&gt;
$FG_SRC/test_suite/shared_data/nasal/, and the setUp() and tearDown()&lt;br /&gt;
functions would use helper functions in the fgtest namespace to start&lt;br /&gt;
and stop Nasal. The Nasal scripts could then call the CppUnit&lt;br /&gt;
assertion macros wrapped up as Nasal functions for communicating&lt;br /&gt;
failures and errors to the test suite. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36991150/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Scanning for scripts is a great idea. Then, developers (core and content) could write tests using pure Nasal.&lt;br /&gt;
&lt;br /&gt;
However, all scripts found and executed will be seen as a single test within the test suite. So maybe we should have a $FG_SRC/test_suite/nasal_staging/ directory for the initial development of such auto-scanned scripts. But then we have someone shift them into $FG_SRC/test_suite/system_tests/, $FG_SRC/test_suite/unit_tests/, or $FG_SRC/test_suite/fgdata_tests/ later on?  That would give better diagnostics and would avoid long-term clutter.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36991198/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*First, we should probably hard code tests into the C++ framework. For this, the CppUnit assertion macros will have to be wrapped up as Nasal functions.&lt;br /&gt;
*Implement the scanning code as we need some CMake magic (probably using file(COPY, ...)).&lt;br /&gt;
*Finally, we must determine if and how to improve the Nnasaldebugging output.&lt;br /&gt;
&lt;br /&gt;
the code could go into a subdirectory in $FG_SRC/test_suite/fgdata_tests/, and the Nasal script in $FG_SRC/test_suite/shared_data/nasal/.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Core development]]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Software_testing&amp;diff=140258</id>
		<title>Software testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Software_testing&amp;diff=140258"/>
		<updated>2024-08-20T05:49:35Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: /* Structure of a CPPUnit test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Note|There’s already the test_suite in {{fg src file|path=test_suite}} using [[Cppunit effort|CppUnit]], thanks to some hard work by [[User:Bugman|Edward]]. We need more tests written for it; submissions are welcome. (Pick an area of interest)&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36972720/&amp;lt;/ref&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{See also|Cppunit effort}}&lt;br /&gt;
&lt;br /&gt;
FlightGear developers use various testing tools. This includes automated testing via unit tests in [[SimGear]] and a full test suite with multiple test categories in the [[FlightGear Git|flightgear repository]], as well as manual in-sim testing. Writing tests is one of the best ways to jump into FlightGear development.&lt;br /&gt;
&lt;br /&gt;
One improving area is unit testing: certain areas and features (e.g., carrier start) now 'can't break.' As we add testing in additional areas (e.g., Multi-player, AI, protocols, and replay are all possible), we increase the baseline quality and have a clearer idea when we make incompatible changes. (The idea is that we capture the 'supported API' in the tests: when an aircraft deviates from that, we can decide to add another test case, fix the aircraft, etc). Of course, there are some pretty significant areas where Automated Testing Is Hard (TM).&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/37078825/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== SimGear ==&lt;br /&gt;
&lt;br /&gt;
Unit testing for the [[SimGear]] sources uses the CMake CTest unit testing infrastructure. Several tests use the BOOST unit testing infrastructure tied to the build system using CTest; however, the FlightGear developers are shifting towards eliminating BOOST, so CPPUnit and CTest tests are preferred.&lt;br /&gt;
&lt;br /&gt;
=== Building and running the SimGear tests ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ make&lt;br /&gt;
$ ctest&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== FlightGear ==&lt;br /&gt;
&lt;br /&gt;
Testing of the [[FlightGear Git|flightgear sources]] is via a comprehensive test suite implemented using [https://www.freedesktop.org/wiki/Software/cppunit/ CppUnit], a port of the famous JUnit framework.&lt;br /&gt;
&lt;br /&gt;
=== Building the test suite ===&lt;br /&gt;
&lt;br /&gt;
You must build FlightGear from the source using cmake to run the tests. See [[Building FlightGear]] for details.&lt;br /&gt;
&lt;br /&gt;
Once you have your cmake build environment, do the following:&lt;br /&gt;
# Change to your FlightGear build* directory&lt;br /&gt;
# Enable building the tests by setting a cmake variable:  &amp;lt;code&amp;gt;cmake -DBUILD_TESTING=ON .&amp;lt;/code&amp;gt;&lt;br /&gt;
# Ensure the &amp;lt;code&amp;gt;[[$FG ROOT|$FG_ROOT]]&amp;lt;/code&amp;gt; environment variable points to fgdata e.g. &amp;lt;code&amp;gt;$FG_INSTALL_DIR/share/fgdata&amp;lt;/code&amp;gt;&lt;br /&gt;
# Build the test suite:  &amp;lt;code&amp;gt;make test_suite&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Building the test suite will also run a test because you will typically want to write a test and then immediately compile and run it.&lt;br /&gt;
&lt;br /&gt;
 * ls in this directory should include CMakeCache.txt, cmake_install, and others. You do not want to run cmake in the flightgear sources directory, which includes files such as AUTHORS, COPYING, INSTALL, etc.&lt;br /&gt;
&lt;br /&gt;
On a Windows MSVC-based build environment, after generating files with cmake, run the following code:&lt;br /&gt;
# cmake --build . --config RelWithDebInfo --target test_suite/test_suite&lt;br /&gt;
&lt;br /&gt;
=== Running the test suite ===&lt;br /&gt;
&lt;br /&gt;
To run the test suite, simply run &amp;lt;code&amp;gt;./test_suite/fgfs_test_suite&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Executing fgfs_test_suite will run the entire test suite and print a Synopsis of results, as shown below.&lt;br /&gt;
&lt;br /&gt;
 Synopsis&lt;br /&gt;
 ========&lt;br /&gt;
 &lt;br /&gt;
 System/functional tests ....................................... [ OK ]&lt;br /&gt;
 Unit tests .................................................... [ OK ]&lt;br /&gt;
 Simgear unit tests ............................................ [ OK ]&lt;br /&gt;
 FGData tests .................................................. [ OK ]&lt;br /&gt;
 Synopsis ...................................................... [ OK ]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also run individual test cases. Run &amp;lt;code&amp;gt;./test_suite/fgfs_test_suite -h&amp;lt;/code&amp;gt; to see the various options&lt;br /&gt;
&lt;br /&gt;
For example, fgfs_test_suite --log-level=alert -d -u GPSTests will run the GPS unit tests while displaying the output.&lt;br /&gt;
&lt;br /&gt;
=== Why write unit tests? ===&lt;br /&gt;
&lt;br /&gt;
A well-tested piece of software will have a much lower bug count/load. An extensive test suite with &amp;quot;'unit tests,'&amp;quot; system/functional tests, GUI tests, installer tests, and other categories of tests can significantly help in this regard.&lt;br /&gt;
&lt;br /&gt;
The benefits of not just chasing clear &amp;quot;wins&amp;quot; are great: An excellent learning experience for new developers; the ability to catch latent, unreported bugs; making it easier to refactor current code by creating a safety net; making it easier for current developers to accept new contributions (when accompanied with passing tests); helping other test writers by contributing to the standard test suite infrastructure; and being able to check for memory leaks or other issues via Valgrind easily.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36977686/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you are a new developer, jump in and write any test! It does not need to catch a bug. Do whatever you wish! Just dive into this shallow end, and you'll see that the water is not cold.&lt;br /&gt;
&lt;br /&gt;
You are writing a test as a safety net. You write the test to pass, make your changes, and then make sure that the test still passes. Then, you push both the test and core changes.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36977465/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It'd be better to work in a specific area of interest to you and submit merge requests. When reviewed, that would usually trigger some C++ feedback, but we aren't looking for perfection here. The feedback you receive during the open and public review process increases our overall pool of knowledge of what best practice looks like, even if a given commit is less than perfect.&lt;br /&gt;
&lt;br /&gt;
Having 10 or 20 people actively contributing correct and reasonable code is more important than three people contributing perfect, micro-optimised C++. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36951247/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Benefits of unit testing ===&lt;br /&gt;
There are lots of benefits to writing tests that pass.&lt;br /&gt;
&lt;br /&gt;
Benefits include :&lt;br /&gt;
&lt;br /&gt;
* Learning! New developers can learn a ton from writing several passing tests in the area they are interested in. This is one of the quickest ways to learn about a pre-existing and mature code base. You have zero worries about breaking things.&lt;br /&gt;
&lt;br /&gt;
* Latent bug uncovering. One will probably fail every ten tests you write, expecting them to pass. Tests may uncover unexpected behavior that a developer can improve.&lt;br /&gt;
&lt;br /&gt;
* Refactoring. If we had 10,000 passing tests (assuming universal test coverage), large-scale refactoring of the entire code base would be quick and reliable. It would enable refactoring on a scale currently unimaginable. I cannot emphasize enough how much of a benefit this would be.&lt;br /&gt;
&lt;br /&gt;
* Developer turnover. Again, if we had 10,000 passing tests (assuming universal test coverage), it would encourage new developers, giving them confidence that their changes will not cause problems. It is a safety net. It also would provide existing developers peace of mind when a new developer works in one of the dark parts of FlightGear that no current developer understands (there are plenty of those).&lt;br /&gt;
&lt;br /&gt;
* Test suite infrastructure. The more passing tests written, the better the test suite infrastructure will become. We can already do a lot, but adding more passing tests will help other test writers.&lt;br /&gt;
&lt;br /&gt;
* Memory checking. Running a single test through Valgrind is fantastic. Running FlightGear through Valgrind is close to impossible. One can write tests that pass but are useful under Valgrind to catch memory leaks!&lt;br /&gt;
&lt;br /&gt;
* Code quality and standards. If a test compiles on all OSes without warning, it passes, and Valgrind gives you an ok, it is good enough. You don't need to be a C++ expert to dive into this shallow end of the pool.&lt;br /&gt;
&lt;br /&gt;
=== Bootstrapping completely new tests ===&lt;br /&gt;
To start diving straight into the test suite code, firstly copy what has been done in this commit:  {{repo link&lt;br /&gt;
| site   = sf&lt;br /&gt;
| user = edauvergne&lt;br /&gt;
| repo   = flightgear&lt;br /&gt;
| commit = 8474df&lt;br /&gt;
| view   = commit&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Just modify all names for a JSBSim test (or any other test fixture you&lt;br /&gt;
want to code). You should then be able to compile and check that your&lt;br /&gt;
new test dummy () test passes as expected. You can then slowly build up&lt;br /&gt;
from this basic infrastructure as you learn the fgfs internals, c++,&lt;br /&gt;
and git skills required for implementing your test on your fork's new&lt;br /&gt;
development branch :)&lt;br /&gt;
&lt;br /&gt;
=== Structure of a CPPUnit test ===&lt;br /&gt;
&lt;br /&gt;
You're going to create a new test, by &lt;br /&gt;
* Choosing an appropriate test group directory and an appropriate topic directory for the new test&lt;br /&gt;
* Creating a class in .cxx and .hxx files, &lt;br /&gt;
* Add some CPPUNIT boilerplate code, common to all the tests&lt;br /&gt;
* Modifying CMakeLists.txt files to ensure your new class is built&lt;br /&gt;
* Adding a registration entry for your new class in the chosen directory's TestSuite.cxx file.  &lt;br /&gt;
&lt;br /&gt;
These are the test group directories&lt;br /&gt;
&lt;br /&gt;
* flightgear/test_suite/fgdata_tests&lt;br /&gt;
* flightgear/test_suite/gui_tests&lt;br /&gt;
* flightgear/test_suite/simgear_tests&lt;br /&gt;
* flightgear/test_suite/system_tests&lt;br /&gt;
* flightgear/test_suite/unit_tests&lt;br /&gt;
&lt;br /&gt;
Under each of these directories, are topic directory&lt;br /&gt;
For example, under flightgear/test_suite/unit_tests, you'll find directory names (topics) that roughly correspond to the directories under flightgear/src.&lt;br /&gt;
```&lt;br /&gt;
└── unit_tests&lt;br /&gt;
    ├── Add-ons&lt;br /&gt;
    ├── AI&lt;br /&gt;
    ├── Airports&lt;br /&gt;
    ├── Autopilot&lt;br /&gt;
    ├── CMakeLists.txt&lt;br /&gt;
    ├── FDM&lt;br /&gt;
    ├── general&lt;br /&gt;
    ├── Input&lt;br /&gt;
    ├── Instrumentation&lt;br /&gt;
    ├── Main&lt;br /&gt;
    ├── Navaids&lt;br /&gt;
    ├── Network&lt;br /&gt;
    └── Scripting&lt;br /&gt;
```&lt;br /&gt;
For this example we'll look at the steps taken to add the httpd tests under test_suite/Network.&lt;br /&gt;
&lt;br /&gt;
Steps:&lt;br /&gt;
#  Create two new files: test_suite/Network/test_httpd.cxx and test_httpd.hxx. Note that these filenames start with test_. That's a Flightgear standard.&lt;br /&gt;
&lt;br /&gt;
Add the appropriate license files at the top of each of these files.&lt;br /&gt;
&lt;br /&gt;
=== Headless testing ===&lt;br /&gt;
{{Main article|FlightGear Headless}}&lt;br /&gt;
&lt;br /&gt;
For an FDM+systems test, we should run FG without a renderer (which is what the test_suite does) to benchmark the pure C++ performance of whatever system we care about (FDM or whatever). But a few hours playing with 'perf' on Linux or Instruments on macOS will show you that OSG + the GL drivers use 80% of our CPU time, and hence Amdhal's law will always get you.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36977666/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Graphics testing ===&lt;br /&gt;
{{See also|FlightGear Benchmark}}&lt;br /&gt;
&lt;br /&gt;
Create test-case scenes where you can quickly measure differences and compare via screenshots. The brain/eye/memory are terrible at this stuff, setup something you can load from the command line via a script to test old/new versions, if possible. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36959002/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, a test would use several rc files (.[[fgfsrc]] variants, with different renderers and threading modes, including static values for:&lt;br /&gt;
* c172p at some parking in a detailed airport&lt;br /&gt;
* camera set with a specific direction and field of view&lt;br /&gt;
* AW with specific METARs around (if not possible, BW with specific METAR)&lt;br /&gt;
* fixed rendering settings ( &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36975122/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We can load a [[Instant Replay|replay tape]] on startup. Since the FDM and User interface are unavailable, replays are suitable for testing rendering and performance.&lt;br /&gt;
&lt;br /&gt;
But essentially, small amounts of shell script + Nasal hacking, can implement any of these methods,  and any of them would be welcome additions. The unit-test framework is excellent for lower-level tests run by developers (i.e., 'Does the API call produce the right results in the system?'), but a smoke test that regular users can run would be ideal. &lt;br /&gt;
&lt;br /&gt;
A rendering performance would likely do the following:&lt;br /&gt;
&lt;br /&gt;
* Select some particular rendering settings (clouds, draw distance, etc)&lt;br /&gt;
* Run a saved fgtape recording&lt;br /&gt;
* Record the mean/min/max FPS during this and save it in some text file/copy to the clipboard&lt;br /&gt;
&lt;br /&gt;
So yes, if anyone wants to work on the above, the code is all there. Please jump in and start hacking. I don't think it needs any more from the core code, but as always, please ask if it does.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36975213/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, when describing a /rendering/ test (to establish FPS), the advantage of a replay tape is that the actual position (and, therefore, the rendered scene) will be 100% consistent across different computers.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that the CPU use of the FDM+systems is typically &amp;lt; 10% of our total CPU use, even when running OSG single-threaded, so for a rendering performance test, whether the FD is run or not is probably noise compared to other things that do run (Nasal, Canvas for example)&lt;br /&gt;
&lt;br /&gt;
Also, the Multi-monitor setup is an area that could use additional unit testing. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36904782/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fgdata ==&lt;br /&gt;
=== Nasal scripting (comments) ===&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
The now builtin CppUnit framework can solve all the issues&lt;br /&gt;
identified in the old [[Nasal Unit Testing Framework]] wiki article and the discussions it points to&lt;br /&gt;
and provide the full framework required.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36990615/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have some very simple tests running now for the route manager, which relies on Nasal. We're skipping a few of the bigger Nasal modules (local weather, jetways) and have a few lingering issues in some other modules, but the basic concept is working. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
An exciting further step, which you might wish to discuss with Edward, is writing test checks *in* Nasal since this could be quite a fast way to test some areas of the code. There are several ways that could work, and I don't know if Edward has always planned something around this, so I won't preempt that conversation.&lt;br /&gt;
&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36764781/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
we have route-manager tests which validate route_manager.nas is working correctly, and we have Canavs tests ({{fg src file|path=test_suite/simgear_tests/canvas|}}) which poke the Nasal API. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36991200/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We need more FGData testing via the test suite.&lt;br /&gt;
&lt;br /&gt;
James has suggested adding CppUnit assertions to Nasal so others can write tests in pure Nasal. James would make these changes in C++.  &lt;br /&gt;
In addition, some C++ code in a test would scan a directory for files matching a pattern, e.g., test_XYZ.nas, and run each of those automatically.&lt;br /&gt;
&lt;br /&gt;
The idea for testing Nasal would be that you write a small CppUnit&lt;br /&gt;
interface in C++ in $FG_SRC/test_suite/*_tests/ (the FGData Nasal&lt;br /&gt;
testing would be in a fgdata_tests/ directory). This would register&lt;br /&gt;
each test which points to the script in&lt;br /&gt;
$FG_SRC/test_suite/shared_data/nasal/, and the setUp() and tearDown()&lt;br /&gt;
functions would use helper functions in the fgtest namespace to start&lt;br /&gt;
and stop Nasal. The Nasal scripts could then call the CppUnit&lt;br /&gt;
assertion macros wrapped up as Nasal functions for communicating&lt;br /&gt;
failures and errors to the test suite. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36991150/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Scanning for scripts is a great idea. Then, developers (core and content) could write tests using pure Nasal.&lt;br /&gt;
&lt;br /&gt;
However, all scripts found and executed will be seen as a single test within the test suite. So maybe we should have a $FG_SRC/test_suite/nasal_staging/ directory for the initial development of such auto-scanned scripts. But then we have someone shift them into $FG_SRC/test_suite/system_tests/, $FG_SRC/test_suite/unit_tests/, or $FG_SRC/test_suite/fgdata_tests/ later on?  That would give better diagnostics and would avoid long-term clutter.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36991198/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* First, we should probably hard code tests into the C++ framework. For this, the CppUnit assertion macros will have to be wrapped up as Nasal functions.&lt;br /&gt;
* Implement the scanning code as we need some CMake magic (probably using file(COPY, ...)).&lt;br /&gt;
* Finally, we must determine if and how to improve the Nnasaldebugging output.&lt;br /&gt;
&lt;br /&gt;
the code could go into a subdirectory in $FG_SRC/test_suite/fgdata_tests/, and the Nasal script in $FG_SRC/test_suite/shared_data/nasal/.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Core development]]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Software_testing&amp;diff=140257</id>
		<title>Software testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Software_testing&amp;diff=140257"/>
		<updated>2024-08-20T04:37:33Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: /* Bootstrapping completely new tests */ Adding a detailed description of the elements of a single test.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Note|There’s already the test_suite in {{fg src file|path=test_suite}} using [[Cppunit effort|CppUnit]], thanks to some hard work by [[User:Bugman|Edward]]. We need more tests written for it; submissions are welcome. (Pick an area of interest)&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36972720/&amp;lt;/ref&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{See also|Cppunit effort}}&lt;br /&gt;
&lt;br /&gt;
FlightGear developers use various testing tools. This includes automated testing via unit tests in [[SimGear]] and a full test suite with multiple test categories in the [[FlightGear Git|flightgear repository]], as well as manual in-sim testing. Writing tests is one of the best ways to jump into FlightGear development.&lt;br /&gt;
&lt;br /&gt;
One improving area is unit testing: certain areas and features (e.g., carrier start) now 'can't break.' As we add testing in additional areas (e.g., Multi-player, AI, protocols, and replay are all possible), we increase the baseline quality and have a clearer idea when we make incompatible changes. (The idea is that we capture the 'supported API' in the tests: when an aircraft deviates from that, we can decide to add another test case, fix the aircraft, etc). Of course, there are some pretty significant areas where Automated Testing Is Hard (TM).&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/37078825/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== SimGear ==&lt;br /&gt;
&lt;br /&gt;
Unit testing for the [[SimGear]] sources uses the CMake CTest unit testing infrastructure. Several tests use the BOOST unit testing infrastructure tied to the build system using CTest; however, the FlightGear developers are shifting towards eliminating BOOST, so CPPUnit and CTest tests are preferred.&lt;br /&gt;
&lt;br /&gt;
=== Building and running the SimGear tests ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ make&lt;br /&gt;
$ ctest&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== FlightGear ==&lt;br /&gt;
&lt;br /&gt;
Testing of the [[FlightGear Git|flightgear sources]] is via a comprehensive test suite implemented using [https://www.freedesktop.org/wiki/Software/cppunit/ CppUnit], a port of the famous JUnit framework.&lt;br /&gt;
&lt;br /&gt;
=== Building the test suite ===&lt;br /&gt;
&lt;br /&gt;
You must build FlightGear from the source using cmake to run the tests. See [[Building FlightGear]] for details.&lt;br /&gt;
&lt;br /&gt;
Once you have your cmake build environment, do the following:&lt;br /&gt;
# Change to your FlightGear build* directory&lt;br /&gt;
# Enable building the tests by setting a cmake variable:  &amp;lt;code&amp;gt;cmake -DBUILD_TESTING=ON .&amp;lt;/code&amp;gt;&lt;br /&gt;
# Ensure the &amp;lt;code&amp;gt;[[$FG ROOT|$FG_ROOT]]&amp;lt;/code&amp;gt; environment variable points to fgdata e.g. &amp;lt;code&amp;gt;$FG_INSTALL_DIR/share/fgdata&amp;lt;/code&amp;gt;&lt;br /&gt;
# Build the test suite:  &amp;lt;code&amp;gt;make test_suite&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Building the test suite will also run a test because you will typically want to write a test and then immediately compile and run it.&lt;br /&gt;
&lt;br /&gt;
 * ls in this directory should include CMakeCache.txt, cmake_install, and others. You do not want to run cmake in the flightgear sources directory, which includes files such as AUTHORS, COPYING, INSTALL, etc.&lt;br /&gt;
&lt;br /&gt;
On a Windows MSVC-based build environment, after generating files with cmake, run the following code:&lt;br /&gt;
# cmake --build . --config RelWithDebInfo --target test_suite/test_suite&lt;br /&gt;
&lt;br /&gt;
=== Running the test suite ===&lt;br /&gt;
&lt;br /&gt;
To run the test suite, simply run &amp;lt;code&amp;gt;./test_suite/fgfs_test_suite&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Executing fgfs_test_suite will run the entire test suite and print a Synopsis of results, as shown below.&lt;br /&gt;
&lt;br /&gt;
 Synopsis&lt;br /&gt;
 ========&lt;br /&gt;
 &lt;br /&gt;
 System/functional tests ....................................... [ OK ]&lt;br /&gt;
 Unit tests .................................................... [ OK ]&lt;br /&gt;
 Simgear unit tests ............................................ [ OK ]&lt;br /&gt;
 FGData tests .................................................. [ OK ]&lt;br /&gt;
 Synopsis ...................................................... [ OK ]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also run individual test cases. Run &amp;lt;code&amp;gt;./test_suite/fgfs_test_suite -h&amp;lt;/code&amp;gt; to see the various options&lt;br /&gt;
&lt;br /&gt;
For example, fgfs_test_suite --log-level=alert -d -u GPSTests will run the GPS unit tests while displaying the output.&lt;br /&gt;
&lt;br /&gt;
=== Why write unit tests? ===&lt;br /&gt;
&lt;br /&gt;
A well-tested piece of software will have a much lower bug count/load. An extensive test suite with &amp;quot;'unit tests,'&amp;quot; system/functional tests, GUI tests, installer tests, and other categories of tests can significantly help in this regard.&lt;br /&gt;
&lt;br /&gt;
The benefits of not just chasing clear &amp;quot;wins&amp;quot; are great: An excellent learning experience for new developers; the ability to catch latent, unreported bugs; making it easier to refactor current code by creating a safety net; making it easier for current developers to accept new contributions (when accompanied with passing tests); helping other test writers by contributing to the standard test suite infrastructure; and being able to check for memory leaks or other issues via Valgrind easily.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36977686/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you are a new developer, jump in and write any test! It does not need to catch a bug. Do whatever you wish! Just dive into this shallow end, and you'll see that the water is not cold.&lt;br /&gt;
&lt;br /&gt;
You are writing a test as a safety net. You write the test to pass, make your changes, and then make sure that the test still passes. Then, you push both the test and core changes.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36977465/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It'd be better to work in a specific area of interest to you and submit merge requests. When reviewed, that would usually trigger some C++ feedback, but we aren't looking for perfection here. The feedback you receive during the open and public review process increases our overall pool of knowledge of what best practice looks like, even if a given commit is less than perfect.&lt;br /&gt;
&lt;br /&gt;
Having 10 or 20 people actively contributing correct and reasonable code is more important than three people contributing perfect, micro-optimised C++. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36951247/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Benefits of unit testing ===&lt;br /&gt;
There are lots of benefits to writing tests that pass.&lt;br /&gt;
&lt;br /&gt;
Benefits include :&lt;br /&gt;
&lt;br /&gt;
* Learning! New developers can learn a ton from writing several passing tests in the area they are interested in. This is one of the quickest ways to learn about a pre-existing and mature code base. You have zero worries about breaking things.&lt;br /&gt;
&lt;br /&gt;
* Latent bug uncovering. One will probably fail every ten tests you write, expecting them to pass. Tests may uncover unexpected behavior that a developer can improve.&lt;br /&gt;
&lt;br /&gt;
* Refactoring. If we had 10,000 passing tests (assuming universal test coverage), large-scale refactoring of the entire code base would be quick and reliable. It would enable refactoring on a scale currently unimaginable. I cannot emphasize enough how much of a benefit this would be.&lt;br /&gt;
&lt;br /&gt;
* Developer turnover. Again, if we had 10,000 passing tests (assuming universal test coverage), it would encourage new developers, giving them confidence that their changes will not cause problems. It is a safety net. It also would provide existing developers peace of mind when a new developer works in one of the dark parts of FlightGear that no current developer understands (there are plenty of those).&lt;br /&gt;
&lt;br /&gt;
* Test suite infrastructure. The more passing tests written, the better the test suite infrastructure will become. We can already do a lot, but adding more passing tests will help other test writers.&lt;br /&gt;
&lt;br /&gt;
* Memory checking. Running a single test through Valgrind is fantastic. Running FlightGear through Valgrind is close to impossible. One can write tests that pass but are useful under Valgrind to catch memory leaks!&lt;br /&gt;
&lt;br /&gt;
* Code quality and standards. If a test compiles on all OSes without warning, it passes, and Valgrind gives you an ok, it is good enough. You don't need to be a C++ expert to dive into this shallow end of the pool.&lt;br /&gt;
&lt;br /&gt;
=== Bootstrapping completely new tests ===&lt;br /&gt;
To start diving straight into the test suite code, firstly copy what has been done in this commit:  {{repo link&lt;br /&gt;
| site   = sf&lt;br /&gt;
| user = edauvergne&lt;br /&gt;
| repo   = flightgear&lt;br /&gt;
| commit = 8474df&lt;br /&gt;
| view   = commit&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Just modify all names for a JSBSim test (or any other test fixture you&lt;br /&gt;
want to code). You should then be able to compile and check that your&lt;br /&gt;
new test dummy () test passes as expected. You can then slowly build up&lt;br /&gt;
from this basic infrastructure as you learn the fgfs internals, c++,&lt;br /&gt;
and git skills required for implementing your test on your fork's new&lt;br /&gt;
development branch :)&lt;br /&gt;
&lt;br /&gt;
=== Structure of a CPPUnit test ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you look at the example above&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Headless testing ===&lt;br /&gt;
{{Main article|FlightGear Headless}}&lt;br /&gt;
&lt;br /&gt;
For an FDM+systems test, we should run FG without a renderer (which is what the test_suite does) to benchmark the pure C++ performance of whatever system we care about (FDM or whatever). But a few hours playing with 'perf' on Linux or Instruments on macOS will show you that OSG + the GL drivers use 80% of our CPU time, and hence Amdhal's law will always get you.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36977666/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Graphics testing ===&lt;br /&gt;
{{See also|FlightGear Benchmark}}&lt;br /&gt;
&lt;br /&gt;
Create test-case scenes where you can quickly measure differences and compare via screenshots. The brain/eye/memory are terrible at this stuff, setup something you can load from the command line via a script to test old/new versions, if possible. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36959002/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, a test would use several rc files (.[[fgfsrc]] variants, with different renderers and threading modes, including static values for:&lt;br /&gt;
* c172p at some parking in a detailed airport&lt;br /&gt;
* camera set with a specific direction and field of view&lt;br /&gt;
* AW with specific METARs around (if not possible, BW with specific METAR)&lt;br /&gt;
* fixed rendering settings ( &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36975122/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We can load a [[Instant Replay|replay tape]] on startup. Since the FDM and User interface are unavailable, replays are suitable for testing rendering and performance.&lt;br /&gt;
&lt;br /&gt;
But essentially, small amounts of shell script + Nasal hacking, can implement any of these methods,  and any of them would be welcome additions. The unit-test framework is excellent for lower-level tests run by developers (i.e., 'Does the API call produce the right results in the system?'), but a smoke test that regular users can run would be ideal. &lt;br /&gt;
&lt;br /&gt;
A rendering performance would likely do the following:&lt;br /&gt;
&lt;br /&gt;
* Select some particular rendering settings (clouds, draw distance, etc)&lt;br /&gt;
* Run a saved fgtape recording&lt;br /&gt;
* Record the mean/min/max FPS during this and save it in some text file/copy to the clipboard&lt;br /&gt;
&lt;br /&gt;
So yes, if anyone wants to work on the above, the code is all there. Please jump in and start hacking. I don't think it needs any more from the core code, but as always, please ask if it does.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36975213/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, when describing a /rendering/ test (to establish FPS), the advantage of a replay tape is that the actual position (and, therefore, the rendered scene) will be 100% consistent across different computers.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that the CPU use of the FDM+systems is typically &amp;lt; 10% of our total CPU use, even when running OSG single-threaded, so for a rendering performance test, whether the FD is run or not is probably noise compared to other things that do run (Nasal, Canvas for example)&lt;br /&gt;
&lt;br /&gt;
Also, the Multi-monitor setup is an area that could use additional unit testing. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36904782/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fgdata ==&lt;br /&gt;
=== Nasal scripting (comments) ===&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
The now builtin CppUnit framework can solve all the issues&lt;br /&gt;
identified in the old [[Nasal Unit Testing Framework]] wiki article and the discussions it points to&lt;br /&gt;
and provide the full framework required.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36990615/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have some very simple tests running now for the route manager, which relies on Nasal. We're skipping a few of the bigger Nasal modules (local weather, jetways) and have a few lingering issues in some other modules, but the basic concept is working. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
An exciting further step, which you might wish to discuss with Edward, is writing test checks *in* Nasal since this could be quite a fast way to test some areas of the code. There are several ways that could work, and I don't know if Edward has always planned something around this, so I won't preempt that conversation.&lt;br /&gt;
&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36764781/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
we have route-manager tests which validate route_manager.nas is working correctly, and we have Canavs tests ({{fg src file|path=test_suite/simgear_tests/canvas|}}) which poke the Nasal API. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36991200/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We need more FGData testing via the test suite.&lt;br /&gt;
&lt;br /&gt;
James has suggested adding CppUnit assertions to Nasal so others can write tests in pure Nasal. James would make these changes in C++.  &lt;br /&gt;
In addition, some C++ code in a test would scan a directory for files matching a pattern, e.g., test_XYZ.nas, and run each of those automatically.&lt;br /&gt;
&lt;br /&gt;
The idea for testing Nasal would be that you write a small CppUnit&lt;br /&gt;
interface in C++ in $FG_SRC/test_suite/*_tests/ (the FGData Nasal&lt;br /&gt;
testing would be in a fgdata_tests/ directory). This would register&lt;br /&gt;
each test which points to the script in&lt;br /&gt;
$FG_SRC/test_suite/shared_data/nasal/, and the setUp() and tearDown()&lt;br /&gt;
functions would use helper functions in the fgtest namespace to start&lt;br /&gt;
and stop Nasal. The Nasal scripts could then call the CppUnit&lt;br /&gt;
assertion macros wrapped up as Nasal functions for communicating&lt;br /&gt;
failures and errors to the test suite. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36991150/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Scanning for scripts is a great idea. Then, developers (core and content) could write tests using pure Nasal.&lt;br /&gt;
&lt;br /&gt;
However, all scripts found and executed will be seen as a single test within the test suite. So maybe we should have a $FG_SRC/test_suite/nasal_staging/ directory for the initial development of such auto-scanned scripts. But then we have someone shift them into $FG_SRC/test_suite/system_tests/, $FG_SRC/test_suite/unit_tests/, or $FG_SRC/test_suite/fgdata_tests/ later on?  That would give better diagnostics and would avoid long-term clutter.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36991198/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* First, we should probably hard code tests into the C++ framework. For this, the CppUnit assertion macros will have to be wrapped up as Nasal functions.&lt;br /&gt;
* Implement the scanning code as we need some CMake magic (probably using file(COPY, ...)).&lt;br /&gt;
* Finally, we must determine if and how to improve the Nnasaldebugging output.&lt;br /&gt;
&lt;br /&gt;
the code could go into a subdirectory in $FG_SRC/test_suite/fgdata_tests/, and the Nasal script in $FG_SRC/test_suite/shared_data/nasal/.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Core development]]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=140251</id>
		<title>User:Callahanp</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=140251"/>
		<updated>2024-08-17T17:58:46Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: Weekly Status &amp;amp; Plan&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== This Week ===&lt;br /&gt;
11-Aug-2024 - 17-Aug-2024&lt;br /&gt;
&lt;br /&gt;
* initial commit for flightgear [https://sourceforge.net/p/flightgear/codetickets/2890/ tickets/2890 - Upgrade Mongoose Web Server] &lt;br /&gt;
* plan to refactor MongooseHttpd, MongooseConnection and the Handlers&lt;br /&gt;
* initiate work on test_suite/unit_tests/Network/test_httpd.cxx&lt;br /&gt;
&lt;br /&gt;
19-Aug-2024 - &lt;br /&gt;
&lt;br /&gt;
* Build &amp;amp; run test_suite/unit_tests/Network/test_httpd.cxx&lt;br /&gt;
*&lt;br /&gt;
&lt;br /&gt;
=== Reading List: ===&lt;br /&gt;
&lt;br /&gt;
==== Start With ====&lt;br /&gt;
*[[/cmake.org/getting-started/|https://cmake.org/getting-started/]] -- Build using g++ and clang.&lt;br /&gt;
*[[/learn.microsoft.com/en-us/vcpkg/|https://learn.microsoft.com/en-us/vcpkg/]] -- cross-platform C/C++ package manager&lt;br /&gt;
*[[https://www.jenkins.io/ -- Automation Server&lt;br /&gt;
*[[/www.sourceware.org/gdb/|https://www.sourceware.org/gdb/]] or [[/lldb.llvm.org/|https://lldb.llvm.org/]] -- Debuggers&lt;br /&gt;
*[[/github.com/google/sanitizers|https://github.com/google/sanitizers]] -- Read about each of the available sanitizers&lt;br /&gt;
*[[/valgrind.org/docs/manual/quick-start.html|https://valgrind.org/docs/manual/quick-start.html]] -- A suite of debugging and profiling tools&lt;br /&gt;
*A review of all the options for each tool you want to acquire.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Reading Lists ====&lt;br /&gt;
&lt;br /&gt;
=== Overviews ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Topic !! Overview  !! Options !! Progress !! Notes !!&lt;br /&gt;
|-&lt;br /&gt;
| vcpkg || https://learn.microsoft.com/en-us/vcpkg/  || &lt;br /&gt;
|- &lt;br /&gt;
| apt || https://wiki.debian.org/Apt || &lt;br /&gt;
|- &lt;br /&gt;
| cmake || https://cmake.org/getting-started/ ||&lt;br /&gt;
|-&lt;br /&gt;
| g++ || https://www.gnu.org/software/gcc/ ||&lt;br /&gt;
|-&lt;br /&gt;
| gdb || https://www.sourceware.org/gdb/ ||&lt;br /&gt;
|-&lt;br /&gt;
| llvm || https://llvm.org ||&lt;br /&gt;
|-&lt;br /&gt;
| clang || https://clang.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| lldb || https://lldb.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| valgrind || https://valgrind.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| lcov || https://github.com/linux-test-project/lcov || -DENABLE_COVERAGE=1&lt;br /&gt;
if (ENABLE_COVERAGE)&lt;br /&gt;
  set(CMAKE_BUILD_TYPE &amp;quot;Debug&amp;quot; CACHE STRING&lt;br /&gt;
    &amp;quot;set the build type.&amp;quot; FORCE)&lt;br /&gt;
  include(CodeCoverage.cmake)&lt;br /&gt;
  append_coverage_compiler_flags()&lt;br /&gt;
endif()&lt;br /&gt;
&lt;br /&gt;
add_executable&lt;br /&gt;
target_link_libraries( a.exe  test_a.cpp CPPUnit::CPPUnit&lt;br /&gt;
 if (ENABLE_COVERAGE)&lt;br /&gt;
   setup_target_for_coverage_lcov(&lt;br /&gt;
      NAME coverage&lt;br /&gt;
      EXECUTABLE ${cmake_current_binarey_dir}/test_a&lt;br /&gt;
      LCOV_ARGS --rc lcov_branch_coverage=1&lt;br /&gt;
      GENHTML_ARGS --legend --branch-coveragbe&lt;br /&gt;
      DEPENDENCIES test_a)&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| sanitizers || https://github.com/google/sanitizers&lt;br /&gt;
https://www.cl.cam.ac.uk/~nk480/C1819/lecture5.pdf&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| asan || https://github.com/google/sanitizers/wiki/AddressSanitizer ||gdb &amp;amp; clang:&lt;br /&gt;
CMAKE_CXX_FLAGS -fsanitize=address&lt;br /&gt;
CMAKE_EXE_LINKER_FLAGS -fsanitize=address&lt;br /&gt;
|-&lt;br /&gt;
| msan || https://github.com/google/sanitizers/wiki/MemorySanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| tsan || https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual ||&lt;br /&gt;
|-&lt;br /&gt;
| ubsan || https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html || gdb &amp;amp; clang:&lt;br /&gt;
CMAKE_CXX_FLAGS -fsanitize=undefined&lt;br /&gt;
CMAKE_EXE_LINKER_FLAGS -fsanitize=undefined&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Start With==&lt;br /&gt;
&lt;br /&gt;
*[[/cmake.org/getting-started/|https://cmake.org/getting-started/]] -- Build using g++ and clang.&lt;br /&gt;
*[[/learn.microsoft.com/en-us/vcpkg/|https://learn.microsoft.com/en-us/vcpkg/]] -- cross-platform C/C++ package manager&lt;br /&gt;
*[[/www.sourceware.org/gdb/|https://www.sourceware.org/gdb/]] or [[/lldb.llvm.org/|https://lldb.llvm.org/]] -- Debuggers&lt;br /&gt;
*[[/github.com/google/sanitizers|https://github.com/google/sanitizers]] -- Read about each of the available sanitizers&lt;br /&gt;
*[[/valgrind.org/docs/manual/quick-start.html|https://valgrind.org/docs/manual/quick-start.html]] -- A suite of debugging and profiling tools&lt;br /&gt;
*A review of all the options for each tool you want to acquire.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Reading Lists ==&lt;br /&gt;
&lt;br /&gt;
=== Overviews ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Topic !! Overview  !! Options !! Progress !! Notes !!&lt;br /&gt;
|-&lt;br /&gt;
| vcpkg || https://learn.microsoft.com/en-us/vcpkg/  || &lt;br /&gt;
|- &lt;br /&gt;
| apt || https://wiki.debian.org/Apt || &lt;br /&gt;
|- &lt;br /&gt;
| cmake || https://cmake.org/getting-started/ ||&lt;br /&gt;
|-&lt;br /&gt;
| g++ || https://www.gnu.org/software/gcc/ ||&lt;br /&gt;
|-&lt;br /&gt;
| gdb || https://www.sourceware.org/gdb/ ||&lt;br /&gt;
|-&lt;br /&gt;
| llvm || https://llvm.org ||&lt;br /&gt;
|-&lt;br /&gt;
| clang || https://clang.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| lldb || https://lldb.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| valgrind || https://valgrind.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| sanitizers || https://github.com/google/sanitizers&lt;br /&gt;
https://www.cl.cam.ac.uk/~nk480/C1819/lecture5.pdf&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| asan || https://github.com/google/sanitizers/wiki/AddressSanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| msan || https://github.com/google/sanitizers/wiki/MemorySanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| tsan || https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual ||&lt;br /&gt;
|-&lt;br /&gt;
| ubsan || https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html ||&lt;br /&gt;
 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Start With ====&lt;br /&gt;
*[[/cmake.org/getting-started/|https://cmake.org/getting-started/]] -- Build using g++ and clang.&lt;br /&gt;
*[[/learn.microsoft.com/en-us/vcpkg/|https://learn.microsoft.com/en-us/vcpkg/]] -- cross-platform C/C++ package manager&lt;br /&gt;
*[[/www.sourceware.org/gdb/|https://www.sourceware.org/gdb/]] or [[/lldb.llvm.org/|https://lldb.llvm.org/]] -- Debuggers&lt;br /&gt;
*[[/github.com/google/sanitizers|https://github.com/google/sanitizers]] -- Read about each of the available sanitizers&lt;br /&gt;
*[[/valgrind.org/docs/manual/quick-start.html|https://valgrind.org/docs/manual/quick-start.html]] -- A suite of debugging and profiling tools&lt;br /&gt;
*A review of all the options for each tool you want to acquire.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Reading Lists ====&lt;br /&gt;
&lt;br /&gt;
=== Overviews ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Topic !! Overview  !! Options !! Progress !! Notes !!&lt;br /&gt;
|-&lt;br /&gt;
| vcpkg || https://learn.microsoft.com/en-us/vcpkg/  || &lt;br /&gt;
|- &lt;br /&gt;
| apt || https://wiki.debian.org/Apt || &lt;br /&gt;
|- &lt;br /&gt;
| cmake || https://cmake.org/getting-started/ ||&lt;br /&gt;
|-&lt;br /&gt;
| g++ || https://www.gnu.org/software/gcc/ ||&lt;br /&gt;
|-&lt;br /&gt;
| gdb || https://www.sourceware.org/gdb/ ||&lt;br /&gt;
|-&lt;br /&gt;
| llvm || https://llvm.org ||&lt;br /&gt;
|-&lt;br /&gt;
| clang || https://clang.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| lldb || https://lldb.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| valgrind || https://valgrind.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| sanitizers || https://github.com/google/sanitizers&lt;br /&gt;
https://www.cl.cam.ac.uk/~nk480/C1819/lecture5.pdf&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| asan || https://github.com/google/sanitizers/wiki/AddressSanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| msan || https://github.com/google/sanitizers/wiki/MemorySanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| tsan || https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual ||&lt;br /&gt;
|-&lt;br /&gt;
| ubsan || https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html ||&lt;br /&gt;
 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Integration ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Topic !! Download_and_compile.sh !! dev1&lt;br /&gt;
|-&lt;br /&gt;
| vcpkg ||   || &lt;br /&gt;
|- &lt;br /&gt;
| apt || || &lt;br /&gt;
|- &lt;br /&gt;
| cmake || ||&lt;br /&gt;
|-&lt;br /&gt;
| g++ ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| gdb || ||&lt;br /&gt;
|-&lt;br /&gt;
| llvm ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| clang ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| lldb ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| valgrind ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| sanitizers ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| asan ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| msan ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| tsan || ||&lt;br /&gt;
|-&lt;br /&gt;
| ubsan || ||&lt;br /&gt;
 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Follow-on Questions ====&lt;br /&gt;
* Does g++ support each of these sanitizers?&lt;br /&gt;
* What other tools should I research besides gdb, lldb, valgrind, UBSAN, ASAN, TSAN, and MSAN?&lt;br /&gt;
* Are there tools other than sanitizers and debuggers I should know about?&lt;br /&gt;
* Are there obsolete tools I should ignore?&lt;br /&gt;
* Are there books that cover C++ topics beyond writing C++? How about how-to guides? (I'll be searching for these next, but do you happen to know any particularly useful and easy to read?&lt;br /&gt;
* Crash dumps and crash dump tools. I don't know much about them. What good resources on this topic are there for Linux, Windows, and Mac?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Background ====&lt;br /&gt;
I'm about to start going through the list above for myself. It may take a while.&lt;br /&gt;
&lt;br /&gt;
I'm currently involved in a project with about half a million existing lines of C++ code and want to know what tools I need to work in this environment properly. The application has multi-threaded parts.&lt;br /&gt;
&lt;br /&gt;
I can do basic g++, Debug, DebWithRelInfo, and Release builds using cmake or a pre-defined build script and step through code line-by-line with the gdb in VSCode, but want to become familiar with gdb at the command line.&lt;br /&gt;
&lt;br /&gt;
I want to come up to speed with clang and lldb in vscode.&lt;br /&gt;
&lt;br /&gt;
[[/stackoverflow.com/questions/63978029/setup-lldb-debugging-with-cpp-extension-in-vscode-linux|https://stackoverflow.com/questions/63978029/setup-lldb-debugging-with-cpp-extension-in-vscode-linux]]&lt;br /&gt;
&lt;br /&gt;
== Other Thoughts ==&lt;br /&gt;
&lt;br /&gt;
I need to familiarize myself with other tools available, learn how to enable particular tools in a build, and learn how to use the tool's output.&lt;br /&gt;
&lt;br /&gt;
I want to learn to use tools like UBSAN, ASAN, TSAN, and MSAN effectively and how to switch from g++ to clang when appropriate. I want to learn what tools other than the sanitizers and debuggers above are available.&lt;br /&gt;
&lt;br /&gt;
There's no such thing as free beer! Someone pays for flightgear cloud infrastructure that I personallly benefit from.  So I contribute a little at:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;https://liberapay.com/t3r&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Currently working on:&lt;br /&gt;
&lt;br /&gt;
Git Worktrees with download_and_compile.sh  (done &amp;amp; working)&lt;br /&gt;
&lt;br /&gt;
Web Socket Refactor &amp;amp; Fix.  &lt;br /&gt;
&lt;br /&gt;
OSM (Open Street Map) Scenery Build (on hold)&lt;br /&gt;
&lt;br /&gt;
Goals (Maybe)&lt;br /&gt;
&lt;br /&gt;
*Download Scenery from Current Scenery Developers&lt;br /&gt;
*Build Scripts for Scenery Land Class, Elevation, and OSM processing&lt;br /&gt;
*Understand the underlying formats in Flightgear Scenery&lt;br /&gt;
*Understand the processing of Scenery data between tiles in the build process and the running simulator&lt;br /&gt;
*Assist Scenery Developers with technical support.&lt;br /&gt;
*full explanation of the advantages and disadvantages of the worktree approach.&lt;br /&gt;
&lt;br /&gt;
[[Hackathon Proposal: Property Subscription Improvements|Hackathon-2023-Proposal-Websocket-Property-Subscription-Improvements]]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=139918</id>
		<title>User:Callahanp</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=139918"/>
		<updated>2024-06-06T13:59:59Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: /* Overviews */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
==Start With==&lt;br /&gt;
&lt;br /&gt;
*[[/cmake.org/getting-started/|https://cmake.org/getting-started/]] -- Build using g++ and clang.&lt;br /&gt;
*[[/learn.microsoft.com/en-us/vcpkg/|https://learn.microsoft.com/en-us/vcpkg/]] -- cross-platform C/C++ package manager&lt;br /&gt;
*[[https://www.jenkins.io/ -- Automation Server&lt;br /&gt;
*[[/www.sourceware.org/gdb/|https://www.sourceware.org/gdb/]] or [[/lldb.llvm.org/|https://lldb.llvm.org/]] -- Debuggers&lt;br /&gt;
*[[/github.com/google/sanitizers|https://github.com/google/sanitizers]] -- Read about each of the available sanitizers&lt;br /&gt;
*[[/valgrind.org/docs/manual/quick-start.html|https://valgrind.org/docs/manual/quick-start.html]] -- A suite of debugging and profiling tools&lt;br /&gt;
*A review of all the options for each tool you want to acquire.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Reading Lists ==&lt;br /&gt;
&lt;br /&gt;
=== Overviews ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Topic !! Overview  !! Options !! Progress !! Notes !!&lt;br /&gt;
|-&lt;br /&gt;
| vcpkg || https://learn.microsoft.com/en-us/vcpkg/  || &lt;br /&gt;
|- &lt;br /&gt;
| apt || https://wiki.debian.org/Apt || &lt;br /&gt;
|- &lt;br /&gt;
| cmake || https://cmake.org/getting-started/ ||&lt;br /&gt;
|-&lt;br /&gt;
| g++ || https://www.gnu.org/software/gcc/ ||&lt;br /&gt;
|-&lt;br /&gt;
| gdb || https://www.sourceware.org/gdb/ ||&lt;br /&gt;
|-&lt;br /&gt;
| llvm || https://llvm.org ||&lt;br /&gt;
|-&lt;br /&gt;
| clang || https://clang.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| lldb || https://lldb.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| valgrind || https://valgrind.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| lcov || https://github.com/linux-test-project/lcov || -DENABLE_COVERAGE=1&lt;br /&gt;
if (ENABLE_COVERAGE)&lt;br /&gt;
  set(CMAKE_BUILD_TYPE &amp;quot;Debug&amp;quot; CACHE STRING&lt;br /&gt;
    &amp;quot;set the build type.&amp;quot; FORCE)&lt;br /&gt;
  include(CodeCoverage.cmake)&lt;br /&gt;
  append_coverage_compiler_flags()&lt;br /&gt;
endif()&lt;br /&gt;
&lt;br /&gt;
add_executable&lt;br /&gt;
target_link_libraries( a.exe  test_a.cpp CPPUnit::CPPUnit&lt;br /&gt;
 if (ENABLE_COVERAGE)&lt;br /&gt;
   setup_target_for_coverage_lcov(&lt;br /&gt;
      NAME coverage&lt;br /&gt;
      EXECUTABLE ${cmake_current_binarey_dir}/test_a&lt;br /&gt;
      LCOV_ARGS --rc lcov_branch_coverage=1&lt;br /&gt;
      GENHTML_ARGS --legend --branch-coveragbe&lt;br /&gt;
      DEPENDENCIES test_a)&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| sanitizers || https://github.com/google/sanitizers&lt;br /&gt;
https://www.cl.cam.ac.uk/~nk480/C1819/lecture5.pdf&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| asan || https://github.com/google/sanitizers/wiki/AddressSanitizer ||gdb &amp;amp; clang:&lt;br /&gt;
CMAKE_CXX_FLAGS -fsanitize=address&lt;br /&gt;
CMAKE_EXE_LINKER_FLAGS -fsanitize=address&lt;br /&gt;
|-&lt;br /&gt;
| msan || https://github.com/google/sanitizers/wiki/MemorySanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| tsan || https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual ||&lt;br /&gt;
|-&lt;br /&gt;
| ubsan || https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html || gdb &amp;amp; clang:&lt;br /&gt;
CMAKE_CXX_FLAGS -fsanitize=undefined&lt;br /&gt;
CMAKE_EXE_LINKER_FLAGS -fsanitize=undefined&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Start With==&lt;br /&gt;
&lt;br /&gt;
*[[/cmake.org/getting-started/|https://cmake.org/getting-started/]] -- Build using g++ and clang.&lt;br /&gt;
*[[/learn.microsoft.com/en-us/vcpkg/|https://learn.microsoft.com/en-us/vcpkg/]] -- cross-platform C/C++ package manager&lt;br /&gt;
*[[/www.sourceware.org/gdb/|https://www.sourceware.org/gdb/]] or [[/lldb.llvm.org/|https://lldb.llvm.org/]] -- Debuggers&lt;br /&gt;
*[[/github.com/google/sanitizers|https://github.com/google/sanitizers]] -- Read about each of the available sanitizers&lt;br /&gt;
*[[/valgrind.org/docs/manual/quick-start.html|https://valgrind.org/docs/manual/quick-start.html]] -- A suite of debugging and profiling tools&lt;br /&gt;
*A review of all the options for each tool you want to acquire.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Reading Lists ==&lt;br /&gt;
&lt;br /&gt;
=== Overviews ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Topic !! Overview  !! Options !! Progress !! Notes !!&lt;br /&gt;
|-&lt;br /&gt;
| vcpkg || https://learn.microsoft.com/en-us/vcpkg/  || &lt;br /&gt;
|- &lt;br /&gt;
| apt || https://wiki.debian.org/Apt || &lt;br /&gt;
|- &lt;br /&gt;
| cmake || https://cmake.org/getting-started/ ||&lt;br /&gt;
|-&lt;br /&gt;
| g++ || https://www.gnu.org/software/gcc/ ||&lt;br /&gt;
|-&lt;br /&gt;
| gdb || https://www.sourceware.org/gdb/ ||&lt;br /&gt;
|-&lt;br /&gt;
| llvm || https://llvm.org ||&lt;br /&gt;
|-&lt;br /&gt;
| clang || https://clang.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| lldb || https://lldb.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| valgrind || https://valgrind.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| sanitizers || https://github.com/google/sanitizers&lt;br /&gt;
https://www.cl.cam.ac.uk/~nk480/C1819/lecture5.pdf&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| asan || https://github.com/google/sanitizers/wiki/AddressSanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| msan || https://github.com/google/sanitizers/wiki/MemorySanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| tsan || https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual ||&lt;br /&gt;
|-&lt;br /&gt;
| ubsan || https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html ||&lt;br /&gt;
 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Start With==&lt;br /&gt;
&lt;br /&gt;
*[[/cmake.org/getting-started/|https://cmake.org/getting-started/]] -- Build using g++ and clang.&lt;br /&gt;
*[[/learn.microsoft.com/en-us/vcpkg/|https://learn.microsoft.com/en-us/vcpkg/]] -- cross-platform C/C++ package manager&lt;br /&gt;
*[[/www.sourceware.org/gdb/|https://www.sourceware.org/gdb/]] or [[/lldb.llvm.org/|https://lldb.llvm.org/]] -- Debuggers&lt;br /&gt;
*[[/github.com/google/sanitizers|https://github.com/google/sanitizers]] -- Read about each of the available sanitizers&lt;br /&gt;
*[[/valgrind.org/docs/manual/quick-start.html|https://valgrind.org/docs/manual/quick-start.html]] -- A suite of debugging and profiling tools&lt;br /&gt;
*A review of all the options for each tool you want to acquire.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Reading Lists ==&lt;br /&gt;
&lt;br /&gt;
=== Overviews ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Topic !! Overview  !! Options !! Progress !! Notes !!&lt;br /&gt;
|-&lt;br /&gt;
| vcpkg || https://learn.microsoft.com/en-us/vcpkg/  || &lt;br /&gt;
|- &lt;br /&gt;
| apt || https://wiki.debian.org/Apt || &lt;br /&gt;
|- &lt;br /&gt;
| cmake || https://cmake.org/getting-started/ ||&lt;br /&gt;
|-&lt;br /&gt;
| g++ || https://www.gnu.org/software/gcc/ ||&lt;br /&gt;
|-&lt;br /&gt;
| gdb || https://www.sourceware.org/gdb/ ||&lt;br /&gt;
|-&lt;br /&gt;
| llvm || https://llvm.org ||&lt;br /&gt;
|-&lt;br /&gt;
| clang || https://clang.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| lldb || https://lldb.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| valgrind || https://valgrind.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| sanitizers || https://github.com/google/sanitizers&lt;br /&gt;
https://www.cl.cam.ac.uk/~nk480/C1819/lecture5.pdf&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| asan || https://github.com/google/sanitizers/wiki/AddressSanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| msan || https://github.com/google/sanitizers/wiki/MemorySanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| tsan || https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual ||&lt;br /&gt;
|-&lt;br /&gt;
| ubsan || https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html ||&lt;br /&gt;
 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Integration ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Topic !! Download_and_compile.sh !! dev1&lt;br /&gt;
|-&lt;br /&gt;
| vcpkg ||   || &lt;br /&gt;
|- &lt;br /&gt;
| apt || || &lt;br /&gt;
|- &lt;br /&gt;
| cmake || ||&lt;br /&gt;
|-&lt;br /&gt;
| g++ ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| gdb || ||&lt;br /&gt;
|-&lt;br /&gt;
| llvm ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| clang ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| lldb ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| valgrind ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| sanitizers ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| asan ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| msan ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| tsan || ||&lt;br /&gt;
|-&lt;br /&gt;
| ubsan || ||&lt;br /&gt;
 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Follow-on Questions==&lt;br /&gt;
&lt;br /&gt;
* Does g++ support each of these sanitizers?&lt;br /&gt;
* What other tools should I research besides gdb, lldb, valgrind, UBSAN, ASAN, TSAN, and MSAN?&lt;br /&gt;
* Are there tools other than sanitizers and debuggers I should know about?&lt;br /&gt;
* Are there obsolete tools I should ignore?&lt;br /&gt;
* Are there books that cover C++ topics beyond writing C++? How about how-to guides? (I'll be searching for these next, but do you happen to know any particularly useful and easy to read?&lt;br /&gt;
* Crash dumps and crash dump tools. I don't know much about them. What good resources on this topic are there for Linux, Windows, and Mac?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
I'm about to start going through the list above for myself. It may take a while.&lt;br /&gt;
&lt;br /&gt;
I'm currently involved in a project with about half a million existing lines of C++ code and want to know what tools I need to work in this environment properly. The application has multi-threaded parts.&lt;br /&gt;
&lt;br /&gt;
I can do basic g++, Debug, DebWithRelInfo, and Release builds using cmake or a pre-defined build script and step through code line-by-line with the gdb in VSCode, but want to become familiar with gdb at the command line.&lt;br /&gt;
&lt;br /&gt;
I want to come up to speed with clang and lldb in vscode.&lt;br /&gt;
&lt;br /&gt;
[[/stackoverflow.com/questions/63978029/setup-lldb-debugging-with-cpp-extension-in-vscode-linux|https://stackoverflow.com/questions/63978029/setup-lldb-debugging-with-cpp-extension-in-vscode-linux]]&lt;br /&gt;
&lt;br /&gt;
== Other Thoughts ==&lt;br /&gt;
&lt;br /&gt;
I need to familiarize myself with other tools available, learn how to enable particular tools in a build, and learn how to use the tool's output.&lt;br /&gt;
&lt;br /&gt;
I want to learn to use tools like UBSAN, ASAN, TSAN, and MSAN effectively and how to switch from g++ to clang when appropriate. I want to learn what tools other than the sanitizers and debuggers above are available.&lt;br /&gt;
&lt;br /&gt;
There's no such thing as free beer! Someone pays for flightgear cloud infrastructure that I personallly benefit from.  So I contribute a little at:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;https://liberapay.com/t3r&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Currently working on:&lt;br /&gt;
&lt;br /&gt;
Git Worktrees with download_and_compile.sh  (done &amp;amp; working)&lt;br /&gt;
&lt;br /&gt;
Web Socket Refactor &amp;amp; Fix.  &lt;br /&gt;
&lt;br /&gt;
OSM (Open Street Map) Scenery Build (on hold)&lt;br /&gt;
&lt;br /&gt;
Goals (Maybe)&lt;br /&gt;
&lt;br /&gt;
*Download Scenery from Current Scenery Developers&lt;br /&gt;
*Build Scripts for Scenery Land Class, Elevation, and OSM processing&lt;br /&gt;
*Understand the underlying formats in Flightgear Scenery&lt;br /&gt;
*Understand the processing of Scenery data between tiles in the build process and the running simulator&lt;br /&gt;
*Assist Scenery Developers with technical support.&lt;br /&gt;
*full explanation of the advantages and disadvantages of the worktree approach.&lt;br /&gt;
&lt;br /&gt;
[[Hackathon Proposal: Property Subscription Improvements|Hackathon-2023-Proposal-Websocket-Property-Subscription-Improvements]]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=139917</id>
		<title>User:Callahanp</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=139917"/>
		<updated>2024-06-06T13:59:33Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
==Start With==&lt;br /&gt;
&lt;br /&gt;
*[[/cmake.org/getting-started/|https://cmake.org/getting-started/]] -- Build using g++ and clang.&lt;br /&gt;
*[[/learn.microsoft.com/en-us/vcpkg/|https://learn.microsoft.com/en-us/vcpkg/]] -- cross-platform C/C++ package manager&lt;br /&gt;
*[[https://www.jenkins.io/ -- Automation Server&lt;br /&gt;
*[[/www.sourceware.org/gdb/|https://www.sourceware.org/gdb/]] or [[/lldb.llvm.org/|https://lldb.llvm.org/]] -- Debuggers&lt;br /&gt;
*[[/github.com/google/sanitizers|https://github.com/google/sanitizers]] -- Read about each of the available sanitizers&lt;br /&gt;
*[[/valgrind.org/docs/manual/quick-start.html|https://valgrind.org/docs/manual/quick-start.html]] -- A suite of debugging and profiling tools&lt;br /&gt;
*A review of all the options for each tool you want to acquire.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Reading Lists ==&lt;br /&gt;
&lt;br /&gt;
=== Overviews ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Topic !! Overview  !! Options !! Progress !! Notes !!&lt;br /&gt;
|-&lt;br /&gt;
| vcpkg || https://learn.microsoft.com/en-us/vcpkg/  || &lt;br /&gt;
|- &lt;br /&gt;
| apt || https://wiki.debian.org/Apt || &lt;br /&gt;
|- &lt;br /&gt;
| cmake || https://cmake.org/getting-started/ ||&lt;br /&gt;
|-&lt;br /&gt;
| g++ || https://www.gnu.org/software/gcc/ ||&lt;br /&gt;
|-&lt;br /&gt;
| gdb || https://www.sourceware.org/gdb/ ||&lt;br /&gt;
|-&lt;br /&gt;
| llvm || https://llvm.org ||&lt;br /&gt;
|-&lt;br /&gt;
| clang || https://clang.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| lldb || https://lldb.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| valgrind || https://valgrind.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| lcov || https://github.com/linux-test-project/lcov || -DENABLE_COVERAGE=1&lt;br /&gt;
if (ENABLE_COVERAGE)&lt;br /&gt;
  set(CMAKE_BUILD_TYPE &amp;quot;Debug&amp;quot; CACHE STRING&lt;br /&gt;
    &amp;quot;set the build type.&amp;quot; FORCE)&lt;br /&gt;
  include(CodeCoverage.cmake)&lt;br /&gt;
  append_coverage_compiler_flags()&lt;br /&gt;
endif()&lt;br /&gt;
&lt;br /&gt;
add_executable&lt;br /&gt;
target_link_libraries( a.exe  test_a.cpp CPPUnit::CPPUnit&lt;br /&gt;
 if (ENABLE_COVERAGE)&lt;br /&gt;
   setup_target_for_coverage_lcov(&lt;br /&gt;
      NAME coverage&lt;br /&gt;
      EXECUTABLE ${cmake_current_binarey_dir}/test_a&lt;br /&gt;
      LCOV_ARGS --rc lcov_branch_coverage=1&lt;br /&gt;
      GENHTML_ARGS --legend --branch-coveragbe&lt;br /&gt;
      DEPENDENCIES test_a)&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| sanitizers || https://github.com/google/sanitizers&lt;br /&gt;
https://www.cl.cam.ac.uk/~nk480/C1819/lecture5.pdf&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| asan || https://github.com/google/sanitizers/wiki/AddressSanitizer ||gdb &amp;amp; clang:&lt;br /&gt;
CMAKE_CXX_FLAGS -fsanitize=address&lt;br /&gt;
CMAKE_EXE_LINKER_FLAGS -fsanitize=address&lt;br /&gt;
|-&lt;br /&gt;
| msan || https://github.com/google/sanitizers/wiki/MemorySanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| tsan || https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual ||&lt;br /&gt;
|-&lt;br /&gt;
| ubsan || https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html || gdb &amp;amp; clang:&lt;br /&gt;
CMAKE_CXX_FLAGS -fsanitize=undefined&lt;br /&gt;
CMAKE_EXE_LINKER_FLAGS -fsanitize=undefined&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Start With==&lt;br /&gt;
&lt;br /&gt;
*[[/cmake.org/getting-started/|https://cmake.org/getting-started/]] -- Build using g++ and clang.&lt;br /&gt;
*[[/learn.microsoft.com/en-us/vcpkg/|https://learn.microsoft.com/en-us/vcpkg/]] -- cross-platform C/C++ package manager&lt;br /&gt;
*[[/www.sourceware.org/gdb/|https://www.sourceware.org/gdb/]] or [[/lldb.llvm.org/|https://lldb.llvm.org/]] -- Debuggers&lt;br /&gt;
*[[/github.com/google/sanitizers|https://github.com/google/sanitizers]] -- Read about each of the available sanitizers&lt;br /&gt;
*[[/valgrind.org/docs/manual/quick-start.html|https://valgrind.org/docs/manual/quick-start.html]] -- A suite of debugging and profiling tools&lt;br /&gt;
*A review of all the options for each tool you want to acquire.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Reading Lists ==&lt;br /&gt;
&lt;br /&gt;
=== Overviews ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Topic !! Overview  !! Options !! Progress !! Notes !!&lt;br /&gt;
|-&lt;br /&gt;
| vcpkg || https://learn.microsoft.com/en-us/vcpkg/  || &lt;br /&gt;
|- &lt;br /&gt;
| apt || https://wiki.debian.org/Apt || &lt;br /&gt;
|- &lt;br /&gt;
| cmake || https://cmake.org/getting-started/ ||&lt;br /&gt;
|-&lt;br /&gt;
| g++ || https://www.gnu.org/software/gcc/ ||&lt;br /&gt;
|-&lt;br /&gt;
| gdb || https://www.sourceware.org/gdb/ ||&lt;br /&gt;
|-&lt;br /&gt;
| llvm || llvm.org ||&lt;br /&gt;
|-&lt;br /&gt;
| clang || https://clang.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| lldb || https://lldb.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| valgrind || https://valgrind.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| sanitizers || https://github.com/google/sanitizers&lt;br /&gt;
https://www.cl.cam.ac.uk/~nk480/C1819/lecture5.pdf&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| asan || https://github.com/google/sanitizers/wiki/AddressSanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| msan || https://github.com/google/sanitizers/wiki/MemorySanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| tsan || https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual ||&lt;br /&gt;
|-&lt;br /&gt;
| ubsan || https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html ||&lt;br /&gt;
 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Start With==&lt;br /&gt;
&lt;br /&gt;
*[[/cmake.org/getting-started/|https://cmake.org/getting-started/]] -- Build using g++ and clang.&lt;br /&gt;
*[[/learn.microsoft.com/en-us/vcpkg/|https://learn.microsoft.com/en-us/vcpkg/]] -- cross-platform C/C++ package manager&lt;br /&gt;
*[[/www.sourceware.org/gdb/|https://www.sourceware.org/gdb/]] or [[/lldb.llvm.org/|https://lldb.llvm.org/]] -- Debuggers&lt;br /&gt;
*[[/github.com/google/sanitizers|https://github.com/google/sanitizers]] -- Read about each of the available sanitizers&lt;br /&gt;
*[[/valgrind.org/docs/manual/quick-start.html|https://valgrind.org/docs/manual/quick-start.html]] -- A suite of debugging and profiling tools&lt;br /&gt;
*A review of all the options for each tool you want to acquire.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Reading Lists ==&lt;br /&gt;
&lt;br /&gt;
=== Overviews ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Topic !! Overview  !! Options !! Progress !! Notes !!&lt;br /&gt;
|-&lt;br /&gt;
| vcpkg || https://learn.microsoft.com/en-us/vcpkg/  || &lt;br /&gt;
|- &lt;br /&gt;
| apt || https://wiki.debian.org/Apt || &lt;br /&gt;
|- &lt;br /&gt;
| cmake || https://cmake.org/getting-started/ ||&lt;br /&gt;
|-&lt;br /&gt;
| g++ || https://www.gnu.org/software/gcc/ ||&lt;br /&gt;
|-&lt;br /&gt;
| gdb || https://www.sourceware.org/gdb/ ||&lt;br /&gt;
|-&lt;br /&gt;
| llvm || https://llvm.org ||&lt;br /&gt;
|-&lt;br /&gt;
| clang || https://clang.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| lldb || https://lldb.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| valgrind || https://valgrind.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| sanitizers || https://github.com/google/sanitizers&lt;br /&gt;
https://www.cl.cam.ac.uk/~nk480/C1819/lecture5.pdf&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| asan || https://github.com/google/sanitizers/wiki/AddressSanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| msan || https://github.com/google/sanitizers/wiki/MemorySanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| tsan || https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual ||&lt;br /&gt;
|-&lt;br /&gt;
| ubsan || https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html ||&lt;br /&gt;
 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Integration ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Topic !! Download_and_compile.sh !! dev1&lt;br /&gt;
|-&lt;br /&gt;
| vcpkg ||   || &lt;br /&gt;
|- &lt;br /&gt;
| apt || || &lt;br /&gt;
|- &lt;br /&gt;
| cmake || ||&lt;br /&gt;
|-&lt;br /&gt;
| g++ ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| gdb || ||&lt;br /&gt;
|-&lt;br /&gt;
| llvm ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| clang ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| lldb ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| valgrind ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| sanitizers ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| asan ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| msan ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| tsan || ||&lt;br /&gt;
|-&lt;br /&gt;
| ubsan || ||&lt;br /&gt;
 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Follow-on Questions==&lt;br /&gt;
&lt;br /&gt;
* Does g++ support each of these sanitizers?&lt;br /&gt;
* What other tools should I research besides gdb, lldb, valgrind, UBSAN, ASAN, TSAN, and MSAN?&lt;br /&gt;
* Are there tools other than sanitizers and debuggers I should know about?&lt;br /&gt;
* Are there obsolete tools I should ignore?&lt;br /&gt;
* Are there books that cover C++ topics beyond writing C++? How about how-to guides? (I'll be searching for these next, but do you happen to know any particularly useful and easy to read?&lt;br /&gt;
* Crash dumps and crash dump tools. I don't know much about them. What good resources on this topic are there for Linux, Windows, and Mac?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
I'm about to start going through the list above for myself. It may take a while.&lt;br /&gt;
&lt;br /&gt;
I'm currently involved in a project with about half a million existing lines of C++ code and want to know what tools I need to work in this environment properly. The application has multi-threaded parts.&lt;br /&gt;
&lt;br /&gt;
I can do basic g++, Debug, DebWithRelInfo, and Release builds using cmake or a pre-defined build script and step through code line-by-line with the gdb in VSCode, but want to become familiar with gdb at the command line.&lt;br /&gt;
&lt;br /&gt;
I want to come up to speed with clang and lldb in vscode.&lt;br /&gt;
&lt;br /&gt;
[[/stackoverflow.com/questions/63978029/setup-lldb-debugging-with-cpp-extension-in-vscode-linux|https://stackoverflow.com/questions/63978029/setup-lldb-debugging-with-cpp-extension-in-vscode-linux]]&lt;br /&gt;
&lt;br /&gt;
== Other Thoughts ==&lt;br /&gt;
&lt;br /&gt;
I need to familiarize myself with other tools available, learn how to enable particular tools in a build, and learn how to use the tool's output.&lt;br /&gt;
&lt;br /&gt;
I want to learn to use tools like UBSAN, ASAN, TSAN, and MSAN effectively and how to switch from g++ to clang when appropriate. I want to learn what tools other than the sanitizers and debuggers above are available.&lt;br /&gt;
&lt;br /&gt;
There's no such thing as free beer! Someone pays for flightgear cloud infrastructure that I personallly benefit from.  So I contribute a little at:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;https://liberapay.com/t3r&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Currently working on:&lt;br /&gt;
&lt;br /&gt;
Git Worktrees with download_and_compile.sh  (done &amp;amp; working)&lt;br /&gt;
&lt;br /&gt;
Web Socket Refactor &amp;amp; Fix.  &lt;br /&gt;
&lt;br /&gt;
OSM (Open Street Map) Scenery Build (on hold)&lt;br /&gt;
&lt;br /&gt;
Goals (Maybe)&lt;br /&gt;
&lt;br /&gt;
*Download Scenery from Current Scenery Developers&lt;br /&gt;
*Build Scripts for Scenery Land Class, Elevation, and OSM processing&lt;br /&gt;
*Understand the underlying formats in Flightgear Scenery&lt;br /&gt;
*Understand the processing of Scenery data between tiles in the build process and the running simulator&lt;br /&gt;
*Assist Scenery Developers with technical support.&lt;br /&gt;
*full explanation of the advantages and disadvantages of the worktree approach.&lt;br /&gt;
&lt;br /&gt;
[[Hackathon Proposal: Property Subscription Improvements|Hackathon-2023-Proposal-Websocket-Property-Subscription-Improvements]]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=139916</id>
		<title>User:Callahanp</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=139916"/>
		<updated>2024-06-06T13:58:47Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: /* Overviews */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
==Start With==&lt;br /&gt;
&lt;br /&gt;
*[[/cmake.org/getting-started/|https://cmake.org/getting-started/]] -- Build using g++ and clang.&lt;br /&gt;
*[[/learn.microsoft.com/en-us/vcpkg/|https://learn.microsoft.com/en-us/vcpkg/]] -- cross-platform C/C++ package manager&lt;br /&gt;
*[[https://www.jenkins.io/ -- Automation Server&lt;br /&gt;
*[[/www.sourceware.org/gdb/|https://www.sourceware.org/gdb/]] or [[/lldb.llvm.org/|https://lldb.llvm.org/]] -- Debuggers&lt;br /&gt;
*[[/github.com/google/sanitizers|https://github.com/google/sanitizers]] -- Read about each of the available sanitizers&lt;br /&gt;
*[[/valgrind.org/docs/manual/quick-start.html|https://valgrind.org/docs/manual/quick-start.html]] -- A suite of debugging and profiling tools&lt;br /&gt;
*A review of all the options for each tool you want to acquire.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Reading Lists ==&lt;br /&gt;
&lt;br /&gt;
=== Overviews ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Topic !! Overview  !! Options !! Progress !! Notes !!&lt;br /&gt;
|-&lt;br /&gt;
| vcpkg || https://learn.microsoft.com/en-us/vcpkg/  || &lt;br /&gt;
|- &lt;br /&gt;
| apt || https://wiki.debian.org/Apt || &lt;br /&gt;
|- &lt;br /&gt;
| cmake || https://cmake.org/getting-started/ ||&lt;br /&gt;
|-&lt;br /&gt;
| g++ || https://www.gnu.org/software/gcc/ ||&lt;br /&gt;
|-&lt;br /&gt;
| gdb || https://www.sourceware.org/gdb/ ||&lt;br /&gt;
|-&lt;br /&gt;
| llvm || &amp;lt;nowiki&amp;gt;https://llvm.org&amp;lt;/nowiki&amp;gt; ||&lt;br /&gt;
|-&lt;br /&gt;
| clang || https://clang.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| lldb || https://lldb.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| valgrind || https://valgrind.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| lcov || https://github.com/linux-test-project/lcov || -DENABLE_COVERAGE=1&lt;br /&gt;
if (ENABLE_COVERAGE)&lt;br /&gt;
  set(CMAKE_BUILD_TYPE &amp;quot;Debug&amp;quot; CACHE STRING&lt;br /&gt;
    &amp;quot;set the build type.&amp;quot; FORCE)&lt;br /&gt;
  include(CodeCoverage.cmake)&lt;br /&gt;
  append_coverage_compiler_flags()&lt;br /&gt;
endif()&lt;br /&gt;
&lt;br /&gt;
add_executable&lt;br /&gt;
target_link_libraries( a.exe  test_a.cpp CPPUnit::CPPUnit&lt;br /&gt;
 if (ENABLE_COVERAGE)&lt;br /&gt;
   setup_target_for_coverage_lcov(&lt;br /&gt;
      NAME coverage&lt;br /&gt;
      EXECUTABLE ${cmake_current_binarey_dir}/test_a&lt;br /&gt;
      LCOV_ARGS --rc lcov_branch_coverage=1&lt;br /&gt;
      GENHTML_ARGS --legend --branch-coveragbe&lt;br /&gt;
      DEPENDENCIES test_a)&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| sanitizers || https://github.com/google/sanitizers&lt;br /&gt;
https://www.cl.cam.ac.uk/~nk480/C1819/lecture5.pdf&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| asan || https://github.com/google/sanitizers/wiki/AddressSanitizer ||gdb &amp;amp; clang:&lt;br /&gt;
CMAKE_CXX_FLAGS -fsanitize=address&lt;br /&gt;
CMAKE_EXE_LINKER_FLAGS -fsanitize=address&lt;br /&gt;
|-&lt;br /&gt;
| msan || https://github.com/google/sanitizers/wiki/MemorySanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| tsan || https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual ||&lt;br /&gt;
|-&lt;br /&gt;
| ubsan || https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html || gdb &amp;amp; clang:&lt;br /&gt;
CMAKE_CXX_FLAGS -fsanitize=undefined&lt;br /&gt;
CMAKE_EXE_LINKER_FLAGS -fsanitize=undefined&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Start With==&lt;br /&gt;
&lt;br /&gt;
*[[/cmake.org/getting-started/|https://cmake.org/getting-started/]] -- Build using g++ and clang.&lt;br /&gt;
*[[/learn.microsoft.com/en-us/vcpkg/|https://learn.microsoft.com/en-us/vcpkg/]] -- cross-platform C/C++ package manager&lt;br /&gt;
*[[/www.sourceware.org/gdb/|https://www.sourceware.org/gdb/]] or [[/lldb.llvm.org/|https://lldb.llvm.org/]] -- Debuggers&lt;br /&gt;
*[[/github.com/google/sanitizers|https://github.com/google/sanitizers]] -- Read about each of the available sanitizers&lt;br /&gt;
*[[/valgrind.org/docs/manual/quick-start.html|https://valgrind.org/docs/manual/quick-start.html]] -- A suite of debugging and profiling tools&lt;br /&gt;
*A review of all the options for each tool you want to acquire.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Reading Lists ==&lt;br /&gt;
&lt;br /&gt;
=== Overviews ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Topic !! Overview  !! Options !! Progress !! Notes !!&lt;br /&gt;
|-&lt;br /&gt;
| vcpkg || https://learn.microsoft.com/en-us/vcpkg/  || &lt;br /&gt;
|- &lt;br /&gt;
| apt || https://wiki.debian.org/Apt || &lt;br /&gt;
|- &lt;br /&gt;
| cmake || https://cmake.org/getting-started/ ||&lt;br /&gt;
|-&lt;br /&gt;
| g++ || https://www.gnu.org/software/gcc/ ||&lt;br /&gt;
|-&lt;br /&gt;
| gdb || https://www.sourceware.org/gdb/ ||&lt;br /&gt;
|-&lt;br /&gt;
| llvm || llvm.org ||&lt;br /&gt;
|-&lt;br /&gt;
| clang || https://clang.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| lldb || https://lldb.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| valgrind || https://valgrind.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| sanitizers || https://github.com/google/sanitizers&lt;br /&gt;
https://www.cl.cam.ac.uk/~nk480/C1819/lecture5.pdf&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| asan || https://github.com/google/sanitizers/wiki/AddressSanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| msan || https://github.com/google/sanitizers/wiki/MemorySanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| tsan || https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual ||&lt;br /&gt;
|-&lt;br /&gt;
| ubsan || https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html ||&lt;br /&gt;
 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Start With==&lt;br /&gt;
&lt;br /&gt;
*[[/cmake.org/getting-started/|https://cmake.org/getting-started/]] -- Build using g++ and clang.&lt;br /&gt;
*[[/learn.microsoft.com/en-us/vcpkg/|https://learn.microsoft.com/en-us/vcpkg/]] -- cross-platform C/C++ package manager&lt;br /&gt;
*[[/www.sourceware.org/gdb/|https://www.sourceware.org/gdb/]] or [[/lldb.llvm.org/|https://lldb.llvm.org/]] -- Debuggers&lt;br /&gt;
*[[/github.com/google/sanitizers|https://github.com/google/sanitizers]] -- Read about each of the available sanitizers&lt;br /&gt;
*[[/valgrind.org/docs/manual/quick-start.html|https://valgrind.org/docs/manual/quick-start.html]] -- A suite of debugging and profiling tools&lt;br /&gt;
*A review of all the options for each tool you want to acquire.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Reading Lists ==&lt;br /&gt;
&lt;br /&gt;
=== Overviews ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Topic !! Overview  !! Options !! Progress !! Notes !!&lt;br /&gt;
|-&lt;br /&gt;
| vcpkg || https://learn.microsoft.com/en-us/vcpkg/  || &lt;br /&gt;
|- &lt;br /&gt;
| apt || https://wiki.debian.org/Apt || &lt;br /&gt;
|- &lt;br /&gt;
| cmake || https://cmake.org/getting-started/ ||&lt;br /&gt;
|-&lt;br /&gt;
| g++ || https://www.gnu.org/software/gcc/ ||&lt;br /&gt;
|-&lt;br /&gt;
| gdb || https://www.sourceware.org/gdb/ ||&lt;br /&gt;
|-&lt;br /&gt;
| llvm || https://llvm.org ||&lt;br /&gt;
|-&lt;br /&gt;
| clang || https://clang.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| lldb || https://lldb.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| valgrind || https://valgrind.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| sanitizers || https://github.com/google/sanitizers&lt;br /&gt;
https://www.cl.cam.ac.uk/~nk480/C1819/lecture5.pdf&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| asan || https://github.com/google/sanitizers/wiki/AddressSanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| msan || https://github.com/google/sanitizers/wiki/MemorySanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| tsan || https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual ||&lt;br /&gt;
|-&lt;br /&gt;
| ubsan || https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html ||&lt;br /&gt;
 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Integration ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Topic !! Download_and_compile.sh !! dev1&lt;br /&gt;
|-&lt;br /&gt;
| vcpkg ||   || &lt;br /&gt;
|- &lt;br /&gt;
| apt || || &lt;br /&gt;
|- &lt;br /&gt;
| cmake || ||&lt;br /&gt;
|-&lt;br /&gt;
| g++ ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| gdb || ||&lt;br /&gt;
|-&lt;br /&gt;
| llvm ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| clang ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| lldb ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| valgrind ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| sanitizers ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| asan ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| msan ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| tsan || ||&lt;br /&gt;
|-&lt;br /&gt;
| ubsan || ||&lt;br /&gt;
 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Follow-on Questions==&lt;br /&gt;
&lt;br /&gt;
* Does g++ support each of these sanitizers?&lt;br /&gt;
* What other tools should I research besides gdb, lldb, valgrind, UBSAN, ASAN, TSAN, and MSAN?&lt;br /&gt;
* Are there tools other than sanitizers and debuggers I should know about?&lt;br /&gt;
* Are there obsolete tools I should ignore?&lt;br /&gt;
* Are there books that cover C++ topics beyond writing C++? How about how-to guides? (I'll be searching for these next, but do you happen to know any particularly useful and easy to read?&lt;br /&gt;
* Crash dumps and crash dump tools. I don't know much about them. What good resources on this topic are there for Linux, Windows, and Mac?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
I'm about to start going through the list above for myself. It may take a while.&lt;br /&gt;
&lt;br /&gt;
I'm currently involved in a project with about half a million existing lines of C++ code and want to know what tools I need to work in this environment properly. The application has multi-threaded parts.&lt;br /&gt;
&lt;br /&gt;
I can do basic g++, Debug, DebWithRelInfo, and Release builds using cmake or a pre-defined build script and step through code line-by-line with the gdb in VSCode, but want to become familiar with gdb at the command line.&lt;br /&gt;
&lt;br /&gt;
I want to come up to speed with clang and lldb in vscode.&lt;br /&gt;
&lt;br /&gt;
[[/stackoverflow.com/questions/63978029/setup-lldb-debugging-with-cpp-extension-in-vscode-linux|https://stackoverflow.com/questions/63978029/setup-lldb-debugging-with-cpp-extension-in-vscode-linux]]&lt;br /&gt;
&lt;br /&gt;
== Other Thoughts ==&lt;br /&gt;
&lt;br /&gt;
I need to familiarize myself with other tools available, learn how to enable particular tools in a build, and learn how to use the tool's output.&lt;br /&gt;
&lt;br /&gt;
I want to learn to use tools like UBSAN, ASAN, TSAN, and MSAN effectively and how to switch from g++ to clang when appropriate. I want to learn what tools other than the sanitizers and debuggers above are available.&lt;br /&gt;
&lt;br /&gt;
There's no such thing as free beer! Someone pays for flightgear cloud infrastructure that I personallly benefit from.  So I contribute a little at:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;https://liberapay.com/t3r&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Currently working on:&lt;br /&gt;
&lt;br /&gt;
Git Worktrees with download_and_compile.sh  (done &amp;amp; working)&lt;br /&gt;
&lt;br /&gt;
Web Socket Refactor &amp;amp; Fix.  &lt;br /&gt;
&lt;br /&gt;
OSM (Open Street Map) Scenery Build (on hold)&lt;br /&gt;
&lt;br /&gt;
Goals (Maybe)&lt;br /&gt;
&lt;br /&gt;
*Download Scenery from Current Scenery Developers&lt;br /&gt;
*Build Scripts for Scenery Land Class, Elevation, and OSM processing&lt;br /&gt;
*Understand the underlying formats in Flightgear Scenery&lt;br /&gt;
*Understand the processing of Scenery data between tiles in the build process and the running simulator&lt;br /&gt;
*Assist Scenery Developers with technical support.&lt;br /&gt;
*full explanation of the advantages and disadvantages of the worktree approach.&lt;br /&gt;
&lt;br /&gt;
[[Hackathon Proposal: Property Subscription Improvements|Hackathon-2023-Proposal-Websocket-Property-Subscription-Improvements]]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=139915</id>
		<title>User:Callahanp</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=139915"/>
		<updated>2024-06-06T13:57:34Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: /* Overviews */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
==Start With==&lt;br /&gt;
&lt;br /&gt;
*[[/cmake.org/getting-started/|https://cmake.org/getting-started/]] -- Build using g++ and clang.&lt;br /&gt;
*[[/learn.microsoft.com/en-us/vcpkg/|https://learn.microsoft.com/en-us/vcpkg/]] -- cross-platform C/C++ package manager&lt;br /&gt;
*[[https://www.jenkins.io/ -- Automation Server&lt;br /&gt;
*[[/www.sourceware.org/gdb/|https://www.sourceware.org/gdb/]] or [[/lldb.llvm.org/|https://lldb.llvm.org/]] -- Debuggers&lt;br /&gt;
*[[/github.com/google/sanitizers|https://github.com/google/sanitizers]] -- Read about each of the available sanitizers&lt;br /&gt;
*[[/valgrind.org/docs/manual/quick-start.html|https://valgrind.org/docs/manual/quick-start.html]] -- A suite of debugging and profiling tools&lt;br /&gt;
*A review of all the options for each tool you want to acquire.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Reading Lists ==&lt;br /&gt;
&lt;br /&gt;
=== Overviews ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Topic !! Overview  !! Options !! Progress !! Notes !!&lt;br /&gt;
|-&lt;br /&gt;
| vcpkg || https://learn.microsoft.com/en-us/vcpkg/  || &lt;br /&gt;
|- &lt;br /&gt;
| apt || https://wiki.debian.org/Apt || &lt;br /&gt;
|- &lt;br /&gt;
| cmake || https://cmake.org/getting-started/ ||&lt;br /&gt;
|-&lt;br /&gt;
| g++ || https://www.gnu.org/software/gcc/ ||&lt;br /&gt;
|-&lt;br /&gt;
| gdb || https://www.sourceware.org/gdb/ ||&lt;br /&gt;
|-&lt;br /&gt;
| llvm || llvm.org ||&lt;br /&gt;
|-&lt;br /&gt;
| clang || https://clang.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| lldb || https://lldb.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| valgrind || https://valgrind.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| lcov || https://github.com/linux-test-project/lcov || -DENABLE_COVERAGE=1&lt;br /&gt;
if (ENABLE_COVERAGE)&lt;br /&gt;
  set(CMAKE_BUILD_TYPE &amp;quot;Debug&amp;quot; CACHE STRING&lt;br /&gt;
    &amp;quot;set the build type.&amp;quot; FORCE)&lt;br /&gt;
  include(CodeCoverage.cmake)&lt;br /&gt;
  append_coverage_compiler_flags()&lt;br /&gt;
endif()&lt;br /&gt;
&lt;br /&gt;
add_executable&lt;br /&gt;
target_link_libraries( a.exe  test_a.cpp CPPUnit::CPPUnit&lt;br /&gt;
 if (ENABLE_COVERAGE)&lt;br /&gt;
   setup_target_for_coverage_lcov(&lt;br /&gt;
      NAME coverage&lt;br /&gt;
      EXECUTABLE ${cmake_current_binarey_dir}/test_a&lt;br /&gt;
      LCOV_ARGS --rc lcov_branch_coverage=1&lt;br /&gt;
      GENHTML_ARGS --legend --branch-coveragbe&lt;br /&gt;
      DEPENDENCIES test_a)&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| sanitizers || https://github.com/google/sanitizers&lt;br /&gt;
https://www.cl.cam.ac.uk/~nk480/C1819/lecture5.pdf&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| asan || https://github.com/google/sanitizers/wiki/AddressSanitizer ||gdb &amp;amp; clang:&lt;br /&gt;
CMAKE_CXX_FLAGS -fsanitize=address&lt;br /&gt;
CMAKE_EXE_LINKER_FLAGS -fsanitize=address&lt;br /&gt;
|-&lt;br /&gt;
| msan || https://github.com/google/sanitizers/wiki/MemorySanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| tsan || https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual ||&lt;br /&gt;
|-&lt;br /&gt;
| ubsan || https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html || gdb &amp;amp; clang:&lt;br /&gt;
CMAKE_CXX_FLAGS -fsanitize=undefined&lt;br /&gt;
CMAKE_EXE_LINKER_FLAGS -fsanitize=undefined&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Start With==&lt;br /&gt;
&lt;br /&gt;
*[[/cmake.org/getting-started/|https://cmake.org/getting-started/]] -- Build using g++ and clang.&lt;br /&gt;
*[[/learn.microsoft.com/en-us/vcpkg/|https://learn.microsoft.com/en-us/vcpkg/]] -- cross-platform C/C++ package manager&lt;br /&gt;
*[[/www.sourceware.org/gdb/|https://www.sourceware.org/gdb/]] or [[/lldb.llvm.org/|https://lldb.llvm.org/]] -- Debuggers&lt;br /&gt;
*[[/github.com/google/sanitizers|https://github.com/google/sanitizers]] -- Read about each of the available sanitizers&lt;br /&gt;
*[[/valgrind.org/docs/manual/quick-start.html|https://valgrind.org/docs/manual/quick-start.html]] -- A suite of debugging and profiling tools&lt;br /&gt;
*A review of all the options for each tool you want to acquire.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Reading Lists ==&lt;br /&gt;
&lt;br /&gt;
=== Overviews ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Topic !! Overview  !! Options !! Progress !! Notes !!&lt;br /&gt;
|-&lt;br /&gt;
| vcpkg || https://learn.microsoft.com/en-us/vcpkg/  || &lt;br /&gt;
|- &lt;br /&gt;
| apt || https://wiki.debian.org/Apt || &lt;br /&gt;
|- &lt;br /&gt;
| cmake || https://cmake.org/getting-started/ ||&lt;br /&gt;
|-&lt;br /&gt;
| g++ || https://www.gnu.org/software/gcc/ ||&lt;br /&gt;
|-&lt;br /&gt;
| gdb || https://www.sourceware.org/gdb/ ||&lt;br /&gt;
|-&lt;br /&gt;
| llvm || llvm.org ||&lt;br /&gt;
|-&lt;br /&gt;
| clang || https://clang.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| lldb || https://lldb.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| valgrind || https://valgrind.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| sanitizers || https://github.com/google/sanitizers&lt;br /&gt;
https://www.cl.cam.ac.uk/~nk480/C1819/lecture5.pdf&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| asan || https://github.com/google/sanitizers/wiki/AddressSanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| msan || https://github.com/google/sanitizers/wiki/MemorySanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| tsan || https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual ||&lt;br /&gt;
|-&lt;br /&gt;
| ubsan || https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html ||&lt;br /&gt;
 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Start With==&lt;br /&gt;
&lt;br /&gt;
*[[/cmake.org/getting-started/|https://cmake.org/getting-started/]] -- Build using g++ and clang.&lt;br /&gt;
*[[/learn.microsoft.com/en-us/vcpkg/|https://learn.microsoft.com/en-us/vcpkg/]] -- cross-platform C/C++ package manager&lt;br /&gt;
*[[/www.sourceware.org/gdb/|https://www.sourceware.org/gdb/]] or [[/lldb.llvm.org/|https://lldb.llvm.org/]] -- Debuggers&lt;br /&gt;
*[[/github.com/google/sanitizers|https://github.com/google/sanitizers]] -- Read about each of the available sanitizers&lt;br /&gt;
*[[/valgrind.org/docs/manual/quick-start.html|https://valgrind.org/docs/manual/quick-start.html]] -- A suite of debugging and profiling tools&lt;br /&gt;
*A review of all the options for each tool you want to acquire.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Reading Lists ==&lt;br /&gt;
&lt;br /&gt;
=== Overviews ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Topic !! Overview  !! Options !! Progress !! Notes !!&lt;br /&gt;
|-&lt;br /&gt;
| vcpkg || https://learn.microsoft.com/en-us/vcpkg/  || &lt;br /&gt;
|- &lt;br /&gt;
| apt || https://wiki.debian.org/Apt || &lt;br /&gt;
|- &lt;br /&gt;
| cmake || https://cmake.org/getting-started/ ||&lt;br /&gt;
|-&lt;br /&gt;
| g++ || https://www.gnu.org/software/gcc/ ||&lt;br /&gt;
|-&lt;br /&gt;
| gdb || https://www.sourceware.org/gdb/ ||&lt;br /&gt;
|-&lt;br /&gt;
| llvm || https://llvm.org ||&lt;br /&gt;
|-&lt;br /&gt;
| clang || https://clang.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| lldb || https://lldb.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| valgrind || https://valgrind.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| sanitizers || https://github.com/google/sanitizers&lt;br /&gt;
https://www.cl.cam.ac.uk/~nk480/C1819/lecture5.pdf&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| asan || https://github.com/google/sanitizers/wiki/AddressSanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| msan || https://github.com/google/sanitizers/wiki/MemorySanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| tsan || https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual ||&lt;br /&gt;
|-&lt;br /&gt;
| ubsan || https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html ||&lt;br /&gt;
 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Integration ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Topic !! Download_and_compile.sh !! dev1&lt;br /&gt;
|-&lt;br /&gt;
| vcpkg ||   || &lt;br /&gt;
|- &lt;br /&gt;
| apt || || &lt;br /&gt;
|- &lt;br /&gt;
| cmake || ||&lt;br /&gt;
|-&lt;br /&gt;
| g++ ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| gdb || ||&lt;br /&gt;
|-&lt;br /&gt;
| llvm ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| clang ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| lldb ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| valgrind ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| sanitizers ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| asan ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| msan ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| tsan || ||&lt;br /&gt;
|-&lt;br /&gt;
| ubsan || ||&lt;br /&gt;
 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Follow-on Questions==&lt;br /&gt;
&lt;br /&gt;
* Does g++ support each of these sanitizers?&lt;br /&gt;
* What other tools should I research besides gdb, lldb, valgrind, UBSAN, ASAN, TSAN, and MSAN?&lt;br /&gt;
* Are there tools other than sanitizers and debuggers I should know about?&lt;br /&gt;
* Are there obsolete tools I should ignore?&lt;br /&gt;
* Are there books that cover C++ topics beyond writing C++? How about how-to guides? (I'll be searching for these next, but do you happen to know any particularly useful and easy to read?&lt;br /&gt;
* Crash dumps and crash dump tools. I don't know much about them. What good resources on this topic are there for Linux, Windows, and Mac?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
I'm about to start going through the list above for myself. It may take a while.&lt;br /&gt;
&lt;br /&gt;
I'm currently involved in a project with about half a million existing lines of C++ code and want to know what tools I need to work in this environment properly. The application has multi-threaded parts.&lt;br /&gt;
&lt;br /&gt;
I can do basic g++, Debug, DebWithRelInfo, and Release builds using cmake or a pre-defined build script and step through code line-by-line with the gdb in VSCode, but want to become familiar with gdb at the command line.&lt;br /&gt;
&lt;br /&gt;
I want to come up to speed with clang and lldb in vscode.&lt;br /&gt;
&lt;br /&gt;
[[/stackoverflow.com/questions/63978029/setup-lldb-debugging-with-cpp-extension-in-vscode-linux|https://stackoverflow.com/questions/63978029/setup-lldb-debugging-with-cpp-extension-in-vscode-linux]]&lt;br /&gt;
&lt;br /&gt;
== Other Thoughts ==&lt;br /&gt;
&lt;br /&gt;
I need to familiarize myself with other tools available, learn how to enable particular tools in a build, and learn how to use the tool's output.&lt;br /&gt;
&lt;br /&gt;
I want to learn to use tools like UBSAN, ASAN, TSAN, and MSAN effectively and how to switch from g++ to clang when appropriate. I want to learn what tools other than the sanitizers and debuggers above are available.&lt;br /&gt;
&lt;br /&gt;
There's no such thing as free beer! Someone pays for flightgear cloud infrastructure that I personallly benefit from.  So I contribute a little at:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;https://liberapay.com/t3r&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Currently working on:&lt;br /&gt;
&lt;br /&gt;
Git Worktrees with download_and_compile.sh  (done &amp;amp; working)&lt;br /&gt;
&lt;br /&gt;
Web Socket Refactor &amp;amp; Fix.  &lt;br /&gt;
&lt;br /&gt;
OSM (Open Street Map) Scenery Build (on hold)&lt;br /&gt;
&lt;br /&gt;
Goals (Maybe)&lt;br /&gt;
&lt;br /&gt;
*Download Scenery from Current Scenery Developers&lt;br /&gt;
*Build Scripts for Scenery Land Class, Elevation, and OSM processing&lt;br /&gt;
*Understand the underlying formats in Flightgear Scenery&lt;br /&gt;
*Understand the processing of Scenery data between tiles in the build process and the running simulator&lt;br /&gt;
*Assist Scenery Developers with technical support.&lt;br /&gt;
*full explanation of the advantages and disadvantages of the worktree approach.&lt;br /&gt;
&lt;br /&gt;
[[Hackathon Proposal: Property Subscription Improvements|Hackathon-2023-Proposal-Websocket-Property-Subscription-Improvements]]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=139914</id>
		<title>User:Callahanp</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=139914"/>
		<updated>2024-06-06T13:56:41Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: /* Follow-on Questions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
==Start With==&lt;br /&gt;
&lt;br /&gt;
*[[/cmake.org/getting-started/|https://cmake.org/getting-started/]] -- Build using g++ and clang.&lt;br /&gt;
*[[/learn.microsoft.com/en-us/vcpkg/|https://learn.microsoft.com/en-us/vcpkg/]] -- cross-platform C/C++ package manager&lt;br /&gt;
*[[https://www.jenkins.io/ -- Automation Server&lt;br /&gt;
*[[/www.sourceware.org/gdb/|https://www.sourceware.org/gdb/]] or [[/lldb.llvm.org/|https://lldb.llvm.org/]] -- Debuggers&lt;br /&gt;
*[[/github.com/google/sanitizers|https://github.com/google/sanitizers]] -- Read about each of the available sanitizers&lt;br /&gt;
*[[/valgrind.org/docs/manual/quick-start.html|https://valgrind.org/docs/manual/quick-start.html]] -- A suite of debugging and profiling tools&lt;br /&gt;
*A review of all the options for each tool you want to acquire.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Reading Lists ==&lt;br /&gt;
&lt;br /&gt;
=== Overviews ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Topic !! Overview  !! Options !! Progress !! Notes !!&lt;br /&gt;
|-&lt;br /&gt;
| vcpkg || https://learn.microsoft.com/en-us/vcpkg/  || &lt;br /&gt;
|- &lt;br /&gt;
| apt || https://wiki.debian.org/Apt || &lt;br /&gt;
|- &lt;br /&gt;
| cmake || https://cmake.org/getting-started/ ||&lt;br /&gt;
|-&lt;br /&gt;
| g++ || https://www.gnu.org/software/gcc/ ||&lt;br /&gt;
|-&lt;br /&gt;
| gdb || https://www.sourceware.org/gdb/ ||&lt;br /&gt;
|-&lt;br /&gt;
| llvm || llvm.org ||&lt;br /&gt;
|-&lt;br /&gt;
| clang || https://clang.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| lldb || https://lldb.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| valgrind || https://valgrind.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| lcov || https://github.com/linux-test-project/lcov || -DENABLE_COVERAGE=1&lt;br /&gt;
if (ENABLE_COVERAGE)&lt;br /&gt;
  set(CMAKE_BUILD_TYPE &amp;quot;Debug&amp;quot; CACHE STRING&lt;br /&gt;
    &amp;quot;set the build type.&amp;quot; FORCE)&lt;br /&gt;
  include(CodeCoverage.cmake)&lt;br /&gt;
  append_coverage_compiler_flags()&lt;br /&gt;
endif()&lt;br /&gt;
&lt;br /&gt;
add_executable&lt;br /&gt;
target_link_libraries( a.exe  test_a.cpp CPPUnit::CPPUnit&lt;br /&gt;
 if (ENABLE_COVERAGE)&lt;br /&gt;
   setup_target_for_coverage_lcov(&lt;br /&gt;
      NAME coverage&lt;br /&gt;
      EXECUTABLE ${cmake_current_binarey_dir}/test_a&lt;br /&gt;
      LCOV_ARGS --rc lcov_branch_coverage=1&lt;br /&gt;
      GENHTML_ARGS --legend --branch-coveragbe&lt;br /&gt;
      DEPENDENCIES test_a)&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| sanitizers || https://github.com/google/sanitizers&lt;br /&gt;
https://www.cl.cam.ac.uk/~nk480/C1819/lecture5.pdf&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| asan || https://github.com/google/sanitizers/wiki/AddressSanitizer ||gdb &amp;amp; clang:&lt;br /&gt;
CMAKE_CXX_FLAGS -fsanitize=address&lt;br /&gt;
CMAKE_EXE_LINKER_FLAGS -fsanitize=address&lt;br /&gt;
|-&lt;br /&gt;
| msan || https://github.com/google/sanitizers/wiki/MemorySanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| tsan || https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual ||&lt;br /&gt;
|-&lt;br /&gt;
| ubsan || https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html || gdb &amp;amp; clang:&lt;br /&gt;
CMAKE_CXX_FLAGS -fsanitize=undefined&lt;br /&gt;
CMAKE_EXE_LINKER_FLAGS -fsanitize=undefined&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Start With==&lt;br /&gt;
&lt;br /&gt;
*[[/cmake.org/getting-started/|https://cmake.org/getting-started/]] -- Build using g++ and clang.&lt;br /&gt;
*[[/learn.microsoft.com/en-us/vcpkg/|https://learn.microsoft.com/en-us/vcpkg/]] -- cross-platform C/C++ package manager&lt;br /&gt;
*[[/www.sourceware.org/gdb/|https://www.sourceware.org/gdb/]] or [[/lldb.llvm.org/|https://lldb.llvm.org/]] -- Debuggers&lt;br /&gt;
*[[/github.com/google/sanitizers|https://github.com/google/sanitizers]] -- Read about each of the available sanitizers&lt;br /&gt;
*[[/valgrind.org/docs/manual/quick-start.html|https://valgrind.org/docs/manual/quick-start.html]] -- A suite of debugging and profiling tools&lt;br /&gt;
*A review of all the options for each tool you want to acquire.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Reading Lists ==&lt;br /&gt;
&lt;br /&gt;
=== Overviews ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Topic !! Overview  !! Options !! Progress !! Notes !!&lt;br /&gt;
|-&lt;br /&gt;
| vcpkg || https://learn.microsoft.com/en-us/vcpkg/  || &lt;br /&gt;
|- &lt;br /&gt;
| apt || https://wiki.debian.org/Apt || &lt;br /&gt;
|- &lt;br /&gt;
| cmake || https://cmake.org/getting-started/ ||&lt;br /&gt;
|-&lt;br /&gt;
| g++ || https://www.gnu.org/software/gcc/ ||&lt;br /&gt;
|-&lt;br /&gt;
| gdb || https://www.sourceware.org/gdb/ ||&lt;br /&gt;
|-&lt;br /&gt;
| llvm || llvm.org ||&lt;br /&gt;
|-&lt;br /&gt;
| clang || https://clang.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| lldb || https://lldb.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| valgrind || https://valgrind.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| sanitizers || https://github.com/google/sanitizers&lt;br /&gt;
https://www.cl.cam.ac.uk/~nk480/C1819/lecture5.pdf&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| asan || https://github.com/google/sanitizers/wiki/AddressSanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| msan || https://github.com/google/sanitizers/wiki/MemorySanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| tsan || https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual ||&lt;br /&gt;
|-&lt;br /&gt;
| ubsan || https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html ||&lt;br /&gt;
 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Start With==&lt;br /&gt;
&lt;br /&gt;
*[[/cmake.org/getting-started/|https://cmake.org/getting-started/]] -- Build using g++ and clang.&lt;br /&gt;
*[[/learn.microsoft.com/en-us/vcpkg/|https://learn.microsoft.com/en-us/vcpkg/]] -- cross-platform C/C++ package manager&lt;br /&gt;
*[[/www.sourceware.org/gdb/|https://www.sourceware.org/gdb/]] or [[/lldb.llvm.org/|https://lldb.llvm.org/]] -- Debuggers&lt;br /&gt;
*[[/github.com/google/sanitizers|https://github.com/google/sanitizers]] -- Read about each of the available sanitizers&lt;br /&gt;
*[[/valgrind.org/docs/manual/quick-start.html|https://valgrind.org/docs/manual/quick-start.html]] -- A suite of debugging and profiling tools&lt;br /&gt;
*A review of all the options for each tool you want to acquire.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Reading Lists ==&lt;br /&gt;
&lt;br /&gt;
=== Overviews ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Topic !! Overview  !! Options !! Progress !! Notes !!&lt;br /&gt;
|-&lt;br /&gt;
| vcpkg || https://learn.microsoft.com/en-us/vcpkg/  || &lt;br /&gt;
|- &lt;br /&gt;
| apt || https://wiki.debian.org/Apt || &lt;br /&gt;
|- &lt;br /&gt;
| cmake || https://cmake.org/getting-started/ ||&lt;br /&gt;
|-&lt;br /&gt;
| g++ || https://www.gnu.org/software/gcc/ ||&lt;br /&gt;
|-&lt;br /&gt;
| gdb || https://www.sourceware.org/gdb/ ||&lt;br /&gt;
|-&lt;br /&gt;
| llvm || llvm.org ||&lt;br /&gt;
|-&lt;br /&gt;
| clang || https://clang.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| lldb || https://lldb.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| valgrind || https://valgrind.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| sanitizers || https://github.com/google/sanitizers&lt;br /&gt;
https://www.cl.cam.ac.uk/~nk480/C1819/lecture5.pdf&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| asan || https://github.com/google/sanitizers/wiki/AddressSanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| msan || https://github.com/google/sanitizers/wiki/MemorySanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| tsan || https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual ||&lt;br /&gt;
|-&lt;br /&gt;
| ubsan || https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html ||&lt;br /&gt;
 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Integration ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Topic !! Download_and_compile.sh !! dev1&lt;br /&gt;
|-&lt;br /&gt;
| vcpkg ||   || &lt;br /&gt;
|- &lt;br /&gt;
| apt || || &lt;br /&gt;
|- &lt;br /&gt;
| cmake || ||&lt;br /&gt;
|-&lt;br /&gt;
| g++ ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| gdb || ||&lt;br /&gt;
|-&lt;br /&gt;
| llvm ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| clang ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| lldb ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| valgrind ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| sanitizers ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| asan ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| msan ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| tsan || ||&lt;br /&gt;
|-&lt;br /&gt;
| ubsan || ||&lt;br /&gt;
 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Follow-on Questions==&lt;br /&gt;
&lt;br /&gt;
* Does g++ support each of these sanitizers?&lt;br /&gt;
* What other tools should I research besides gdb, lldb, valgrind, UBSAN, ASAN, TSAN, and MSAN?&lt;br /&gt;
* Are there tools other than sanitizers and debuggers I should know about?&lt;br /&gt;
* Are there obsolete tools I should ignore?&lt;br /&gt;
* Are there books that cover C++ topics beyond writing C++? How about how-to guides? (I'll be searching for these next, but do you happen to know any particularly useful and easy to read?&lt;br /&gt;
* Crash dumps and crash dump tools. I don't know much about them. What good resources on this topic are there for Linux, Windows, and Mac?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
I'm about to start going through the list above for myself. It may take a while.&lt;br /&gt;
&lt;br /&gt;
I'm currently involved in a project with about half a million existing lines of C++ code and want to know what tools I need to work in this environment properly. The application has multi-threaded parts.&lt;br /&gt;
&lt;br /&gt;
I can do basic g++, Debug, DebWithRelInfo, and Release builds using cmake or a pre-defined build script and step through code line-by-line with the gdb in VSCode, but want to become familiar with gdb at the command line.&lt;br /&gt;
&lt;br /&gt;
I want to come up to speed with clang and lldb in vscode.&lt;br /&gt;
&lt;br /&gt;
[[/stackoverflow.com/questions/63978029/setup-lldb-debugging-with-cpp-extension-in-vscode-linux|https://stackoverflow.com/questions/63978029/setup-lldb-debugging-with-cpp-extension-in-vscode-linux]]&lt;br /&gt;
&lt;br /&gt;
== Other Thoughts ==&lt;br /&gt;
&lt;br /&gt;
I need to familiarize myself with other tools available, learn how to enable particular tools in a build, and learn how to use the tool's output.&lt;br /&gt;
&lt;br /&gt;
I want to learn to use tools like UBSAN, ASAN, TSAN, and MSAN effectively and how to switch from g++ to clang when appropriate. I want to learn what tools other than the sanitizers and debuggers above are available.&lt;br /&gt;
&lt;br /&gt;
There's no such thing as free beer! Someone pays for flightgear cloud infrastructure that I personallly benefit from.  So I contribute a little at:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;https://liberapay.com/t3r&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Currently working on:&lt;br /&gt;
&lt;br /&gt;
Git Worktrees with download_and_compile.sh  (done &amp;amp; working)&lt;br /&gt;
&lt;br /&gt;
Web Socket Refactor &amp;amp; Fix.  &lt;br /&gt;
&lt;br /&gt;
OSM (Open Street Map) Scenery Build (on hold)&lt;br /&gt;
&lt;br /&gt;
Goals (Maybe)&lt;br /&gt;
&lt;br /&gt;
*Download Scenery from Current Scenery Developers&lt;br /&gt;
*Build Scripts for Scenery Land Class, Elevation, and OSM processing&lt;br /&gt;
*Understand the underlying formats in Flightgear Scenery&lt;br /&gt;
*Understand the processing of Scenery data between tiles in the build process and the running simulator&lt;br /&gt;
*Assist Scenery Developers with technical support.&lt;br /&gt;
*full explanation of the advantages and disadvantages of the worktree approach.&lt;br /&gt;
&lt;br /&gt;
[[Hackathon Proposal: Property Subscription Improvements|Hackathon-2023-Proposal-Websocket-Property-Subscription-Improvements]]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User_talk:Callahanp&amp;diff=139913</id>
		<title>User talk:Callahanp</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User_talk:Callahanp&amp;diff=139913"/>
		<updated>2024-06-06T13:53:06Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The following is a response by [[User:Johan G|Johan G]] to a wiki mail I sent to him personally with questions about how to properly organize wiki pages and a solicitation of comments on the style of writing in [[Howto:Build your own Panel or Cockpit]]  and [[Howto:C172P Panel Project]].  Johan's comments include references to several useful articles on wiki style and structure including the use of sub-categories instead of categorizing in the title. &lt;br /&gt;
&lt;br /&gt;
* [[FlightGear wiki:Manual of Style|Manual of style]]&lt;br /&gt;
* [[Help:Templates]]&lt;br /&gt;
* [[:Category:Navigation templates]] &lt;br /&gt;
&lt;br /&gt;
His comments also cover the use of templates including  {{tl|delete}} and {{tl|WIP}} &lt;br /&gt;
&lt;br /&gt;
== Cleanup, subpages, lack of feedback etc. ==&lt;br /&gt;
Hi there, I saw your wiki mail. I am only sort of active in the community at the moment, more due to IRL reasons than my interest in FlightGear (though I am still actually hardly ever flying in FlightGear).&lt;br /&gt;
&lt;br /&gt;
This got a bit longer than I first planned and to a large extent reflects my opinion, but I hope you will find it useful anyway.&lt;br /&gt;
&lt;br /&gt;
{{tip|The main aim is to make it easy for the reader to navigate, read and comprehend the material.}}&lt;br /&gt;
&lt;br /&gt;
Regarding templates, skim through [[Help:Templates]], look at templates similar to what you want to achieve and ''start small''.  The other help pages may be helpful too, but maybe more in general.&lt;br /&gt;
&lt;br /&gt;
As for lack of feedback, I do not think you should see that as a bad sign.&lt;br /&gt;
&lt;br /&gt;
=== Style ===&lt;br /&gt;
When it comes to style, there is a somewhat hidden away [[FlightGear wiki:Manual of Style|Manual of style]], but see my tip.&lt;br /&gt;
&lt;br /&gt;
However in general finding, navigating, reading and comprehending is made easier by&lt;br /&gt;
* good first sections that summarizes articles well,&lt;br /&gt;
* good article, section and subsection titles,&lt;br /&gt;
* balanced article, section, subsection and paragraph lengths, and&lt;br /&gt;
* a decent navigation box on the right.&lt;br /&gt;
Illustrations will help as well (with good captions they may even aid finding the article).&lt;br /&gt;
&lt;br /&gt;
The first section also serves the two purposes of giving an early indication to whether one has landed on the right page or not, and can also help the reader get a quick overview that will help him comprehend the article easier. It should however be at least somewhat concise, one or maybe a few short paragraphs.&lt;br /&gt;
&lt;br /&gt;
The best thing with making articles easier to navigate, read and comprehend for the reader is that they will also most likely get better page rankings.&lt;br /&gt;
&lt;br /&gt;
=== Subpages or not ===&lt;br /&gt;
Personally I most often use subpages to put drafts, to do lists etc. as subpages to my user page.&lt;br /&gt;
&lt;br /&gt;
While the article series could be organized into subpages, consider if they need quite that long a title and if they can stand somewhat on their own.  You can perhaps instead group them in a category (probably as a subcategory to [http://wiki.flightgear.org/index.php?title=Special%3ACategoryTree&amp;amp;target=Cockpit+building&amp;amp;mode=categories&amp;amp;namespaces= Category:Cockpit building]) and with a custom navbox template in each article (see [[:Category:Navigation templates]] for inspiration).  I think that a navbox on the top right will help navigation more than subpages.&lt;br /&gt;
&lt;br /&gt;
=== Moving and deleting pages and other wiki maintenance ===&lt;br /&gt;
While one need to be at least an administrator to delete pages, anyone can move them (in essence rename them), unless they are protected.  It is not all that obvious at first, but if you are at a computer you can either see a ''Move'' or a ''More'' tab among the page tabs on top of a page.  From there on it should be explained in the form where you enter a new name for the page.&lt;br /&gt;
&lt;br /&gt;
If you instead want a page deleted mark the page with the {{tl|delete}} template.  It may take a while till the page is deleted.&lt;br /&gt;
&lt;br /&gt;
One important thing when moving a page is to consider the pages that might link to it.  In order to help a reader to find what he is looking for you might need to edit the pages linking to the page to be moved.  To see what pages that are affected, click the ''[[Special:WhatLinksHere/User talk:Callahanp|What links here]]'' link on the sidebar to the left.&lt;br /&gt;
&lt;br /&gt;
You could optionally add the {{tl|WIP}} template to the top of the pages while you put most of your effort on them and they might change often.&lt;br /&gt;
&lt;br /&gt;
=== Preview early and preview often ===&lt;br /&gt;
Finally, preview early and preview often and save when mostly done (preferably with a short and concise summary).&lt;br /&gt;
&lt;br /&gt;
—[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 16:17, 5 November 2017 (EST)&lt;br /&gt;
&lt;br /&gt;
[[talk:Callahanp/Flightgear Codebase]]&lt;br /&gt;
&lt;br /&gt;
=== About creating new pages ===&lt;br /&gt;
Hi! Saw your message on the unofficial FlightGear Discord server.&lt;br /&gt;
&lt;br /&gt;
This might be of help: [[Help:Your first article#Creating a new article]].  Not quite as relevant, but possibly of help: [[Help:Namespaces]].&lt;br /&gt;
&lt;br /&gt;
—[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 20:42, 1 November 2023 (UTC)&lt;br /&gt;
&lt;br /&gt;
== External links ==&lt;br /&gt;
&lt;br /&gt;
Hi,&lt;br /&gt;
&lt;br /&gt;
Maybe it was intentional, but I am not sure if you understand how external links work on the wiki. For example, I found this piece of code on [[User:Callahanp]]:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;[[/www.reddit.com/user/Ujjawal-Gupta/|Ujjawal-Gupta]]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
This creates a (broken) internal wiki link: [[/www.reddit.com/user/Ujjawal-Gupta/|Ujjawal-Gupta]]&lt;br /&gt;
&lt;br /&gt;
I think what you were trying to do is:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;[http://www.reddit.com/user/Ujjawal-Gupta/ Ujjawal-Gupta]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Which results in: [http://www.reddit.com/user/Ujjawal-Gupta/ Ujjawal-Gupta]&lt;br /&gt;
&lt;br /&gt;
Please see the manual for more help: [[Help:Formatting#Links to external sites]]. Don't hesitate to ask if something is unclear.&lt;br /&gt;
&lt;br /&gt;
Cheers,&lt;br /&gt;
&lt;br /&gt;
[[User:Gijs|Gijs]] ([[User talk:Gijs|talk]]) 08:37, 31 May 2024 (UTC)&lt;br /&gt;
&lt;br /&gt;
Gijs,&lt;br /&gt;
&lt;br /&gt;
Thanks for the info, and yes, I'm aware of the difference, it was just a bad bit of editing. I'm sure this popped up during an automated scan of wiki errors.  I'd be very surprised if anyone actually looked at the page, let alone tried the link.&lt;br /&gt;
That section was copy pasta from a post I made on reddit. I had meant to remove the link entirely, as it did not apply here, and was formatted improperly anyway.&lt;br /&gt;
&lt;br /&gt;
-pat&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=139899</id>
		<title>User:Callahanp</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=139899"/>
		<updated>2024-05-31T01:24:00Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
==Start With==&lt;br /&gt;
&lt;br /&gt;
*[[/cmake.org/getting-started/|https://cmake.org/getting-started/]] -- Build using g++ and clang.&lt;br /&gt;
*[[/learn.microsoft.com/en-us/vcpkg/|https://learn.microsoft.com/en-us/vcpkg/]] -- cross-platform C/C++ package manager&lt;br /&gt;
*[[https://www.jenkins.io/ -- Automation Server&lt;br /&gt;
*[[/www.sourceware.org/gdb/|https://www.sourceware.org/gdb/]] or [[/lldb.llvm.org/|https://lldb.llvm.org/]] -- Debuggers&lt;br /&gt;
*[[/github.com/google/sanitizers|https://github.com/google/sanitizers]] -- Read about each of the available sanitizers&lt;br /&gt;
*[[/valgrind.org/docs/manual/quick-start.html|https://valgrind.org/docs/manual/quick-start.html]] -- A suite of debugging and profiling tools&lt;br /&gt;
*A review of all the options for each tool you want to acquire.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Reading Lists ==&lt;br /&gt;
&lt;br /&gt;
=== Overviews ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Topic !! Overview  !! Options !! Progress !! Notes !!&lt;br /&gt;
|-&lt;br /&gt;
| vcpkg || https://learn.microsoft.com/en-us/vcpkg/  || &lt;br /&gt;
|- &lt;br /&gt;
| apt || https://wiki.debian.org/Apt || &lt;br /&gt;
|- &lt;br /&gt;
| cmake || https://cmake.org/getting-started/ ||&lt;br /&gt;
|-&lt;br /&gt;
| g++ || https://www.gnu.org/software/gcc/ ||&lt;br /&gt;
|-&lt;br /&gt;
| gdb || https://www.sourceware.org/gdb/ ||&lt;br /&gt;
|-&lt;br /&gt;
| llvm || llvm.org ||&lt;br /&gt;
|-&lt;br /&gt;
| clang || https://clang.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| lldb || https://lldb.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| valgrind || https://valgrind.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| lcov || https://github.com/linux-test-project/lcov || -DENABLE_COVERAGE=1&lt;br /&gt;
if (ENABLE_COVERAGE)&lt;br /&gt;
  set(CMAKE_BUILD_TYPE &amp;quot;Debug&amp;quot; CACHE STRING&lt;br /&gt;
    &amp;quot;set the build type.&amp;quot; FORCE)&lt;br /&gt;
  include(CodeCoverage.cmake)&lt;br /&gt;
  append_coverage_compiler_flags()&lt;br /&gt;
endif()&lt;br /&gt;
&lt;br /&gt;
add_executable&lt;br /&gt;
target_link_libraries( a.exe  test_a.cpp CPPUnit::CPPUnit&lt;br /&gt;
 if (ENABLE_COVERAGE)&lt;br /&gt;
   setup_target_for_coverage_lcov(&lt;br /&gt;
      NAME coverage&lt;br /&gt;
      EXECUTABLE ${cmake_current_binarey_dir}/test_a&lt;br /&gt;
      LCOV_ARGS --rc lcov_branch_coverage=1&lt;br /&gt;
      GENHTML_ARGS --legend --branch-coveragbe&lt;br /&gt;
      DEPENDENCIES test_a)&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| sanitizers || https://github.com/google/sanitizers&lt;br /&gt;
https://www.cl.cam.ac.uk/~nk480/C1819/lecture5.pdf&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| asan || https://github.com/google/sanitizers/wiki/AddressSanitizer ||gdb &amp;amp; clang:&lt;br /&gt;
CMAKE_CXX_FLAGS -fsanitize=address&lt;br /&gt;
CMAKE_EXE_LINKER_FLAGS -fsanitize=address&lt;br /&gt;
|-&lt;br /&gt;
| msan || https://github.com/google/sanitizers/wiki/MemorySanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| tsan || https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual ||&lt;br /&gt;
|-&lt;br /&gt;
| ubsan || https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html || gdb &amp;amp; clang:&lt;br /&gt;
CMAKE_CXX_FLAGS -fsanitize=undefined&lt;br /&gt;
CMAKE_EXE_LINKER_FLAGS -fsanitize=undefined&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Start With==&lt;br /&gt;
&lt;br /&gt;
*[[/cmake.org/getting-started/|https://cmake.org/getting-started/]] -- Build using g++ and clang.&lt;br /&gt;
*[[/learn.microsoft.com/en-us/vcpkg/|https://learn.microsoft.com/en-us/vcpkg/]] -- cross-platform C/C++ package manager&lt;br /&gt;
*[[/www.sourceware.org/gdb/|https://www.sourceware.org/gdb/]] or [[/lldb.llvm.org/|https://lldb.llvm.org/]] -- Debuggers&lt;br /&gt;
*[[/github.com/google/sanitizers|https://github.com/google/sanitizers]] -- Read about each of the available sanitizers&lt;br /&gt;
*[[/valgrind.org/docs/manual/quick-start.html|https://valgrind.org/docs/manual/quick-start.html]] -- A suite of debugging and profiling tools&lt;br /&gt;
*A review of all the options for each tool you want to acquire.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Reading Lists ==&lt;br /&gt;
&lt;br /&gt;
=== Overviews ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Topic !! Overview  !! Options !! Progress !! Notes !!&lt;br /&gt;
|-&lt;br /&gt;
| vcpkg || https://learn.microsoft.com/en-us/vcpkg/  || &lt;br /&gt;
|- &lt;br /&gt;
| apt || https://wiki.debian.org/Apt || &lt;br /&gt;
|- &lt;br /&gt;
| cmake || https://cmake.org/getting-started/ ||&lt;br /&gt;
|-&lt;br /&gt;
| g++ || https://www.gnu.org/software/gcc/ ||&lt;br /&gt;
|-&lt;br /&gt;
| gdb || https://www.sourceware.org/gdb/ ||&lt;br /&gt;
|-&lt;br /&gt;
| llvm || llvm.org ||&lt;br /&gt;
|-&lt;br /&gt;
| clang || https://clang.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| lldb || https://lldb.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| valgrind || https://valgrind.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| sanitizers || https://github.com/google/sanitizers&lt;br /&gt;
https://www.cl.cam.ac.uk/~nk480/C1819/lecture5.pdf&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| asan || https://github.com/google/sanitizers/wiki/AddressSanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| msan || https://github.com/google/sanitizers/wiki/MemorySanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| tsan || https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual ||&lt;br /&gt;
|-&lt;br /&gt;
| ubsan || https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html ||&lt;br /&gt;
 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Start With==&lt;br /&gt;
&lt;br /&gt;
*[[/cmake.org/getting-started/|https://cmake.org/getting-started/]] -- Build using g++ and clang.&lt;br /&gt;
*[[/learn.microsoft.com/en-us/vcpkg/|https://learn.microsoft.com/en-us/vcpkg/]] -- cross-platform C/C++ package manager&lt;br /&gt;
*[[/www.sourceware.org/gdb/|https://www.sourceware.org/gdb/]] or [[/lldb.llvm.org/|https://lldb.llvm.org/]] -- Debuggers&lt;br /&gt;
*[[/github.com/google/sanitizers|https://github.com/google/sanitizers]] -- Read about each of the available sanitizers&lt;br /&gt;
*[[/valgrind.org/docs/manual/quick-start.html|https://valgrind.org/docs/manual/quick-start.html]] -- A suite of debugging and profiling tools&lt;br /&gt;
*A review of all the options for each tool you want to acquire.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Reading Lists ==&lt;br /&gt;
&lt;br /&gt;
=== Overviews ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Topic !! Overview  !! Options !! Progress !! Notes !!&lt;br /&gt;
|-&lt;br /&gt;
| vcpkg || https://learn.microsoft.com/en-us/vcpkg/  || &lt;br /&gt;
|- &lt;br /&gt;
| apt || https://wiki.debian.org/Apt || &lt;br /&gt;
|- &lt;br /&gt;
| cmake || https://cmake.org/getting-started/ ||&lt;br /&gt;
|-&lt;br /&gt;
| g++ || https://www.gnu.org/software/gcc/ ||&lt;br /&gt;
|-&lt;br /&gt;
| gdb || https://www.sourceware.org/gdb/ ||&lt;br /&gt;
|-&lt;br /&gt;
| llvm || llvm.org ||&lt;br /&gt;
|-&lt;br /&gt;
| clang || https://clang.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| lldb || https://lldb.llvm.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| valgrind || https://valgrind.org/ ||&lt;br /&gt;
|-&lt;br /&gt;
| sanitizers || https://github.com/google/sanitizers&lt;br /&gt;
https://www.cl.cam.ac.uk/~nk480/C1819/lecture5.pdf&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| asan || https://github.com/google/sanitizers/wiki/AddressSanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| msan || https://github.com/google/sanitizers/wiki/MemorySanitizer ||&lt;br /&gt;
|-&lt;br /&gt;
| tsan || https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual ||&lt;br /&gt;
|-&lt;br /&gt;
| ubsan || https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html ||&lt;br /&gt;
 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Integration ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Topic !! Download_and_compile.sh !! dev1&lt;br /&gt;
|-&lt;br /&gt;
| vcpkg ||   || &lt;br /&gt;
|- &lt;br /&gt;
| apt || || &lt;br /&gt;
|- &lt;br /&gt;
| cmake || ||&lt;br /&gt;
|-&lt;br /&gt;
| g++ ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| gdb || ||&lt;br /&gt;
|-&lt;br /&gt;
| llvm ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| clang ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| lldb ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| valgrind ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| sanitizers ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| asan ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| msan ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| tsan || ||&lt;br /&gt;
|-&lt;br /&gt;
| ubsan || ||&lt;br /&gt;
 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Follow-on Questions==&lt;br /&gt;
&lt;br /&gt;
* Does g++ support each of these sanitizers?&lt;br /&gt;
* What other tools should I research besides gdb, lldb, valgrind, UBSAN, ASAN, TSAN, and MSAN?&lt;br /&gt;
* Are there tools other than sanitizers and debuggers I should know about?&lt;br /&gt;
* Are there obsolete tools I should ignore?&lt;br /&gt;
* Are there books that cover C++ topics beyond writing C++? How about how-to guides? (I'll be searching for these next, but do you happen to know any particularly useful and easy to read?&lt;br /&gt;
* In his reply, [[/www.reddit.com/user/Ujjawal-Gupta/|Ujjawal-Gupta]] mentions crash dumps and crash dump tools. I don't know much about them. What good resources on this topic are there for Linux, Windows, and Mac?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
I'm about to start going through the list above for myself. It may take a while.&lt;br /&gt;
&lt;br /&gt;
I'm currently involved in a project with about half a million existing lines of C++ code and want to know what tools I need to work in this environment properly. The application has multi-threaded parts.&lt;br /&gt;
&lt;br /&gt;
I can do basic g++, Debug, DebWithRelInfo, and Release builds using cmake or a pre-defined build script and step through code line-by-line with the gdb in VSCode, but want to become familiar with gdb at the command line.&lt;br /&gt;
&lt;br /&gt;
I want to come up to speed with clang and lldb in vscode.&lt;br /&gt;
&lt;br /&gt;
[[/stackoverflow.com/questions/63978029/setup-lldb-debugging-with-cpp-extension-in-vscode-linux|https://stackoverflow.com/questions/63978029/setup-lldb-debugging-with-cpp-extension-in-vscode-linux]]&lt;br /&gt;
&lt;br /&gt;
== Other Thoughts ==&lt;br /&gt;
&lt;br /&gt;
I need to familiarize myself with other tools available, learn how to enable particular tools in a build, and learn how to use the tool's output.&lt;br /&gt;
&lt;br /&gt;
I want to learn to use tools like UBSAN, ASAN, TSAN, and MSAN effectively and how to switch from g++ to clang when appropriate. I want to learn what tools other than the sanitizers and debuggers above are available.&lt;br /&gt;
&lt;br /&gt;
There's no such thing as free beer! Someone pays for flightgear cloud infrastructure that I personallly benefit from.  So I contribute a little at:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;https://liberapay.com/t3r&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Currently working on:&lt;br /&gt;
&lt;br /&gt;
Git Worktrees with download_and_compile.sh  (done &amp;amp; working)&lt;br /&gt;
&lt;br /&gt;
Web Socket Refactor &amp;amp; Fix.  &lt;br /&gt;
&lt;br /&gt;
OSM (Open Street Map) Scenery Build (on hold)&lt;br /&gt;
&lt;br /&gt;
Goals (Maybe)&lt;br /&gt;
&lt;br /&gt;
*Download Scenery from Current Scenery Developers&lt;br /&gt;
*Build Scripts for Scenery Land Class, Elevation, and OSM processing&lt;br /&gt;
*Understand the underlying formats in Flightgear Scenery&lt;br /&gt;
*Understand the processing of Scenery data between tiles in the build process and the running simulator&lt;br /&gt;
*Assist Scenery Developers with technical support.&lt;br /&gt;
*full explanation of the advantages and disadvantages of the worktree approach.&lt;br /&gt;
&lt;br /&gt;
[[Hackathon Proposal: Property Subscription Improvements|Hackathon-2023-Proposal-Websocket-Property-Subscription-Improvements]]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=139896</id>
		<title>User:Callahanp</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=139896"/>
		<updated>2024-05-30T16:12:30Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: formatting&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
==Start With==&lt;br /&gt;
&lt;br /&gt;
*[[/cmake.org/getting-started/|https://cmake.org/getting-started/]] -- Build using g++ and clang.&lt;br /&gt;
*[[/learn.microsoft.com/en-us/vcpkg/|https://learn.microsoft.com/en-us/vcpkg/]] -- cross-platform C/C++ package manager&lt;br /&gt;
*[[/www.sourceware.org/gdb/|https://www.sourceware.org/gdb/]] or [[/lldb.llvm.org/|https://lldb.llvm.org/]] -- Debuggers&lt;br /&gt;
*[[/github.com/google/sanitizers|https://github.com/google/sanitizers]] -- Read about each of the available sanitizers&lt;br /&gt;
*[[/valgrind.org/docs/manual/quick-start.html|https://valgrind.org/docs/manual/quick-start.html]] -- A suite of debugging and profiling tools&lt;br /&gt;
*A review of all the options for each tool you want to acquire.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Follow-on Questions==&lt;br /&gt;
&lt;br /&gt;
* Does g++ support each of these sanitizers?&lt;br /&gt;
*What other tools should I research besides gdb, lldb, valgrind, UBSAN, ASAN, TSAN, and MSAN?&lt;br /&gt;
*Are there tools other than sanitizers and debuggers I should know about?&lt;br /&gt;
*Are there obsolete tools I should ignore?&lt;br /&gt;
*Are there books that cover C++ topics beyond writing C++? How about how-to guides? (I'll be searching for these next, but do you happen to know any particularly useful and easy to read?&lt;br /&gt;
*In his reply, [[/www.reddit.com/user/Ujjawal-Gupta/|Ujjawal-Gupta]] mentions crash dumps and crash dump tools. I don't know much about them. What good resources on this topic are there for Linux, Windows, and Mac?&lt;br /&gt;
&lt;br /&gt;
=## Background:=&lt;br /&gt;
I'm about to start going through the list above for myself. It may take a while.&lt;br /&gt;
&lt;br /&gt;
I'm currently involved in a project with about half a million existing lines of C++ code and want to know what tools I need to work in this environment properly. The application has multi-threaded parts.&lt;br /&gt;
&lt;br /&gt;
I can do basic g++, Debug, DebWithRelInfo, and Release builds using cmake or a pre-defined build script and step through code line-by-line with the gdb in VSCode, but want to become familiar with gdb at the command line.&lt;br /&gt;
&lt;br /&gt;
I want to come up to speed with clang and lldb in vscode.&lt;br /&gt;
&lt;br /&gt;
[[/stackoverflow.com/questions/63978029/setup-lldb-debugging-with-cpp-extension-in-vscode-linux|https://stackoverflow.com/questions/63978029/setup-lldb-debugging-with-cpp-extension-in-vscode-linux]]&lt;br /&gt;
== Other Thoughts ==&lt;br /&gt;
&lt;br /&gt;
I need to familiarize myself with other tools available, learn how to enable particular tools in a build, and learn how to use the tool's output.&lt;br /&gt;
&lt;br /&gt;
I want to learn to use tools like UBSAN, ASAN, TSAN, and MSAN effectively and how to switch from g++ to clang when appropriate. I want to learn what tools other than the sanitizers and debuggers above are available.&lt;br /&gt;
&lt;br /&gt;
There's no such thing as free beer! Someone pays for flightgear cloud infrastructure that I personallly benefit from.  So I contribute a little at:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;https://liberapay.com/t3r&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Currently working on:&lt;br /&gt;
&lt;br /&gt;
Git Worktrees with download_and_compile.sh  (done &amp;amp; working)&lt;br /&gt;
&lt;br /&gt;
Web Socket Refactor &amp;amp; Fix.  &lt;br /&gt;
&lt;br /&gt;
OSM (Open Street Map) Scenery Build (on hold)&lt;br /&gt;
&lt;br /&gt;
Goals (Maybe)&lt;br /&gt;
&lt;br /&gt;
*Download Scenery from Current Scenery Developers&lt;br /&gt;
*Build Scripts for Scenery Land Class, Elevation, and OSM processing&lt;br /&gt;
*Understand the underlying formats in Flightgear Scenery&lt;br /&gt;
*Understand the processing of Scenery data between tiles in the build process and the running simulator&lt;br /&gt;
*Assist Scenery Developers with technical support.&lt;br /&gt;
*full explanation of the advantages and disadvantages of the worktree approach.&lt;br /&gt;
&lt;br /&gt;
[[Hackathon Proposal: Property Subscription Improvements|Hackathon-2023-Proposal-Websocket-Property-Subscription-Improvements]]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=139895</id>
		<title>User:Callahanp</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=139895"/>
		<updated>2024-05-30T16:08:49Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: What I'm really doing&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
==Start With==&lt;br /&gt;
&lt;br /&gt;
*[[/cmake.org/getting-started/|https://cmake.org/getting-started/]] -- Build using g++ and clang.&lt;br /&gt;
*[[/learn.microsoft.com/en-us/vcpkg/|https://learn.microsoft.com/en-us/vcpkg/]] -- cross-platform C/C++ package manager&lt;br /&gt;
*[[/www.sourceware.org/gdb/|https://www.sourceware.org/gdb/]] or [[/lldb.llvm.org/|https://lldb.llvm.org/]] -- Debuggers&lt;br /&gt;
*[[/github.com/google/sanitizers|https://github.com/google/sanitizers]] -- Read about each of the available sanitizers&lt;br /&gt;
*[[/valgrind.org/docs/manual/quick-start.html|https://valgrind.org/docs/manual/quick-start.html]] -- A suite of debugging and profiling tools&lt;br /&gt;
*A review of all the options for each tool you want to acquire.&lt;br /&gt;
&lt;br /&gt;
==Follow-on Questions==&lt;br /&gt;
&lt;br /&gt;
* Does g++ support each of these sanitizers?&lt;br /&gt;
*What other tools should I research besides gdb, lldb, valgrind, UBSAN, ASAN, TSAN, and MSAN?&lt;br /&gt;
*Are there tools other than sanitizers and debuggers I should know about?&lt;br /&gt;
*Are there obsolete tools I should ignore?&lt;br /&gt;
*Are there books that cover C++ topics beyond writing C++? How about how-to guides? (I'll be searching for these next, but do you happen to know any particularly useful and easy to read?&lt;br /&gt;
*In his reply, [[/www.reddit.com/user/Ujjawal-Gupta/|Ujjawal-Gupta]] mentions crash dumps and crash dump tools. I don't know much about them. What good resources on this topic are there for Linux, Windows, and Mac?&lt;br /&gt;
&lt;br /&gt;
=## Background:=&lt;br /&gt;
I'm about to start going through the list above for myself. It may take a while.&lt;br /&gt;
&lt;br /&gt;
I'm currently involved in a project with about half a million existing lines of C++ code and want to know what tools I need to work in this environment properly. The application has multi-threaded parts.&lt;br /&gt;
&lt;br /&gt;
I can do basic g++, Debug, DebWithRelInfo, and Release builds using cmake or a pre-defined build script and step through code line-by-line with the gdb in VSCode, but want to become familiar with gdb at the command line.&lt;br /&gt;
&lt;br /&gt;
I want to come up to speed with clang and lldb in vscode.&lt;br /&gt;
&lt;br /&gt;
[[/stackoverflow.com/questions/63978029/setup-lldb-debugging-with-cpp-extension-in-vscode-linux|https://stackoverflow.com/questions/63978029/setup-lldb-debugging-with-cpp-extension-in-vscode-linux]]&lt;br /&gt;
&lt;br /&gt;
I need to familiarize myself with other tools available, learn how to enable particular tools in a build, and learn how to use the tool's output.&lt;br /&gt;
&lt;br /&gt;
I want to learn to use tools like UBSAN, ASAN, TSAN, and MSAN effectively and how to switch from g++ to clang when appropriate. I want to learn what tools other than the sanitizers and debuggers above are available.&lt;br /&gt;
&lt;br /&gt;
There's no such thing as free beer! Someone pays for flightgear cloud infrastructure that I personallly benefit from.  So I contribute a little at:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;https://liberapay.com/t3r&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Currently working on:&lt;br /&gt;
&lt;br /&gt;
Git Worktrees with download_and_compile.sh&lt;br /&gt;
&lt;br /&gt;
Web Socket Refactor &amp;amp; Fix.  &lt;br /&gt;
&lt;br /&gt;
OSM (Open Street Map) Scenery Build &lt;br /&gt;
&lt;br /&gt;
Goals (Maybe)&lt;br /&gt;
&lt;br /&gt;
*Download Scenery from Current Scenery Developers&lt;br /&gt;
*Build Scripts for Scenery Land Class, Elevation, and OSM processing&lt;br /&gt;
*Understand the underlying formats in Flightgear Scenery&lt;br /&gt;
*Understand the processing of Scenery data between tiles in the build process and the running simulator&lt;br /&gt;
*Assist Scenery Developers with technical support.&lt;br /&gt;
*full explanation of the advantages and disadvantages of the worktree approach.&lt;br /&gt;
&lt;br /&gt;
[[Hackathon Proposal: Property Subscription Improvements|Hackathon-2023-Proposal-Websocket-Property-Subscription-Improvements]]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Callahanp:Git_Worktrees_with_download_and_compile.sh&amp;diff=139784</id>
		<title>Callahanp:Git Worktrees with download and compile.sh</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Callahanp:Git_Worktrees_with_download_and_compile.sh&amp;diff=139784"/>
		<updated>2024-04-24T20:47:36Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: Created page with &amp;quot;A while ago I encountered the idea of using git worktrees for various branches instead of a single git workspace with stash and switch branches.  I found the idea appealing for a number of reasons, but found that there are advantages and disadvantages to both approaches.  A bit of explanation of both methods. {| class=&amp;quot;wikitable&amp;quot; |+ Two Approaches to the problem of concurrent work on multiple branches |- ! Single Worktree !! Separate Git Worktrees |- | A user might have...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A while ago I encountered the idea of using git worktrees for various branches instead of a single git workspace with stash and switch branches.  I found the idea appealing for a number of reasons, but found that there are advantages and disadvantages to both approaches.&lt;br /&gt;
&lt;br /&gt;
A bit of explanation of both methods.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Two Approaches to the problem of concurrent work on multiple branches&lt;br /&gt;
|-&lt;br /&gt;
! Single Worktree !! Separate Git Worktrees&lt;br /&gt;
|-&lt;br /&gt;
| A user might have just one, or several complete clones of a set of repositories.  Each of these clones would have a single worktree. If working on multiple branches the user might simply do the work on a separate set of clones, or they could use a single set by using git stash to move between branches.&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Reasons for adoption of one approach or the other might include&lt;br /&gt;
* A need to quickly produce separate builds for next, stable and lts versions&lt;br /&gt;
* A need to work on changes to multiple branches in parallel&lt;br /&gt;
* Comple&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Advantages&lt;br /&gt;
|-&lt;br /&gt;
! Single Worktree !! Separate Git Worktrees&lt;br /&gt;
|-&lt;br /&gt;
| Good for doing one thing at a time || Multitasking&lt;br /&gt;
|-&lt;br /&gt;
| Simple to change context: move to a different directory, or stash current branch work, switch branches as needed and continue|| Multiple contexts are all set up and ready to go&lt;br /&gt;
|-&lt;br /&gt;
| Less to keep track of || &lt;br /&gt;
|-&lt;br /&gt;
|  || Faster Context Switching&lt;br /&gt;
|-&lt;br /&gt;
|  || Worktrees take up less space than a &lt;br /&gt;
|-&lt;br /&gt;
| Sequential Builds || Parallel Builds&lt;br /&gt;
|-&lt;br /&gt;
| 1 script sets up your environment. It's all you need. || Configuration file covers multiple working contexts in an easy to read format&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Disadvantages&lt;br /&gt;
|-&lt;br /&gt;
! Single Worktree !! Separate Git Worktrees&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
Manually track all the contexts in which you wish to work || More active contexts - You'll need tools to manage the complexity&lt;br /&gt;
|-&lt;br /&gt;
| When the work gets complex, managing it manually becomes harder || Definitely more complex, but then it supports very complex needs.&lt;br /&gt;
|-&lt;br /&gt;
| Multiple full copies of repositories in some situations || Requires some configuration to avoid manually setting up each working context.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=139783</id>
		<title>User:Callahanp</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Callahanp&amp;diff=139783"/>
		<updated>2024-04-24T19:12:34Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;There's no such thing as free beer! Someone pays for flightgear cloud infrastructure that I personallly benefit from.  So I contribute a little at:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;https://liberapay.com/t3r&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Currently working on:&lt;br /&gt;
&lt;br /&gt;
Git Worktrees with download_and_compile.sh&lt;br /&gt;
&lt;br /&gt;
Web Socket Refactor &amp;amp; Fix.  &lt;br /&gt;
&lt;br /&gt;
OSM (Open Street Map) Scenery Build &lt;br /&gt;
&lt;br /&gt;
Goals (Maybe)&lt;br /&gt;
&lt;br /&gt;
* Download Scenery from Current Scenery Developers&lt;br /&gt;
* Build Scripts for Scenery Land Class, Elevation, and OSM processing&lt;br /&gt;
* Understand the underlying formats in Flightgear Scenery&lt;br /&gt;
* Understand the processing of Scenery data between tiles in the build process and the running simulator&lt;br /&gt;
* Assist Scenery Developers with technical support.&lt;br /&gt;
* full explanation of the advantages and disadvantages of the worktree approach.&lt;br /&gt;
&lt;br /&gt;
[[Hackathon Proposal: Property Subscription Improvements|Hackathon-2023-Proposal-Websocket-Property-Subscription-Improvements]]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Software_testing&amp;diff=139770</id>
		<title>Software testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Software_testing&amp;diff=139770"/>
		<updated>2024-04-22T17:02:11Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Note|There’s already the test_suite in {{fg src file|path=test_suite}} using [[Cppunit effort|CppUnit]], thanks to some hard work by [[User:Bugman|Edward]]. We need more tests written for it; submissions are welcome. (Pick an area of interest)&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36972720/&amp;lt;/ref&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{See also|Cppunit effort}}&lt;br /&gt;
&lt;br /&gt;
FlightGear developers use various testing tools. This includes automated testing via unit tests in [[SimGear]] and a full test suite with multiple test categories in the [[FlightGear Git|flightgear repository]], as well as manual in-sim testing. Writing tests is one of the best ways to jump into FlightGear development.&lt;br /&gt;
&lt;br /&gt;
One improving area is unit testing: certain areas and features (e.g., carrier start) now 'can't break.' As we add testing in additional areas (e.g., Multi-player, AI, protocols, and replay are all possible), we increase the baseline quality and have a clearer idea when we make incompatible changes. (The idea is that we capture the 'supported API' in the tests: when an aircraft deviates from that, we can decide to add another test case, fix the aircraft, etc). Of course, there are some pretty significant areas where Automated Testing Is Hard (TM).&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/37078825/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== SimGear ==&lt;br /&gt;
&lt;br /&gt;
Unit testing for the [[SimGear]] sources uses the CMake CTest unit testing infrastructure. Several tests use the BOOST unit testing infrastructure tied to the build system using CTest; however, the FlightGear developers are shifting towards eliminating BOOST, so CPPUnit and CTest tests are preferred.&lt;br /&gt;
&lt;br /&gt;
=== Building and running the SimGear tests ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ make&lt;br /&gt;
$ ctest&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== FlightGear ==&lt;br /&gt;
&lt;br /&gt;
Testing of the [[FlightGear Git|flightgear sources]] is via a comprehensive test suite implemented using [https://www.freedesktop.org/wiki/Software/cppunit/ CppUnit], a port of the famous JUnit framework.&lt;br /&gt;
&lt;br /&gt;
=== Building the test suite ===&lt;br /&gt;
&lt;br /&gt;
You must build FlightGear from the source using cmake to run the tests. See [[Building FlightGear]] for details.&lt;br /&gt;
&lt;br /&gt;
Once you have your cmake build environment, do the following:&lt;br /&gt;
# Change to your FlightGear build* directory&lt;br /&gt;
# Enable building the tests by setting a cmake variable:  &amp;lt;code&amp;gt;cmake -DBUILD_TESTING=ON .&amp;lt;/code&amp;gt;&lt;br /&gt;
# Ensure the &amp;lt;code&amp;gt;[[$FG ROOT|$FG_ROOT]]&amp;lt;/code&amp;gt; environment variable points to fgdata e.g. &amp;lt;code&amp;gt;$FG_INSTALL_DIR/share/fgdata&amp;lt;/code&amp;gt;&lt;br /&gt;
# Build the test suite:  &amp;lt;code&amp;gt;make test_suite&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Building the test suite will also run a test because you will typically want to write a test and then immediately compile and run it.&lt;br /&gt;
&lt;br /&gt;
 * ls in this directory should include CMakeCache.txt, cmake_install, and others. You do not want to run cmake in the flightgear sources directory, which includes files such as AUTHORS, COPYING, INSTALL, etc.&lt;br /&gt;
&lt;br /&gt;
On a Windows MSVC-based build environment, after generating files with cmake, run the following code:&lt;br /&gt;
# cmake --build . --config RelWithDebInfo --target test_suite/test_suite&lt;br /&gt;
&lt;br /&gt;
=== Running the test suite ===&lt;br /&gt;
&lt;br /&gt;
To run the test suite, simply run &amp;lt;code&amp;gt;./test_suite/fgfs_test_suite&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Executing fgfs_test_suite will run the entire test suite and print a Synopsis of results, as shown below.&lt;br /&gt;
&lt;br /&gt;
 Synopsis&lt;br /&gt;
 ========&lt;br /&gt;
 &lt;br /&gt;
 System/functional tests ....................................... [ OK ]&lt;br /&gt;
 Unit tests .................................................... [ OK ]&lt;br /&gt;
 Simgear unit tests ............................................ [ OK ]&lt;br /&gt;
 FGData tests .................................................. [ OK ]&lt;br /&gt;
 Synopsis ...................................................... [ OK ]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also run individual test cases. Run &amp;lt;code&amp;gt;./test_suite/fgfs_test_suite -h&amp;lt;/code&amp;gt; to see the various options&lt;br /&gt;
&lt;br /&gt;
For example, fgfs_test_suite --log-level=alert -d -u GPSTests will run the GPS unit tests while displaying the output.&lt;br /&gt;
&lt;br /&gt;
=== Why write unit tests? ===&lt;br /&gt;
&lt;br /&gt;
A well-tested piece of software will have a much lower bug count/load. An extensive test suite with &amp;quot;'unit tests,'&amp;quot; system/functional tests, GUI tests, installer tests, and other categories of tests can significantly help in this regard.&lt;br /&gt;
&lt;br /&gt;
The benefits of not just chasing clear &amp;quot;wins&amp;quot; are great: An excellent learning experience for new developers; the ability to catch latent, unreported bugs; making it easier to refactor current code by creating a safety net; making it easier for current developers to accept new contributions (when accompanied with passing tests); helping other test writers by contributing to the standard test suite infrastructure; and being able to check for memory leaks or other issues via Valgrind easily.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36977686/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you are a new developer, jump in and write any test! It does not need to catch a bug. Do whatever you wish! Just dive into this shallow end, and you'll see that the water is not cold.&lt;br /&gt;
&lt;br /&gt;
You are writing a test as a safety net. You write the test to pass, make your changes, and then make sure that the test still passes. Then, you push both the test and core changes.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36977465/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It'd be better to work in a specific area of interest to you and submit merge requests. When reviewed, that would usually trigger some C++ feedback, but we aren't looking for perfection here. The feedback you receive during the open and public review process increases our overall pool of knowledge of what best practice looks like, even if a given commit is less than perfect.&lt;br /&gt;
&lt;br /&gt;
Having 10 or 20 people actively contributing correct and reasonable code is more important than three people contributing perfect, micro-optimised C++. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36951247/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Benefits of unit testing ===&lt;br /&gt;
There are lots of benefits to writing tests that pass.&lt;br /&gt;
&lt;br /&gt;
Benefits include :&lt;br /&gt;
&lt;br /&gt;
* Learning! New developers can learn a ton from writing several passing tests in the area they are interested in. This is one of the quickest ways to learn about a pre-existing and mature code base. You have zero worries about breaking things.&lt;br /&gt;
&lt;br /&gt;
* Latent bug uncovering. One will probably fail every ten tests you write, expecting them to pass. Tests may uncover unexpected behavior that a developer can improve.&lt;br /&gt;
&lt;br /&gt;
* Refactoring. If we had 10,000 passing tests (assuming universal test coverage), large-scale refactoring of the entire code base would be quick and reliable. It would enable refactoring on a scale currently unimaginable. I cannot emphasize enough how much of a benefit this would be.&lt;br /&gt;
&lt;br /&gt;
* Developer turnover. Again, if we had 10,000 passing tests (assuming universal test coverage), it would encourage new developers, giving them confidence that their changes will not cause problems. It is a safety net. It also would provide existing developers peace of mind when a new developer works in one of the dark parts of FlightGear that no current developer understands (there are plenty of those).&lt;br /&gt;
&lt;br /&gt;
* Test suite infrastructure. The more passing tests written, the better the test suite infrastructure will become. We can already do a lot, but adding more passing tests will help other test writers.&lt;br /&gt;
&lt;br /&gt;
* Memory checking. Running a single test through Valgrind is fantastic. Running FlightGear through Valgrind is close to impossible. One can write tests that pass but are useful under Valgrind to catch memory leaks!&lt;br /&gt;
&lt;br /&gt;
* Code quality and standards. If a test compiles on all OSes without warning, it passes, and Valgrind gives you an ok, it is good enough. You don't need to be a C++ expert to dive into this shallow end of the pool.&lt;br /&gt;
&lt;br /&gt;
=== Bootstrapping completely new tests ===&lt;br /&gt;
To start diving straight into the test suite code, firstly copy what has been done in this commit:  {{repo link&lt;br /&gt;
| site   = sf&lt;br /&gt;
| user = edauvergne&lt;br /&gt;
| repo   = flightgear&lt;br /&gt;
| commit = 8474df&lt;br /&gt;
| view   = commit&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Just modify all names for a JSBSim test (or any other test fixture you&lt;br /&gt;
want to code). You should then be able to compile and check that your&lt;br /&gt;
new test dummy () test passes as expected. You can then slowly build up&lt;br /&gt;
from this basic infrastructure as you learn the fgfs internals, c++,&lt;br /&gt;
and git skills required for implementing your test on your fork's new&lt;br /&gt;
development branch :)&lt;br /&gt;
&lt;br /&gt;
=== Headless testing ===&lt;br /&gt;
{{Main article|FlightGear Headless}}&lt;br /&gt;
&lt;br /&gt;
For an FDM+systems test, we should run FG without a renderer (which is what the test_suite does) to benchmark the pure C++ performance of whatever system we care about (FDM or whatever). But a few hours playing with 'perf' on Linux or Instruments on macOS will show you that OSG + the GL drivers use 80% of our CPU time, and hence Amdhal's law will always get you.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36977666/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Graphics testing ===&lt;br /&gt;
{{See also|FlightGear Benchmark}}&lt;br /&gt;
&lt;br /&gt;
Create test-case scenes where you can quickly measure differences and compare via screenshots. The brain/eye/memory are terrible at this stuff, setup something you can load from the command line via a script to test old/new versions, if possible. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36959002/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, a test would use several rc files (.[[fgfsrc]] variants, with different renderers and threading modes, including static values for:&lt;br /&gt;
* c172p at some parking in a detailed airport&lt;br /&gt;
* camera set with a specific direction and field of view&lt;br /&gt;
* AW with specific METARs around (if not possible, BW with specific METAR)&lt;br /&gt;
* fixed rendering settings ( &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36975122/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We can load a [[Instant Replay|replay tape]] on startup. Since the FDM and User interface are unavailable, replays are suitable for testing rendering and performance.&lt;br /&gt;
&lt;br /&gt;
But essentially, small amounts of shell script + Nasal hacking, can implement any of these methods,  and any of them would be welcome additions. The unit-test framework is excellent for lower-level tests run by developers (i.e., 'Does the API call produce the right results in the system?'), but a smoke test that regular users can run would be ideal. &lt;br /&gt;
&lt;br /&gt;
A rendering performance would likely do the following:&lt;br /&gt;
&lt;br /&gt;
* Select some particular rendering settings (clouds, draw distance, etc)&lt;br /&gt;
* Run a saved fgtape recording&lt;br /&gt;
* Record the mean/min/max FPS during this and save it in some text file/copy to the clipboard&lt;br /&gt;
&lt;br /&gt;
So yes, if anyone wants to work on the above, the code is all there. Please jump in and start hacking. I don't think it needs any more from the core code, but as always, please ask if it does.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36975213/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, when describing a /rendering/ test (to establish FPS), the advantage of a replay tape is that the actual position (and, therefore, the rendered scene) will be 100% consistent across different computers.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that the CPU use of the FDM+systems is typically &amp;lt; 10% of our total CPU use, even when running OSG single-threaded, so for a rendering performance test, whether the FD is run or not is probably noise compared to other things that do run (Nasal, Canvas for example)&lt;br /&gt;
&lt;br /&gt;
Also, the Multi-monitor setup is an area that could use additional unit testing. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36904782/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fgdata ==&lt;br /&gt;
=== Nasal scripting (comments) ===&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
The now builtin CppUnit framework can solve all the issues&lt;br /&gt;
identified in the old [[Nasal Unit Testing Framework]] wiki article and the discussions it points to&lt;br /&gt;
and provide the full framework required.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36990615/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have some very simple tests running now for the route manager, which relies on Nasal. We're skipping a few of the bigger Nasal modules (local weather, jetways) and have a few lingering issues in some other modules, but the basic concept is working. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
An exciting further step, which you might wish to discuss with Edward, is writing test checks *in* Nasal since this could be quite a fast way to test some areas of the code. There are several ways that could work, and I don't know if Edward has always planned something around this, so I won't preempt that conversation.&lt;br /&gt;
&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36764781/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
we have route-manager tests which validate route_manager.nas is working correctly, and we have Canavs tests ({{fg src file|path=test_suite/simgear_tests/canvas|}}) which poke the Nasal API. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36991200/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We need more FGData testing via the test suite.&lt;br /&gt;
&lt;br /&gt;
James has suggested adding CppUnit assertions to Nasal so others can write tests in pure Nasal. James would make these changes in C++.  &lt;br /&gt;
In addition, some C++ code in a test would scan a directory for files matching a pattern, e.g., test_XYZ.nas, and run each of those automatically.&lt;br /&gt;
&lt;br /&gt;
The idea for testing Nasal would be that you write a small CppUnit&lt;br /&gt;
interface in C++ in $FG_SRC/test_suite/*_tests/ (the FGData Nasal&lt;br /&gt;
testing would be in a fgdata_tests/ directory). This would register&lt;br /&gt;
each test which points to the script in&lt;br /&gt;
$FG_SRC/test_suite/shared_data/nasal/, and the setUp() and tearDown()&lt;br /&gt;
functions would use helper functions in the fgtest namespace to start&lt;br /&gt;
and stop Nasal. The Nasal scripts could then call the CppUnit&lt;br /&gt;
assertion macros wrapped up as Nasal functions for communicating&lt;br /&gt;
failures and errors to the test suite. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36991150/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Scanning for scripts is a great idea. Then, developers (core and content) could write tests using pure Nasal.&lt;br /&gt;
&lt;br /&gt;
However, all scripts found and executed will be seen as a single test within the test suite. So maybe we should have a $FG_SRC/test_suite/nasal_staging/ directory for the initial development of such auto-scanned scripts. But then we have someone shift them into $FG_SRC/test_suite/system_tests/, $FG_SRC/test_suite/unit_tests/, or $FG_SRC/test_suite/fgdata_tests/ later on?  That would give better diagnostics and would avoid long-term clutter.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36991198/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* First, we should probably hard code tests into the C++ framework. For this, the CppUnit assertion macros will have to be wrapped up as Nasal functions.&lt;br /&gt;
* Implement the scanning code as we need some CMake magic (probably using file(COPY, ...)).&lt;br /&gt;
* Finally, we must determine if and how to improve the Nnasaldebugging output.&lt;br /&gt;
&lt;br /&gt;
the code could go into a subdirectory in $FG_SRC/test_suite/fgdata_tests/, and the Nasal script in $FG_SRC/test_suite/shared_data/nasal/.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Core development]]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Software_testing&amp;diff=139769</id>
		<title>Software testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Software_testing&amp;diff=139769"/>
		<updated>2024-04-22T16:52:15Z</updated>

		<summary type="html">&lt;p&gt;Callahanp: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Note|There’s already the test_suite in {{fg src file|path=test_suite}} using [[Cppunit effort|CppUnit]], thanks to some hard work by [[User:Bugman|Edward]]. We need more tests written for it; submissions are welcome. (Pick an area of interest)&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36972720/&amp;lt;/ref&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{See also|Cppunit effort}}&lt;br /&gt;
&lt;br /&gt;
FlightGear developers use various tools. This includes automated testing via unit tests in [[SimGear]] and a full test suite with multiple test categories in the [[FlightGear Git|flightgear repository]], as well as manual in-sim testing. Writing tests is one of the best ways to jump into FlightGear development.&lt;br /&gt;
&lt;br /&gt;
One improving area is unit testing: certain areas and features (e.g., carrier start) now 'can't break.' As we add testing in additional areas (e.g., Multi-player, AI, protocols, and replay are all possible), we increase the baseline quality and have a clearer idea when we make incompatible changes. (The idea is that we capture the 'supported API' in the tests: when an aircraft deviates from that, we can decide to add another test case, fix the aircraft, etc). Of course, there are some pretty significant areas where Automated Testing Is Hard (TM).&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/37078825/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== SimGear ==&lt;br /&gt;
&lt;br /&gt;
Unit testing for the [[SimGear]] sources uses the CMake CTest unit testing infrastructure. Several tests use the BOOST unit testing infrastructure tied to the build system using CTest; however, the FlightGear developers are shifting towards eliminating BOOST, so CPPUnit and CTest tests are preferred.&lt;br /&gt;
&lt;br /&gt;
=== Building and running the SimGear tests ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ make&lt;br /&gt;
$ ctest&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== FlightGear ==&lt;br /&gt;
&lt;br /&gt;
Testing of the [[FlightGear Git|flightgear sources]] is via a comprehensive test suite implemented using [https://www.freedesktop.org/wiki/Software/cppunit/ CppUnit], a port of the famous JUnit framework.&lt;br /&gt;
&lt;br /&gt;
=== Building the test suite ===&lt;br /&gt;
&lt;br /&gt;
You must build FlightGear from the source using cmake to run the tests. See [[Building FlightGear]] for details.&lt;br /&gt;
&lt;br /&gt;
Once you have your cmake build environment, do the following:&lt;br /&gt;
# Change to your FlightGear build* directory&lt;br /&gt;
# Enable building the tests by setting a cmake variable:  &amp;lt;code&amp;gt;cmake -DBUILD_TESTING=ON .&amp;lt;/code&amp;gt;&lt;br /&gt;
# Ensure the &amp;lt;code&amp;gt;[[$FG ROOT|$FG_ROOT]]&amp;lt;/code&amp;gt; environment variable points to fgdata e.g. &amp;lt;code&amp;gt;$FG_INSTALL_DIR/share/fgdata&amp;lt;/code&amp;gt;&lt;br /&gt;
# Build the test suite:  &amp;lt;code&amp;gt;make test_suite&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Building the test suite will also run a test because you will typically want to write a test and then immediately compile and run it.&lt;br /&gt;
&lt;br /&gt;
 * ls in this directory should include CMakeCache.txt, cmake_install, and others. You do not want to run cmake in the flightgear sources directory, which includes files such as AUTHORS, COPYING, INSTALL, etc.&lt;br /&gt;
&lt;br /&gt;
On a Windows MSVC-based build environment, after generating files with cmake, run the following code:&lt;br /&gt;
# cmake --build . --config RelWithDebInfo --target test_suite/test_suite&lt;br /&gt;
&lt;br /&gt;
=== Running the test suite ===&lt;br /&gt;
&lt;br /&gt;
To run the test suite, simply run &amp;lt;code&amp;gt;./test_suite/fgfs_test_suite&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Executing fgfs_test_suite will run the entire test suite and print a Synopsis of results, as shown below.&lt;br /&gt;
&lt;br /&gt;
 Synopsis&lt;br /&gt;
 ========&lt;br /&gt;
 &lt;br /&gt;
 System/functional tests ....................................... [ OK ]&lt;br /&gt;
 Unit tests .................................................... [ OK ]&lt;br /&gt;
 Simgear unit tests ............................................ [ OK ]&lt;br /&gt;
 FGData tests .................................................. [ OK ]&lt;br /&gt;
 Synopsis ...................................................... [ OK ]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also run individual test cases. Run &amp;lt;code&amp;gt;./test_suite/fgfs_test_suite -h&amp;lt;/code&amp;gt; to see the various options&lt;br /&gt;
&lt;br /&gt;
For example, fgfs_test_suite --log-level=alert -d -u GPSTests will run the GPS unit tests while displaying the output.&lt;br /&gt;
&lt;br /&gt;
=== Why write unit tests? ===&lt;br /&gt;
&lt;br /&gt;
A well-tested piece of software will have a much lower bug count/load. An extensive test suite with &amp;quot;'unit tests,'&amp;quot; system/functional tests, GUI tests, installer tests, and other categories of tests can significantly help in this regard.&lt;br /&gt;
&lt;br /&gt;
The benefits of not just chasing clear &amp;quot;wins&amp;quot; are great: An excellent learning experience for new developers; the ability to catch latent, unreported bugs; making it easier to refactor current code by creating a safety net; making it easier for current developers to accept new contributions (when accompanied with passing tests); helping other test writers by contributing to the standard test suite infrastructure; and being able to check for memory leaks or other issues via Valgrind easily.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36977686/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you are a new developer, jump in and write any test! It does not need to catch a bug. Do whatever you wish! Just dive into this shallow end, and you'll see that the water is not cold.&lt;br /&gt;
&lt;br /&gt;
You are writing a test as a safety net. You write the test to pass, make your changes, and then make sure that the test still passes. Then, you push both the test and core changes.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36977465/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It'd be better to work in a specific area of interest to you and submit merge requests. When reviewed, that would usually trigger some C++ feedback, but we aren't looking for perfection here. The feedback you receive during the open and public review process increases our overall pool of knowledge of what best practice looks like, even if a given commit is less than perfect.&lt;br /&gt;
&lt;br /&gt;
Having 10 or 20 people actively contributing correct and reasonable code is more important than three people contributing perfect, micro-optimised C++. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36951247/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Benefits of unit testing ===&lt;br /&gt;
There are lots of benefits to writing tests that pass.&lt;br /&gt;
&lt;br /&gt;
Benefits include :&lt;br /&gt;
&lt;br /&gt;
* Learning! New developers can learn a ton from writing several passing tests in the area they are interested in. This is one of the quickest ways to learn about a pre-existing and mature code base. You have zero worries about breaking things.&lt;br /&gt;
&lt;br /&gt;
* Latent bug uncovering. One will probably fail every ten tests you write, expecting them to pass. Tests may uncover unexpected behavior that a developer can improve.&lt;br /&gt;
&lt;br /&gt;
* Refactoring. If we had 10,000 passing tests (assuming universal test coverage), large-scale refactoring of the entire code base would be quick and reliable. It would enable refactoring on a scale currently unimaginable. I cannot emphasize enough how much of a benefit this would be.&lt;br /&gt;
&lt;br /&gt;
* Developer turnover. Again, if we had 10,000 passing tests (assuming universal test coverage), it would encourage new developers, giving them confidence that their changes will not cause problems. It is a safety net. It also would provide existing developers peace of mind when a new developer works in one of the dark parts of FlightGear that no current developer understands (there are plenty of those).&lt;br /&gt;
&lt;br /&gt;
* Test suite infrastructure. The more passing tests written, the better the test suite infrastructure will become. We can already do a lot, but adding more passing tests will help other test writers.&lt;br /&gt;
&lt;br /&gt;
* Memory checking. Running a single test through Valgrind is fantastic. Running FlightGear through Valgrind is close to impossible. One can write tests that pass but are useful under Valgrind to catch memory leaks!&lt;br /&gt;
&lt;br /&gt;
* Code quality and standards. If a test compiles on all OSes without warning, it passes, and Valgrind gives you an ok, it is good enough. You don't need to be a C++ expert to dive into this shallow end of the pool.&lt;br /&gt;
&lt;br /&gt;
=== Bootstrapping completely new tests ===&lt;br /&gt;
To start diving straight into the test suite code, firstly copy what has been done in this commit:  {{repo link&lt;br /&gt;
| site   = sf&lt;br /&gt;
| user = edauvergne&lt;br /&gt;
| repo   = flightgear&lt;br /&gt;
| commit = 8474df&lt;br /&gt;
| view   = commit&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Just modify all names for a JSBSim test (or any other test fixture you&lt;br /&gt;
want to code). You should then be able to compile and check that your&lt;br /&gt;
new test dummy () test passes as expected. You can then slowly build up&lt;br /&gt;
from this basic infrastructure as you learn the fgfs internals, c++,&lt;br /&gt;
and git skills required for implementing your test on your fork's new&lt;br /&gt;
development branch :)&lt;br /&gt;
&lt;br /&gt;
=== Headless testing ===&lt;br /&gt;
{{Main article|FlightGear Headless}}&lt;br /&gt;
&lt;br /&gt;
For an FDM+systems test, we should run FG without a renderer (which is what the test_suite does) to benchmark the pure C++ performance of whatever system we care about (FDM or whatever). But a few hours playing with 'perf' on Linux or Instruments on macOS will show you that OSG + the GL drivers use 80% of our CPU time, and hence Amdhal's law will always get you.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36977666/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Graphics testing ===&lt;br /&gt;
{{See also|FlightGear Benchmark}}&lt;br /&gt;
&lt;br /&gt;
Create test-case scenes where you can quickly measure differences and compare via screenshots. The brain/eye/memory are terrible at this stuff, setup something you can load from the command line via a script to test old/new versions, if possible. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36959002/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, a test would use several rc files (.[[fgfsrc]] variants, with different renderers and threading modes, including static values for:&lt;br /&gt;
* c172p at some parking in a detailed airport&lt;br /&gt;
* camera set with a specific direction and field of view&lt;br /&gt;
* AW with specific METARs around (if not possible, BW with specific METAR)&lt;br /&gt;
* fixed rendering settings ( &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36975122/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We can load a [[Instant Replay|replay tape]] on startup. Since the FDM and User interface are unavailable, replays are suitable for testing rendering and performance.&lt;br /&gt;
&lt;br /&gt;
But essentially, small amounts of shell script + Nasal hacking, can implement any of these methods,  and any of them would be welcome additions. The unit-test framework is excellent for lower-level tests run by developers (i.e., 'Does the API call produce the right results in the system?'), but a smoke test that regular users can run would be ideal. &lt;br /&gt;
&lt;br /&gt;
A rendering performance would likely do the following:&lt;br /&gt;
&lt;br /&gt;
* Select some particular rendering settings (clouds, draw distance, etc)&lt;br /&gt;
* Run a saved fgtape recording&lt;br /&gt;
* Record the mean/min/max FPS during this and save it in some text file/copy to the clipboard&lt;br /&gt;
&lt;br /&gt;
So yes, if anyone wants to work on the above, the code is all there. Please jump in and start hacking. I don't think it needs any more from the core code, but as always, please ask if it does.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36975213/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, when describing a /rendering/ test (to establish FPS), the advantage of a replay tape is that the actual position (and, therefore, the rendered scene) will be 100% consistent across different computers.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that the CPU use of the FDM+systems is typically &amp;lt; 10% of our total CPU use, even when running OSG single-threaded, so for a rendering performance test, whether the FD is run or not is probably noise compared to other things that do run (Nasal, Canvas for example)&lt;br /&gt;
&lt;br /&gt;
Also, the Multi-monitor setup is an area that could use additional unit testing. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36904782/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fgdata ==&lt;br /&gt;
=== Nasal scripting (comments) ===&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
The now builtin CppUnit framework can solve all the issues&lt;br /&gt;
identified in the old [[Nasal Unit Testing Framework]] wiki article and the discussions it points to&lt;br /&gt;
and provide the full framework required.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36990615/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have some very simple tests running now for the route manager, which relies on Nasal. We're skipping a few of the bigger Nasal modules (local weather, jetways) and have a few lingering issues in some other modules, but the basic concept is working. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
An exciting further step, which you might wish to discuss with Edward, is writing test checks *in* Nasal since this could be quite a fast way to test some areas of the code. There are several ways that could work, and I don't know if Edward has always planned something around this, so I won't preempt that conversation.&lt;br /&gt;
&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36764781/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
we have route-manager tests which validate route_manager.nas is working correctly, and we have Canavs tests ({{fg src file|path=test_suite/simgear_tests/canvas|}}) which poke the Nasal API. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36991200/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We need more FGData testing via the test suite.&lt;br /&gt;
&lt;br /&gt;
James has suggested adding CppUnit assertions to Nasal so others can write tests in pure Nasal. James would make these changes in C++.  &lt;br /&gt;
In addition, some C++ code in a test would scan a directory for files matching a pattern, e.g., test_XYZ.nas, and run each of those automatically.&lt;br /&gt;
&lt;br /&gt;
The idea for testing Nasal would be that you write a small CppUnit&lt;br /&gt;
interface in C++ in $FG_SRC/test_suite/*_tests/ (the FGData Nasal&lt;br /&gt;
testing would be in a fgdata_tests/ directory). This would register&lt;br /&gt;
each test which points to the script in&lt;br /&gt;
$FG_SRC/test_suite/shared_data/nasal/, and the setUp() and tearDown()&lt;br /&gt;
functions would use helper functions in the fgtest namespace to start&lt;br /&gt;
and stop Nasal. The Nasal scripts could then call the CppUnit&lt;br /&gt;
assertion macros wrapped up as Nasal functions for communicating&lt;br /&gt;
failures and errors to the test suite. &amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36991150/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Scanning for scripts is a great idea. Then, developers (core and content) could write tests using pure Nasal.&lt;br /&gt;
&lt;br /&gt;
However, all scripts found and executed will be seen as a single test within the test suite. So maybe we should have a $FG_SRC/test_suite/nasal_staging/ directory for the initial development of such auto-scanned scripts. But then we have someone shift them into $FG_SRC/test_suite/system_tests/, $FG_SRC/test_suite/unit_tests/, or $FG_SRC/test_suite/fgdata_tests/ later on?  That would give better diagnostics and would avoid long-term clutter.&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/mailman/message/36991198/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* First, we should probably hard code tests into the C++ framework. For this, the CppUnit assertion macros will have to be wrapped up as Nasal functions.&lt;br /&gt;
* Implement the scanning code as we need some CMake magic (probably using file(COPY, ...)).&lt;br /&gt;
* Finally, we must determine if and how to improve the Nnasaldebugging output.&lt;br /&gt;
&lt;br /&gt;
the code could go into a subdirectory in $FG_SRC/test_suite/fgdata_tests/, and the Nasal script in $FG_SRC/test_suite/shared_data/nasal/.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Core development]]&lt;/div&gt;</summary>
		<author><name>Callahanp</name></author>
	</entry>
</feed>