Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
27876b3
adding tools to dividing mock headers
foreseeable Jul 17, 2020
f33ed82
fix spelling
foreseeable Jul 17, 2020
9579352
fix format issues
foreseeable Jul 17, 2020
4106ddc
fix a minor bug in scripts
foreseeable Jul 22, 2020
d13fc8f
adding support to binary size tracking
foreseeable Jul 27, 2020
270933d
refactor profile.py
foreseeable Jul 28, 2020
364d7b2
added type hint and unit test
foreseeable Jul 28, 2020
b812242
update Readme
foreseeable Jul 28, 2020
900eb5e
run formatter
foreseeable Jul 28, 2020
89c47dd
code refactoring
foreseeable Jul 30, 2020
6b94843
adding comments
foreseeable Jul 30, 2020
03f5b7a
run formatter
foreseeable Jul 30, 2020
25ba2d3
add no lint for code corpus to pass ci
foreseeable Jul 30, 2020
e31448a
run formatter
foreseeable Aug 3, 2020
e3d5220
format
foreseeable Aug 3, 2020
688e47c
adding supports to produce changed.txt automatically
foreseeable Aug 3, 2020
810cc3f
run formatter
foreseeable Aug 3, 2020
8e21940
silence clang_tidy on test data
foreseeable Aug 3, 2020
e5dc56a
add comments for get_headers
foreseeable Aug 6, 2020
98d28dc
rename function
foreseeable Aug 6, 2020
29f73b6
adding docs
foreseeable Aug 6, 2020
45c39a0
run formatter
foreseeable Aug 6, 2020
9c6c7dd
use smaller test
foreseeable Aug 6, 2020
a63d79c
run formatter
foreseeable Aug 10, 2020
a1bfc6a
fix typo
foreseeable Aug 18, 2020
1157bcf
use llvm-config instead of hard code path
foreseeable Aug 18, 2020
1ece0c5
remove emptyline
foreseeable Aug 18, 2020
8a77cd4
refactor
foreseeable Aug 18, 2020
7a1d616
fix readme format
foreseeable Aug 20, 2020
59c6e1c
use double quote for consistent
foreseeable Aug 20, 2020
c40bd31
fix typo
foreseeable Aug 20, 2020
c48cd2b
fix typo
foreseeable Aug 20, 2020
2ce96cd
run pylint
foreseeable Aug 20, 2020
78f571f
run fix format
foreseeable Aug 20, 2020
7ab2763
remove profile.py and fix headersplit format
foreseeable Aug 20, 2020
6040230
format fix
foreseeable Aug 20, 2020
4278a4c
integrate unit test under bazel
foreseeable Aug 20, 2020
1bba190
make test run under bazel
foreseeable Aug 24, 2020
0f7ca0f
Merge remote-tracking branch 'upstream/master' into headsplit_tool
foreseeable Aug 24, 2020
891f8b3
integrate ci
foreseeable Aug 24, 2020
66be1ac
fix format
foreseeable Aug 24, 2020
470f3c8
fix column limit
foreseeable Aug 24, 2020
2bc5aa2
format
foreseeable Aug 24, 2020
31e6111
Kick CI
foreseeable Aug 25, 2020
1922301
minor fix
foreseeable Aug 25, 2020
85fc71c
fix BUILD
foreseeable Aug 26, 2020
04da966
fix format
foreseeable Aug 26, 2020
28833ef
add instructions at README
foreseeable Aug 26, 2020
49d6781
idempotent
foreseeable Aug 26, 2020
a7b40e8
add TODO
foreseeable Aug 27, 2020
6c5f650
fix format
foreseeable Aug 28, 2020
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
2 changes: 2 additions & 0 deletions bazel/dependency_imports.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ load("@build_bazel_rules_apple//apple:repositories.bzl", "apple_rules_dependenci
load("@upb//bazel:repository_defs.bzl", upb_bazel_version_repository = "bazel_version_repository")
load("@config_validation_pip3//:requirements.bzl", config_validation_pip_install = "pip_install")
load("@protodoc_pip3//:requirements.bzl", protodoc_pip_install = "pip_install")
load("@headersplit_pip3//:requirements.bzl", headersplit_pip_install = "pip_install")
load("@rules_antlr//antlr:deps.bzl", "antlr_dependencies")

# go version for rules_go
Expand Down Expand Up @@ -53,3 +54,4 @@ def envoy_dependency_imports(go_version = GO_VERSION):

config_validation_pip_install()
protodoc_pip_install()
headersplit_pip_install()
4 changes: 4 additions & 0 deletions bazel/repositories_extra.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ def _python_deps():
name = "protodoc_pip3",
requirements = "@envoy//tools/protodoc:requirements.txt",
)
pip3_import(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to confirm the pip3 trick is so you can bring in Clang as a Python dependency during test via requirements.txt? @lizan @PiotrSikora is there going to be some Wasm dependency that eventually gives us this more directly? I think what is here right now is fine for now though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes I have to install the clang module so that I can use them at test.

name = "headersplit_pip3",
requirements = "@envoy//tools/envoy_headersplit:requirements.txt",
)

