got rid of all the absolute paths in the fitpc code
Previously, there were 2 places (BinaryLogReader and the HTTP file server) that
had "/home/driver/" hard coded. I changed both of those to use paths relative to
the location of the executable (retrieved from /proc/self/exe).
git-svn-id: https://robotics.mvla.net/svn/frc971/2013/trunk/src@4162 f308d9b7-e957-4cde-b6ac-9a88185e7312
diff --git a/aos/common/once_test.cc b/aos/common/once_test.cc
new file mode 100644
index 0000000..ed21b37
--- /dev/null
+++ b/aos/common/once_test.cc
@@ -0,0 +1,128 @@
+#include "aos/common/once.h"
+
+#include "stdlib.h"
+#include "limits.h"
+
+#include "gtest/gtest.h"
+
+namespace aos {
+namespace testing {
+
+class OnceTest : public ::testing::Test {
+ public:
+ static int *Function() {
+ ++times_run_;
+ value_ = rand() % INT_MAX;
+ return &value_;
+ }
+
+ protected:
+ void SetUp() {
+ value_ = 0;
+ times_run_ = 0;
+ }
+
+ static int value_;
+ static int times_run_;
+};
+int OnceTest::value_, OnceTest::times_run_;
+
+// Makes sure that it calls the function at the right time and that it correctly
+// passes the result out.
+TEST_F(OnceTest, Works) {
+ static Once<int> once(Function);
+
+ EXPECT_EQ(0, value_);
+ EXPECT_EQ(0, times_run_);
+
+ EXPECT_EQ(value_, *once.Get());
+ EXPECT_NE(0, value_);
+ EXPECT_NE(0, times_run_);
+ // Make sure it's not passing it through an assignment by value or something
+ // else weird.
+ EXPECT_EQ(&value_, once.Get());
+}
+
+// Makes sure that having a Once at namespace scope works correctly.
+namespace {
+
+Once<int> global_once(OnceTest::Function);
+
+} // namespace
+
+TEST_F(OnceTest, Global) {
+ EXPECT_EQ(value_, *global_once.Get());
+ EXPECT_NE(0, value_);
+ EXPECT_NE(0, times_run_);
+}
+
+// Makes sure that an instance keeps returning the same value without running
+// the function again.
+TEST_F(OnceTest, MultipleGets) {
+ static Once<int> once(Function);
+
+ EXPECT_EQ(value_, *once.Get());
+ EXPECT_EQ(1, times_run_);
+ EXPECT_EQ(value_, *once.Get());
+ EXPECT_EQ(1, times_run_);
+ EXPECT_EQ(value_, *once.Get());
+ EXPECT_EQ(1, times_run_);
+}
+
+// Tests to make sure that the right methods clear out the instance variables at
+// the right times.
+TEST_F(OnceTest, MemoryClearing) {
+ Once<int> once(NULL);
+
+ once.run_ = 1;
+ once.done_ = true;
+ // Run the constructor again to make sure it doesn't touch the variables set
+ // above.
+ new (&once)Once<int>(Function);
+
+ // Should return a random, (potentially) uninitialized value.
+ once.Get();
+ EXPECT_EQ(0, times_run_);
+
+ once.Reset();
+ EXPECT_EQ(0, times_run_);
+ EXPECT_EQ(value_, *once.Get());
+ EXPECT_EQ(1, times_run_);
+}
+
+namespace {
+
+int second_result = 0;
+int *SecondFunction() {
+ second_result = rand() % INT_MAX;
+ return &second_result;
+}
+
+} // namespace
+
+// Makes sure that multiple instances don't interfere with each other.
+TEST_F(OnceTest, MultipleInstances) {
+ static Once<int> once1(Function);
+ static Once<int> once2(SecondFunction);
+
+ EXPECT_EQ(&value_, once1.Get());
+ EXPECT_EQ(&second_result, once2.Get());
+ EXPECT_EQ(&value_, once1.Get());
+ EXPECT_EQ(&second_result, once2.Get());
+}
+
+// Tests calling Reset() to run the function a second time.
+TEST_F(OnceTest, Recalculate) {
+ Once<int> once(Function);
+
+ EXPECT_EQ(value_, *once.Get());
+ EXPECT_EQ(1, times_run_);
+
+ value_ = 0;
+ once.Reset();
+ EXPECT_EQ(value_, *once.Get());
+ EXPECT_EQ(2, times_run_);
+}
+
+} // namespace testing
+} // namespace aos