To create an error human readable message should be provided among other argmunts.
Which is good to better understanding what happend by log records.
To make it more informative user in most cases should put in those message some data (numbers, strings etc.).
This operator will help us to avoid using verbose constructions like boost::format or std::ostringstream or something similar to format a proper error message.
We will be able just to "stream" in a created error any "printable" variables from the context.
Additionaly we will be able to use "fancy" tools for streams like boost::io::quoted or std::hex to format messages.
Example:
```c++
createError(SystemErorr::NoSuchFile, "Could not read pidfile: ")
<< boost::io::quoted(pidfile_path)
<< " " << read_status.toString();
```
* adding bash_session logging
* adding genShellHistoryFromBashSessions
updated to include new function for adding bash_sessions
* adding genShellHistoryFromBashSessions and tests and header
updated test use canonical for filepath
updated to include new function for adding bash_sessions
* Connecte expected.h and error.h tests to build system
% ./build/darwin/osquery/osquery_tests --gtest_filter='Expected*'
Note: Google Test filter = Expected*
[==========] Running 0 tests from 0 test cases.
[==========] 0 tests from 0 test cases ran. (0 ms total)
[ PASSED ] 0 tests.
% ./build/darwin/osquery/osquery_tests --gtest_filter='Expected*'
Note: Google Test filter = Expected*
[==========] Running 2 tests from 2 test cases.
[----------] Global test environment set-up.
[----------] 1 test from ExpectedValueTest
[ RUN ] ExpectedValueTest.initialization
[ OK ] ExpectedValueTest.initialization (0 ms)
[----------] 1 test from ExpectedValueTest (0 ms total)
[----------] 1 test from ExpectedPointerTest
[ RUN ] ExpectedPointerTest.initialization
[ OK ] ExpectedPointerTest.initialization (0 ms)
[----------] 1 test from ExpectedPointerTest (0 ms total)
[----------] Global test environment tear-down
[==========] 2 tests from 2 test cases ran. (0 ms total)
[ PASSED ] 2 tests.
* Check error message and name of error enum separatelly
Different compilers produce different names for C++ classes
Consider this PR as a cosmetic one.
Creating Status class object in the code is not so clear. It is not so obvious that defatult costructed Status is success. Also it is not obvious that status with zero code is success and non-zero is failure.
To fix it I created 2 static methods to make construction of some particular status clear to reader.
* Use assert to check code in Status::failure in debut mode
* Rename success_code constant to kSuccessCode
according to style guide
If the shell history file does not contain a timestamps for the lines
osquery will miss the time in rows and will show an confusing error
about attempt to convert empty string to INTEGER.
```
% head -n 3 ~/.zsh_history
ls
cd source
ls
```
```
osquery> select * from shell_history limit 1;
I0621 11:56:37.804193 2629124992 virtual_table.cpp:292] Error casting time () to INTEGER
+------------+------+---------+-------------------------------+
| uid | time | command | history_file |
+------------+------+---------+-------------------------------+
| 1868255265 | | exit | /home/akindyakov/.zsh_history |
+------------+------+---------+-------------------------------+
```
So, default value for the time in shell history can solve the problem.
osquery itself does not care about unicode validity in table columns,
just takes it "as is". It definetely makes sense, because it could be broken.
But thrift extensions interface for python do it.
If, for instance, shell history contains broken unicode test `python_test_example_queries`
will fail.
```bash
% sed -n '5277p' < ~/.zsh_history | xxd -b [146]
00000000: 11000011 10000011 10111111 01101100 01110011 00001010 ...ls.
```