# Envoy deps that rely on a first stage of dependency loading in envoy_dependencies().
def envoy_dependencies_extra():
Expand Down
3 changes: 3 additions & 0 deletions ci/do_ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,9 @@ elif [[ "$CI_TARGET" == "bazel.dev" ]]; then

echo "Building and testing ${TEST_TARGETS}"
bazel_with_collection test ${BAZEL_BUILD_OPTIONS} -c fastbuild ${TEST_TARGETS}
# TODO(foreseeable): consolidate this and the API tool tests in a dedicated target.
bazel_with_collection //tools/envoy_headersplit:headersplit_test --spawn_strategy=local
bazel_with_collection //tools/envoy_headersplit:replace_includes_test --spawn_strategy=local
exit 0
elif [[ "$CI_TARGET" == "bazel.compile_time_options" ]]; then
# Right now, none of the available compile-time options conflict with each other. If this
Expand Down
5 changes: 5 additions & 0 deletions ci/run_clang_tidy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ function exclude_testdata() {
grep -v tools/testdata/check_format/
}

# Do not run clang-tidy on envoy_headersplit testdata files.
function exclude_testdata() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that you redefined the exclude_testdata function and effectively undid the tools/testdata/check_format exclusion a few lines up.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch! Thanks for fix it

grep -v tools/envoy_headersplit/
}

