Skip to content

Env task states #163

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Nov 28, 2021
Merged
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
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,15 @@ Build C, C++ and ASM files in C++

## Dependency Chart

![Depedency Chart](doc/software_architecture/uml/dependency_graph.png)
![Dependency Chart](doc/software_architecture/uml/dependency_graph.png)

- See also [how to create uml diagrams using VSCode](doc/software_architecture/create_uml_diagrams.md)
## State Diagram

### [Generator State Diagram](doc/software_architecture/uml/generator_tasks.png)

### [Target State Diagram](doc/software_architecture/uml/target_tasks.png)

> See also [how to create uml diagrams using VSCode](doc/software_architecture/create_uml_diagrams.md)

## Community Plugin

Expand Down
11 changes: 11 additions & 0 deletions buildcc/lib/env/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@ if (${TESTING})
add_library(mock_env STATIC
mock/logging.cpp
mock/assert_fatal.cpp

src/env.cpp
src/task_state.cpp
)
target_include_directories(mock_env PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/include
)
target_link_libraries(mock_env PUBLIC
fmt::fmt-header-only
Taskflow

CppUTest
CppUTestExt
gcov
Expand All @@ -21,7 +25,11 @@ if (${TESTING})
add_executable(test_env_util test/test_env_util.cpp)
target_link_libraries(test_env_util PRIVATE mock_env)

add_executable(test_task_state test/test_task_state.cpp)
target_link_libraries(test_task_state PRIVATE mock_env)

add_test(NAME test_env_util COMMAND test_env_util)
add_test(NAME test_task_state COMMAND test_task_state)
endif()

set(ENV_SRCS
Expand All @@ -34,6 +42,9 @@ set(ENV_SRCS
include/env/host_os.h
include/env/host_compiler.h
include/env/util.h

src/task_state.cpp
include/env/task_state.h
)

if(${BUILDCC_BUILD_AS_SINGLE_LIB})
Expand Down
33 changes: 33 additions & 0 deletions buildcc/lib/env/include/env/task_state.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright 2021 Niket Naidu. All rights reserved.
*
* 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 ENV_PRIVATE_TASK_STATE_H_
#define ENV_PRIVATE_TASK_STATE_H_

namespace buildcc::env {

enum class TaskState {
SUCCESS,
FAILURE,
// TODO, Add more states here
};

void set_task_state(TaskState state);
TaskState get_task_state();

} // namespace buildcc::env

#endif
37 changes: 37 additions & 0 deletions buildcc/lib/env/src/task_state.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright 2021 Niket Naidu. All rights reserved.
*
* 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 "env/task_state.h"

#include <mutex>

namespace {

std::mutex current_state_mutex;
buildcc::env::TaskState current_state{buildcc::env::TaskState::SUCCESS};

} // namespace

namespace buildcc::env {

void set_task_state(TaskState state) {
std::lock_guard<std::mutex> guard(current_state_mutex);
current_state = state;
}

TaskState get_task_state() { return current_state; }

} // namespace buildcc::env
71 changes: 71 additions & 0 deletions buildcc/lib/env/test/test_task_state.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#include "env/task_state.h"

#include "taskflow/taskflow.hpp"

// NOTE, Make sure all these includes are AFTER the system and header includes
#include "CppUTest/CommandLineTestRunner.h"
#include "CppUTest/MemoryLeakDetectorNewMacros.h"
#include "CppUTest/TestHarness.h"
#include "CppUTest/Utest.h"

// clang-format off
TEST_GROUP(TaskStateTestGroup)
{
void setup() {
buildcc::env::set_task_state(buildcc::env::TaskState::SUCCESS);
}
};
// clang-format on

TEST(TaskStateTestGroup, OneTask) {
CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::SUCCESS);

tf::Taskflow tf;
bool completed = false;
tf.emplace([&]() {
buildcc::env::set_task_state(buildcc::env::TaskState::FAILURE);
completed = true;
});
tf::Executor executor(2);
executor.run(tf);
executor.wait_for_all();

CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::FAILURE);
CHECK_TRUE(completed);
}

TEST(TaskStateTestGroup, MultipleTasks) {
CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::SUCCESS);

tf::Taskflow tf;
bool completed1 = false;
tf.emplace([&]() {
buildcc::env::set_task_state(buildcc::env::TaskState::FAILURE);
completed1 = true;
});

bool completed2 = false;
tf.emplace([&]() {
buildcc::env::set_task_state(buildcc::env::TaskState::FAILURE);
completed2 = true;
});

bool completed3 = false;
tf.emplace([&]() {
buildcc::env::set_task_state(buildcc::env::TaskState::FAILURE);
completed3 = true;
});

tf::Executor executor(2);
executor.run(tf);
executor.wait_for_all();

CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::FAILURE);
CHECK_TRUE(completed1);
CHECK_TRUE(completed2);
CHECK_TRUE(completed3);
}

