lib/Request.php:196: Warning[2]: session_start(): open(/tmp/sess_1837f93082c2632cae37b7a8b3ac3ec0, O_RDWR) failed: Permission denied (13)
In order to support the testing process we intend to follow, it is necessary for developers to follow a small set of rules while developing. These rules are as follows:
All code must be formatted with astyle using the --style=ansi command line option or an equivalent that formats in ANSI format style.
Every non-GUI class must have at least single Unit Test suite in the tests directory. GUI classes should have a Unit Test also, but that might not be possible (yet).
The Unit Test suite must be named after the class it is testing, with "Test.h" at the end. So, if I'm testing FooClass, then the test suite is called FooClassTest.h (.h is just your standard header file ending, and is used by CxxTest).
Every function in the class being tested must have a corresponding test function in the test suite. You may combine tests for more than one function if the functions are related (like get/set pairs, sequence pairs, etc.) or if it just makes sense.
Every test function must have a documentation comment that lists the functions it actually tests. You should also list anything weird about your test, like it requires access to the Internet.
Every test class must have a documentation comment that gives a general overview of the test, and what class it is testing. It should also list any other classes that it uses, just in case those break too.
The test suite should use test fixtures to initialize necessary data for the tests and to clean up after a test. The fixtures should ensure that the configuration they create is correct before they end (i.e. verify that allocated memory worked). This is best done using the Dbg library facilities. In the CxxTest system, this is done with setUp and tearDown functions.
Each test function should also ensure that the fixture ran correctly for its needs. This double checking makes sure that changes to the fixture don't break tests. Again, use the Dbg library facilities to do this.
Every class must have a class level documentation comment that describes:
The purpose of the class.
How to use the class.
The corresponding test suite.
The class's invariants (what states the class cannot be in).
Any potential bugs and things to do.
And any other comments necessary to understand the class.
Every function (in a class class or not) must have a documentation comment that describes:
The purpose of the function.
The function pre-conditions (what it expects as inputs, what is not allowed)
The function post-conditions (what it guarantees when it is done)
How to use the function.
Any potential bugs or things to do.
Every function must be written in a certain format that leverages the Dbg library to ensure that the function is working correctly and gives debugging information. The format is:
The function begins with an INVARIANT(L,C,F) definition which defines what invariant function to run (described later).
A TRACE() call then follows so that function calls can be logged and traced appropriately.
It then has a series of ASSERT(T) calls to verify that the pre-conditions are correct. This completes the header of the function.
The body of the function then follows which will utilize the rest of the Dbg library to print diagnostic information. The body should use the following macros for additional verification during function operation:
LOG(L,MSG) This logs a message to the current logging output. L is the level (info, error, etc.) and MSG is what you want to say. You can do anything you'd send to cout as a MSG, like: LOG(info, "this has ran" << 12 << "times");
BOUNDS(A,I) This verifies that the index I is within the bounds of array A. This should be called before each array access.
ASSERT(T) This is the usual assertion mechanism.
CHECK_PTR(P) This verifies that a pointer is not NULL (or, is valid). You should initialize all pointers to NULL or attempt to initialize right away. Then, before you use them, use CHECK_PTR(P) to verify it.
UNIMPLEMENTED() This is placed at any point where someone tries to use an UNIMPLEMENTED() feature.
SENTINEL() This is placed at points that should not be reached.
The footer of the function must have ASSERT(T) calls and CHECK_PTR(P) calls that ensure the post-conditions are met properly.
Every class must have an invariant function which is used by all functions with the INVARIANT(L,C,F) macro to ensure that each object is not in an incorrect state. This invariant function should do the smallest amount of verification possible, since it will most likely be called many times. To accomplish this, it should only verify that the object does not have an incorrect state.In multi-threaded applications, this invariant may cause a lot of problems. It will be dropped if it is not possible to properly verify the state of a multi-threaded object without intrusive locking procedures.
Other than that, there are not a lot of requirements on the development at this time. The thing to keep in mind is that each of these will be reviewed periodically for success and adapted as necessary. Since this is such a small project, it will be possible to enforce naming conventions and other coding conventions through example in the code. As new conventions are developed which need to be documented, I'll add them here.
Unknown:0: Warning[2]: Unknown(): open(/tmp/sess_1837f93082c2632cae37b7a8b3ac3ec0, O_RDWR) failed: Permission denied (13)
Unknown:0: Warning[2]: Unknown(): Failed to write session data (files). Please verify that the current setting of session.save_path is correct (/tmp)