Skip to content
This repository was archived by the owner on Dec 29, 2022. It is now read-only.

[Incomplete] Feature/processor container generator #4

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions makefile
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ PLATFORM_SRCS=$(PLATFORM)/dglogging.cpp
UTIL=./util
UTIL_SRCS=$(UTIL)/graphanalyzer.cpp \
$(UTIL)/nodenameutils.cpp \
$(UTIL)/processorcontainergenerator.cpp \
$(NULL)

# Test Utilities
Expand Down
2 changes: 2 additions & 0 deletions unit-test/full/test_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "test_graphstatestore.h"
#include "test_graphtestutils.h"
#include "test_nodenameutils.h"
#include "test_processorcontainergenerator.h"
#include "test_testsplitterdetector.h"
#include "test_topicstate.h"

Expand All @@ -40,6 +41,7 @@ typedef int (*test_fp)(void);
graphstatestore_testsuite, \
graphtestutils_testsuite, \
nodenameutils_testsuite, \
processorcontainergenerator_testsuite, \
testsplitterdetector_testsuite, \
topicstate_testsuite, \
}
Expand Down
126 changes: 126 additions & 0 deletions unit-test/full/test_processorcontainergenerator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
// Copyright 2017 Nest Labs, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "nltest.h"
#include "errortype.hpp"

#include "test_processorcontainergenerator.h"

#include "processorcontainergenerator.hpp"
#include "graph.hpp"
#include "detector.hpp"
#include "nodenameutils.hpp"

#include <typeinfo>
#include <iostream>
#include <fstream>

#define HPP_DIR "tmptest/cpp/"

#define SUITE_DECLARATION(name, test_ptr) { #name, test_ptr, setup_##name, teardown_##name }

using namespace DetectorGraph;

static int setup_processorcontainergenerator(void *inContext)
{
int r;

r = system("mkdir -p " HPP_DIR);

return r;
}

static int teardown_processorcontainergenerator(void *inContext)
{
int r = 0;

r = system("rm -fR " HPP_DIR "*");

return r;
}

// TODO(DGRAPH-3): do actual stuff here.
static void Test_EmptyGraph(nlTestSuite *inSuite, void *inContext)
{
Graph graph;
ProcessorContainerGenerator processorContainerGenerator(graph);
processorContainerGenerator.GenerateClass(HPP_DIR "emptygraph.hpp");
}

struct TestTopicStateA : public DetectorGraph::TopicState {};
struct TestTopicStateB : public DetectorGraph::TopicState {};
class TestDetectorA : public DetectorGraph::Detector
, public SubscriberInterface<TestTopicStateA>
, public Publisher<TestTopicStateB>
{
public:
TestDetectorA(Graph* graph)
: DetectorGraph::Detector(graph)
{
Subscribe<TestTopicStateA>(this);
SetupPublishing<TestTopicStateB>(this);
}

void Evaluate(const TestTopicStateA& aTestTopicStateA)
{

Publisher<TestTopicStateB>::Publish(TestTopicStateB());
}
};

// TODO(DGRAPH-3): TEST actual stuff here.
static void Test_GetVertexMeta(nlTestSuite *inSuite, void *inContext)
{
Graph graph;
TestDetectorA detectorA(&graph);

ProcessorContainerGenerator processorContainerGenerator(graph);
processorContainerGenerator.SetStringFilter(&NodeNameUtils::GetDemangledName);
std::vector<ProcessorContainerGenerator::VertexMeta> vertices = processorContainerGenerator.GetVerticesData();

for (unsigned i = 0; i < vertices.size(); i++)
{
const ProcessorContainerGenerator::VertexMeta& vertexMeta = vertices[i];
printf("Vertex %d, Type %d, Class=%s, Instance=%s\n", i, int(vertexMeta.type),
vertexMeta.className.c_str(), vertexMeta.instanceName.c_str());
}
}

// TODO(DGRAPH-3): TEST actual stuff here.
static void Test_SingleDetector(nlTestSuite *inSuite, void *inContext)
{
Graph graph;
TestDetectorA detectorA(&graph);

ProcessorContainerGenerator processorContainerGenerator(graph);
processorContainerGenerator.SetStringFilter(&NodeNameUtils::GetDemangledName);
processorcontainergenerator.SetOutputClassName("TestAGraph");
processorContainerGenerator.GenerateClass(HPP_DIR "singledetector.hpp");
}

static const nlTest sTests[] = {
NL_TEST_DEF("Test_EmptyGraph", Test_EmptyGraph),
NL_TEST_DEF("Test_GetVertexMeta", Test_GetVertexMeta),
NL_TEST_DEF("Test_SingleDetector", Test_SingleDetector),
NL_TEST_SENTINEL()
};

//This function creates the Suite (i.e: the name of your test and points to the array of test functions)
extern "C"
int processorcontainergenerator_testsuite(void)
{
nlTestSuite theSuite = SUITE_DECLARATION(processorcontainergenerator, &sTests[0]);
nlTestRunner(&theSuite, NULL);
return nlTestRunnerStats(&theSuite);
}
30 changes: 30 additions & 0 deletions unit-test/full/test_processorcontainergenerator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright 2017 Nest Labs, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef DETECTORGRAPH_UNIT_TEST_PROCESSORCONTAINERGENERATOR_H_
#define DETECTORGRAPH_UNIT_TEST_PROCESSORCONTAINERGENERATOR_H_

#ifdef __cplusplus
extern "C" {
#endif

int processorcontainergenerator_testsuite(void);

#ifdef __cplusplus
}
#endif

