Skip to content

Commit

Permalink
AutowiringEnclosure MUST be header-only
Browse files Browse the repository at this point in the history
This is needed in order to prevent near-incompatibility issues from causing programs to crash when trying to link against the AutowiringEnclosure.  The root problem, here, is Google's recommendation that users distribute googletest in their own applications.  This means that there is no public-facing API that Google is compelled to maintain (in order to evade linker errors) and therefore no ABI to standardize behavior.

So, in order to ensure that our class receives the correct layout, we have to make it the consumer's responsibility to ensure correct include ordering.
  • Loading branch information
codemercenary committed Aug 15, 2014
1 parent 663a7c3 commit 20a4dc4
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 66 deletions.
65 changes: 62 additions & 3 deletions autowiring/AutowiringEnclosure.h
@@ -1,9 +1,12 @@
// Copyright (C) 2012-2014 Leap Motion, Inc. All rights reserved.
#pragma once
#include <autowiring/autowiring.h>
#include <gtest/gtest.h>
#include MEMORY_HEADER

#ifndef GTEST_INCLUDE_GTEST_GTEST_H_
#error Please include your version of gtest.h before including the autowiring enclosure
#endif

/// <summary>
/// General purpose exception filter, used for tracking exceptions thrown from unit test CoreThreads
/// </summary>
Expand Down Expand Up @@ -35,6 +38,14 @@ class AutowiringEnclosureExceptionFilter:
}
};

struct TestInfoProxy {
TestInfoProxy(const testing::TestInfo& info) :
m_info(info)
{}

const testing::TestInfo& m_info;
};

/// <summary>
/// Provides a test fixture which ensures proper cleanup of a created subcontext
/// </summary>
Expand All @@ -53,6 +64,54 @@ class AutowiringEnclosure:

public:
// Base overrides:
void OnTestStart(const testing::TestInfo& info) override;
void OnTestEnd(const testing::TestInfo& info) override;
void OnTestStart(const testing::TestInfo& info) override {
AutoRequired<AutowiringEnclosureExceptionFilter> filter;

// The context proper. This is automatically assigned as the current
// context when SetUp is invoked.
AutoCreateContext create;
create->Construct<TestInfoProxy>(info);

// Add exception filter in this context:
create->Inject<AutowiringEnclosureExceptionFilter>();

// Now make it current and let the test run:
create->SetCurrent();
}

void OnTestEnd(const testing::TestInfo& info) override {
// Verify we can grab the test case back out and that the pointer is correct:
Autowired<TestInfoProxy> ti;
Autowired<AutowiringEnclosureExceptionFilter> ecef;
auto ctxt = ecef ? ecef->GetContext() : nullptr;

// Unconditionally reset the global context as the current context
AutoGlobalContext()->SetCurrent();

// Global initialization tests are special, we don't bother checking closure principle on them:
if(!strcmp("GlobalInitTest", info.test_case_name()))
return;

// Need to make sure we got back our exception filter before continuing:
ASSERT_TRUE(ecef.IsAutowired()) << "Failed to find the enclosed context exception filter; unit test may have incorrectly reset the enclosing context before returning";

// Now try to tear down the test context enclosure:
ctxt->SignalShutdown();

// Do not allow teardown to take more than 250 milliseconds or so
if(!ctxt->Wait(std::chrono::milliseconds(250))) {
// Critical error--took too long to tear down
assert(false);
}

static const char sc_autothrow [] = "AUTOTHROW_";
if(!strncmp(sc_autothrow, info.name(), ARRAYCOUNT(sc_autothrow) - 1))
// Throw expected, end here
return;

// If an exception occurred somewhere, report it:
ASSERT_FALSE(ecef->m_excepted)
<< "An unhandled exception occurred in this context" << std::endl
<< "[" << (ecef->m_ti ? ecef->m_ti->name() : "unknown") << "] " << ecef->m_what;
}
};
61 changes: 0 additions & 61 deletions src/autotesting/AutowiringEnclosure.cpp

This file was deleted.

1 change: 0 additions & 1 deletion src/autotesting/CMakeLists.txt
@@ -1,6 +1,5 @@
set(AutoTesting_SOURCES
AutowiringEnclosure.h
AutowiringEnclosure.cpp
gtest-all-guard.h
gtest-all-guard.cpp
)
Expand Down
2 changes: 1 addition & 1 deletion src/autotesting/gtest-all-guard.cpp
@@ -1,7 +1,7 @@
// Copyright (C) 2012-2014 Leap Motion, Inc. All rights reserved.
#include "stdafx.h"
#include "AutowiringEnclosure.h"
#include <gtest/gtest-all.cc>
#include "AutowiringEnclosure.h"

using namespace std;

Expand Down

0 comments on commit 20a4dc4

Please sign in to comment.