# Exclude files in third_party which are temporary forks from other OSS projects.
function exclude_third_party() {
grep -v third_party/
Expand Down
67 changes: 67 additions & 0 deletions tools/envoy_headersplit/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
load("@rules_python//python:defs.bzl", "py_binary", "py_test")
load("@headersplit_pip3//:requirements.bzl", "requirement")
load(
"//bazel:envoy_build_system.bzl",
"envoy_package",
)

licenses(["notice"]) # Apache 2

envoy_package()

py_binary(
name = "headersplit",
srcs = [
"headersplit.py",
],
python_version = "PY3",
srcs_version = "PY3",
visibility = ["//visibility:public"],
deps = [
requirement("clang"),
],
)

py_binary(
name = "replace_includes",
srcs = [
"replace_includes.py",
],
python_version = "PY3",
srcs_version = "PY3",
visibility = ["//visibility:public"],
deps = [
":headersplit",
],
)

py_test(
name = "headersplit_test",
srcs = [
"headersplit_test.py",
],
data = glob(["code_corpus/**"]),
python_version = "PY3",
srcs_version = "PY3",
tags = ["no-sandbox"], # TODO (foreseeable): make this test run under sandbox
visibility = ["//visibility:public"],
deps = [
requirement("clang"),
":headersplit",
],
)

py_test(
name = "replace_includes_test",
srcs = [
"replace_includes_test.py",
],
data = glob(["code_corpus/**"]),
python_version = "PY3",
srcs_version = "PY3",
tags = ["no-sandbox"], # TODO (foreseeable): make this test run under sandbox
visibility = ["//visibility:public"],
deps = [
":replace_includes",
],
)
24 changes: 24 additions & 0 deletions tools/envoy_headersplit/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Envoy Header Split
Tool for spliting monolithic header files in Envoy to speed up compilation
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How often do you think Envoy developers should be running this? Is this a once a year kind of cleanup?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the period could be several months or a year. It should be long enough until we get some monolithic mock headers appeared in Envoy repository.


Steps to divide Envoy mock headers:

1. Run `headersplit.py` to divide the monolithic mock header into different classes

Example (to split monolithic mock header test/mocks/network/mocks.h):

```
cd ${ENVOY_SRCDIR}/test/mocks/network/
python3 ${ENVOY_SRCDIR}/tools/envoy_headersplit/headersplit.py -i mocks.cc -d mocks.h
```

2. Remove unused `#includes` from the new mock headers, and write Bazel dependencies for the newly divided mock classes. (this step needs to be done manually)

3. Run `replace_includes.py` to replace superfluous `#includes` in Envoy directory after dividing. It will also modify the corresponding Bazel `BUILD` file.

Example (to replace `#includes` after dividing mock header test/mocks/network/mocks.h):

```
cd ${ENVOY_SRCDIR}
python3 ${ENVOY_SRCDIR}/tools/envoy_headersplit/replace_includes.py -m network
```
20 changes: 20 additions & 0 deletions tools/envoy_headersplit/code_corpus/class_defn.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include "envoy/split"

// NOLINT(namespace-envoy)

namespace {

class Foo {};

class Bar {
Foo getFoo();
};

class FooBar : Foo, Bar {};

class DeadBeaf {
public:
int val();
FooBar foobar;
};
} // namespace
17 changes: 17 additions & 0 deletions tools/envoy_headersplit/code_corpus/class_defn_without_namespace.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include "envoy/split"

// NOLINT(namespace-envoy)

class Foo {};

class Bar {
Foo getFoo();
};

class FooBar : Foo, Bar {};

class DeadBeaf {
public:
int val();
FooBar foobar;
};
14 changes: 14 additions & 0 deletions tools/envoy_headersplit/code_corpus/class_impl.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include "class_defn.h"

// NOLINT(namespace-envoy)

namespace {
Foo Bar::getFoo() {
Foo foo;
return foo;
}

int DeadBeaf::val() { return 42; }

DeadBeaf::DeadBeaf() = default;
} // namespace
51 changes: 51 additions & 0 deletions tools/envoy_headersplit/code_corpus/fail_mocks.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#include "fail_mocks.h"

// NOLINT(namespace-envoy)

#include <string>

#include "envoy/admin/v3/server_info.pb.h"
#include "envoy/config/core/v3/base.pb.h"

#include "common/singleton/manager_impl.h"

#include "gmock/gmock.h"
#include "gtest/gtest.h"

using testing::_;
using testing::Invoke;
using testing::Return;
using testing::ReturnPointee;
using testing::ReturnRef;
using testing::SaveArg;

namespace Envoy {
namespace Server {

MockConfigTracker::MockConfigTracker() {
ON_CALL(*this, add_(_, _))
.WillByDefault(Invoke([this](const std::string& key, Cb callback) -> EntryOwner* {
EXPECT_TRUE(config_tracker_callbacks_.find(key) == config_tracker_callbacks_.end());
config_tracker_callbacks_[key] = callback;
return new MockEntryOwner();
}));
}
MockConfigTracker::~MockConfigTracker() = default;

MockListenerComponentFactory::MockListenerComponentFactory()
: socket_(std::make_shared<NiceMock<Network::MockListenSocket>>()) {
ON_CALL(*this, createListenSocket(_, _, _, _))
.WillByDefault(Invoke([&](Network::Address::InstanceConstSharedPtr, Network::Socket::Type,
const Network::Socket::OptionsSharedPtr& options,
const ListenSocketCreationParams&) -> Network::SocketSharedPtr {
if (!Network::Socket::applyOptions(options, *socket_,
envoy::config::core::v3::SocketOption::STATE_PREBIND)) {
throw EnvoyException("MockListenerComponentFactory: Setting socket options failed");
}
return socket_;
}));
}
MockListenerComponentFactory::~MockListenerComponentFactory() = default;

} // namespace Server
} // namespace Envoy
64 changes: 64 additions & 0 deletions tools/envoy_headersplit/code_corpus/fail_mocks.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#pragma once
// NOLINT(namespace-envoy)

#include <chrono>
#include <cstdint>
#include <list>
#include <string>

namespace Envoy {
namespace Server {

class MockConfigTracker : public ConfigTracker {
public:
MockConfigTracker();
~MockConfigTracker() override;

struct MockEntryOwner : public EntryOwner {};

MOCK_METHOD(EntryOwner*, add_, (std::string, Cb));

// Server::ConfigTracker
MOCK_METHOD(const CbsMap&, getCallbacksMap, (), (const));
EntryOwnerPtr add(const std::string& key, Cb callback) override {
return EntryOwnerPtr{add_(key, std::move(callback))};
}

absl::node_hash_map<std::string, Cb> config_tracker_callbacks_;
};

class MockListenerComponentFactory : public ListenerComponentFactory {
public:
MockListenerComponentFactory();
~MockListenerComponentFactory() override;

DrainManagerPtr
createDrainManager(envoy::config::listener::v3::Listener::DrainType drain_type) override {
return DrainManagerPtr{createDrainManager_(drain_type)};
}
LdsApiPtr createLdsApi(const envoy::config::core::v3::ConfigSource& lds_config) override {
return LdsApiPtr{createLdsApi_(lds_config)};
}

MOCK_METHOD(LdsApi*, createLdsApi_, (const envoy::config::core::v3::ConfigSource& lds_config));
MOCK_METHOD(std::vector<Network::FilterFactoryCb>, createNetworkFilterFactoryList,
(const Protobuf::RepeatedPtrField<envoy::config::listener::v3::Filter>& filters,
Configuration::FilterChainFactoryContext& filter_chain_factory_context));
MOCK_METHOD(std::vector<Network::ListenerFilterFactoryCb>, createListenerFilterFactoryList,
(const Protobuf::RepeatedPtrField<envoy::config::listener::v3::ListenerFilter>&,
Configuration::ListenerFactoryContext& context));
MOCK_METHOD(std::vector<Network::UdpListenerFilterFactoryCb>, createUdpListenerFilterFactoryList,
(const Protobuf::RepeatedPtrField<envoy::config::listener::v3::ListenerFilter>&,
Configuration::ListenerFactoryContext& context));
MOCK_METHOD(Network::SocketSharedPtr, createListenSocket,
(Network::Address::InstanceConstSharedPtr address, Network::Socket::Type socket_type,
const Network::Socket::OptionsSharedPtr& options,
const ListenSocketCreationParams& params));
MOCK_METHOD(DrainManager*, createDrainManager_,
(envoy::config::listener::v3::Listener::DrainType drain_type));
MOCK_METHOD(uint64_t, nextListenerTag, ());

std::shared_ptr<Network::MockListenSocket> socket_;
};
} // namespace Server
} // namespace Envoy
24 changes: 24 additions & 0 deletions tools/envoy_headersplit/code_corpus/fake_build
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
envoy_cc_test(
name = "async_client_impl_test",
srcs = ["async_client_impl_test.cc"],
deps = [
":common_lib",
"//source/common/buffer:buffer_lib",
"//source/common/http:async_client_lib",
"//source/common/http:context_lib",
"//source/common/http:headers_lib",
"//source/common/http:utility_lib",
"//source/extensions/upstreams/http/generic:config",
"//test/mocks:common_lib",
"//test/mocks/buffer:buffer_mocks",
"//test/mocks/http:http_mocks",
"//test/mocks/local_info:local_info_mocks",
"//test/mocks/router:router_mocks",
"//test/mocks/runtime:runtime_mocks",
"//test/mocks/stats:stats_mocks",
"//test/mocks/upstream:upstream_mocks",
"//test/test_common:test_time_lib",
"@envoy_api//envoy/config/core/v3:pkg_cc_proto",
"@envoy_api//envoy/config/route/v3:pkg_cc_proto",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also to Ashley's advice, I think code corpus examples might want to avoid depending on Envoy implementation and APIs, since they need to be maintained. Again, not the high order bit, but worth considering if you need to add any extra test cases.

],
)
32 changes: 32 additions & 0 deletions tools/envoy_headersplit/code_corpus/fake_source_code.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// NOLINT(namespace-envoy)
#include <chrono>
#include <cstdint>
#include <memory>
#include <string>

#include "envoy/config/core/v3/base.pb.h"
#include "envoy/config/route/v3/route_components.pb.h"

#include "common/buffer/buffer_impl.h"
#include "common/http/async_client_impl.h"
#include "common/http/context_impl.h"
#include "common/http/headers.h"
#include "common/http/utility.h"

#include "test/common/http/common.h"
#include "test/mocks/buffer/mocks.h"
#include "test/mocks/common.h"
#include "test/mocks/http/mocks.h"
#include "test/mocks/local_info/mocks.h"
#include "test/mocks/router/mocks.h"
#include "test/mocks/runtime/mocks.h"
#include "test/mocks/stats/mocks.h"
#include "test/mocks/upstream/mocks.h"
#include "test/test_common/printers.h"

....useless stuff...

NiceMock<Upstream::MockClusterManager>
cm_;

... uninteresting stuff..
11 changes: 11 additions & 0 deletions tools/envoy_headersplit/code_corpus/hello.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// your first c++ program
// NOLINT(namespace-envoy)
#include <iostream>

// random strings

#include "foo/bar"

class test {
test() { std::cout << "Hello World" << std::endl; }
};
Loading