#endif
178 changes: 178 additions & 0 deletions util/processorcontainergenerator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
// Copyright 2017 Nest Labs, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "processorcontainergenerator.hpp"

#include <fstream>
#include <iostream>
#include <sstream>
#include <list>
#include <typeinfo>

#include "dglogging.hpp"

namespace DetectorGraph
{

ProcessorContainerGenerator::ProcessorContainerGenerator(Graph& aGraph)
: mGraph(aGraph)
, mStringFilter(NULL)
, mProcessorContainerName("GeneratedProcessorContainer")
{
}

void ProcessorContainerGenerator::SetStringFilter(std::string (*aStringFilter)(const std::string&))
{
mStringFilter = aStringFilter;
}

void ProcessorContainerGenerator::SetOutputClassName(const std::string& aClassName)
{
mProcessorContainerName = aClassName;
}

std::vector<ProcessorContainerGenerator::VertexMeta> ProcessorContainerGenerator::GetVerticesData()
{
std::vector<VertexMeta> vertexMetaVector;
DetectorGraph::ErrorType r;
r = mGraph.TopoSortGraph();
if (r != DetectorGraph::ErrorType_Success)
{
DG_LOG("Failed to get graph's Topological Sort.");
DG_ASSERT(false);
}

for (std::list< Vertex* >::const_iterator vertexIt = mGraph.GetVertices().begin();
vertexIt != mGraph.GetVertices().end();
++vertexIt)
{
const Vertex* vertex = (*vertexIt);
VertexMeta vertexMetadata;
vertexMetadata.className = GetClassName(vertex->GetName());
vertexMetadata.type = vertex->GetVertexType();
vertexMetadata.instanceName = GetInstanceName(vertexMetadata.className, vertexMetadata.type);

vertexMetaVector.push_back(vertexMetadata);
}

return vertexMetaVector;
}

void ProcessorContainerGenerator::GenerateClass(const std::string& aOutFilePath)
{
ofstream cppHeaderFile;
cppHeaderFile.open(aOutFilePath.c_str());

if (cppHeaderFile.is_open())
{
std::vector<ProcessorContainerGenerator::VertexMeta> vertices = GetVerticesData();

cppHeaderFile << "#include \"graph.hpp\"" << endl;
cppHeaderFile << "#include \"detector.hpp\"" << endl;
cppHeaderFile << "#include \"processorcontainer.hpp\"" << endl;

cppHeaderFile << endl;

cppHeaderFile << "class " << mProcessorContainerName << " : public DetectorGraph::ProcessorContainer" << endl;
cppHeaderFile << "{" << endl;
cppHeaderFile << "public:" << endl;
cppHeaderFile << " " << mProcessorContainerName << "()" << endl;

for (unsigned nodeIndex = 0; nodeIndex < vertices.size(); nodeIndex++)
{
if (nodeIndex == 0)
{
cppHeaderFile << " : ";
}
else
{
cppHeaderFile << " , ";
}

if (vertices[nodeIndex].type == DetectorGraph::Vertex::kDetectorVertex)
{
cppHeaderFile << vertices[nodeIndex].instanceName << "(&mGraph)" << endl;
}
else if (vertices[nodeIndex].type == DetectorGraph::Vertex::kTopicVertex)
{
cppHeaderFile << vertices[nodeIndex].instanceName << "(mGraph.ResolveTopic<";
cppHeaderFile << vertices[nodeIndex].className << ">())" << endl;
}
}
cppHeaderFile << " {" << endl;
cppHeaderFile << " }" << endl;

for (unsigned nodeIndex = 0; nodeIndex < vertices.size(); nodeIndex++)
{
if (vertices[nodeIndex].type == DetectorGraph::Vertex::kDetectorVertex)
{
cppHeaderFile << " " << vertices[nodeIndex].className << " ";
cppHeaderFile << vertices[nodeIndex].instanceName << ";" << endl;
}
else if (vertices[nodeIndex].type == DetectorGraph::Vertex::kTopicVertex)
{
cppHeaderFile << " " << vertices[nodeIndex].className << "* ";
cppHeaderFile << vertices[nodeIndex].instanceName << ";" << endl;
}
}
cppHeaderFile << "};" << endl;

cppHeaderFile.close();

DG_LOG("Sorted DetectorGraph::ProcessorContainer header file created at: %s", aOutFilePath.c_str());
}
}

std::string ProcessorContainerGenerator::GetClassName(const char* aCompilerName) const
{
std::string retString = std::string(aCompilerName);
if (mStringFilter)
{
retString = mStringFilter(retString);
}

return retString;
}

std::string ProcessorContainerGenerator::GetInstanceName(const std::string& aClassName, DetectorGraph::Vertex::VertexType type) const
{
std::string instanceName = aClassName;

std::string::size_type lastNamespaceDelimiterPos;
lastNamespaceDelimiterPos = instanceName.rfind("::");
if (lastNamespaceDelimiterPos != std::string::npos)
{
lastNamespaceDelimiterPos += 2; // "::".size()
instanceName.erase(0, lastNamespaceDelimiterPos);
}

if (type == DetectorGraph::Vertex::kDetectorVertex)
{
return "m" + instanceName;
}
else if (type == DetectorGraph::Vertex::kTopicVertex)
{
instanceName.erase(0, 6); // "Topic<".size()
instanceName.erase(instanceName.size()-1, 1); // ">"
instanceName.append("Topic");
return "mp" + instanceName;
}
else
{
return instanceName;
}
}


}
Loading