int main(int ac, char **av) {
return CommandLineTestRunner::RunAllTests(ac, av);
}
2 changes: 2 additions & 0 deletions buildcc/lib/target/cmake/mock_target.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ add_library(mock_target STATIC

# Generator mocks
mock/generator/task.cpp
mock/generator/runner.cpp
mock/generator/recheck_states.cpp

# Target mocks
mock/target/tasks.cpp
mock/target/runner.cpp
mock/target/recheck_states.cpp
)
target_include_directories(mock_target PUBLIC
Expand Down
2 changes: 2 additions & 0 deletions buildcc/lib/target/mock/expect_generator.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

namespace buildcc::base::m {

void GeneratorRunner(Generator &generator);

void GeneratorExpect_InputRemoved(unsigned int calls, Generator *generator);
void GeneratorExpect_InputAdded(unsigned int calls, Generator *generator);
void GeneratorExpect_InputUpdated(unsigned int calls, Generator *generator);
Expand Down
2 changes: 2 additions & 0 deletions buildcc/lib/target/mock/expect_target.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ namespace buildcc {

namespace base::m {

void TargetRunner(Target &target);

void TargetExpect_SourceRemoved(unsigned int calls, Target *target);
void TargetExpect_SourceAdded(unsigned int calls, Target *target);
void TargetExpect_SourceUpdated(unsigned int calls, Target *target);
Expand Down
13 changes: 13 additions & 0 deletions buildcc/lib/target/mock/generator/runner.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include "target/generator.h"

#include "expect_generator.h"

namespace buildcc::base::m {

void GeneratorRunner(Generator &generator) {
tf::Executor executor(1);
executor.run(generator.GetTaskflow());
executor.wait_for_all();
}

} // namespace buildcc::base::m
13 changes: 13 additions & 0 deletions buildcc/lib/target/mock/target/runner.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include "target/target.h"

#include "expect_target.h"

namespace buildcc::base::m {

void TargetRunner(Target &target) {
tf::Executor executor(1);
executor.run(target.GetTaskflow());
executor.wait_for_all();
}

} // namespace buildcc::base::m
84 changes: 45 additions & 39 deletions doc/software_architecture/uml/dependency_graph.md
Original file line number Diff line number Diff line change
@@ -1,43 +1,49 @@
@startuml


usecase IncludeDirs
usecase PreprocessorFlags
usecase CompilerFlags

usecase LinkFlags
usecase LinkDirs

file SourceFile
file HeaderFile
file ObjectFile
file PrecompileHeader
file Executable
file Library
file Modules

queue Compiler
queue Linker

HeaderFile ..> Compiler
IncludeDirs ..> Compiler
PreprocessorFlags ..> Compiler
CompilerFlags ..> Compiler
SourceFile ..> Compiler

Compiler ..> ObjectFile
Compiler ..> PrecompileHeader

PrecompileHeader ..> ObjectFile

LinkFlags ..> Linker
LinkDirs ..> Linker
ObjectFile ..> Linker
Library ..> Linker
Modules ..> Linker

Linker ..> Executable
Linker ..> Library
Linker ..> Modules
[*] --> Compile
Compile --> Link
Link --> [*]

state Compile {
SourceFile --> Compiler
HeaderFile --> Compiler
IncludeDirs --> Compiler
PreprocessorFlags --> Compiler
CompilerFlags --> Compiler

Compiler --> ObjectFile
Compiler --> PrecompileHeader

PrecompileHeader --> ObjectFile

SourceFile : Path + Timestamp
HeaderFile : Path + Timestamp
IncludeDirs : Path
PreprocessorFlags : String
CompilerFlags : String
Compiler : Toolchain
PrecompileHeader : Path
ObjectFile : Path
}

Compile : {1 ... N}

state Link {
Library --> Linker
Module --> Linker
LinkDirs --> Linker
LinkFlags --> Linker

Linker --> Executable
Linker --> Library
Linker --> Module

Library : Path + Timestamp
Module : Path + Timestamp
Executable : Path + Timestamp
Linker : Toolchain
LinkDirs : Path
LinkFlags : String
}

@enduml
Binary file modified doc/software_architecture/uml/dependency_graph.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions doc/software_architecture/uml/generator_tasks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
@startuml

[*] --> GeneratorStartTask
GeneratorStartTask --> GenerateTask : Success
GenerateTask --> GeneratorEndTask : Success / Failure
GeneratorEndTask --> [*]

state GenerateTask {
}

GeneratorStartTask --> GeneratorEndTask : Failure

GeneratorStartTask : GetEnvTaskState
GenerateTask : PreGenerate
GenerateTask : Generate
GenerateTask : PostGenerate
GeneratorEndTask : Store
GeneratorEndTask : UpdateEnvTaskStateIfFailure

@enduml
Binary file added doc/software_architecture/uml/generator_tasks.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading