Commit b9fbd971 authored by Ramin Halavati's avatar Ramin Halavati Committed by Commit Bot

3 more tests added to network traffic annotation auditor unittest.

Annotation and call deserialization and duplicate code checking added to
network traffic annotation auditor's unittest.

Bug: 656607
Bug: 690323
Change-Id: I4397359da0c170f9fe9a1dda0bcc57ef723ed863
Reviewed-on: https://chromium-review.googlesource.com/568034
Commit-Queue: Ramin Halavati <rhalavati@chromium.org>
Reviewed-by: default avatarMartin Šrámek <msramek@chromium.org>
Cr-Commit-Position: refs/heads/master@{#486704}
parent ffc67cf8
headless/public/util/http_url_fetcher.cc
headless::HttpURLFetcher::Delegate::Delegate
net::URLRequestContext::CreateRequest
1
\ No newline at end of file
chrome/browser/supervised_user/legacy/supervised_user_refresh_token_fetcher.cc
OnGetTokenSuccess
166
Definition
supervised_user_refresh_token_fetcher
semantics
sender: "Supervised Users"
description:
"Fetches an OAuth2 refresh token scoped down to the Supervised "
"User Sync scope and tied to the given Supervised User ID, "
"identifying the Supervised User Profile to be created."
trigger:
"Called when creating a new Supervised User profile in Chromium "
"to fetch OAuth credentials for using Sync with the new profile."
data:
"The request is authenticated with an OAuth2 access token "
"identifying the Google account and contains the following "
"information:\n* The Supervised User ID, a randomly generated "
"64-bit identifier for the profile.\n* The device name, to "
"identify the refresh token in account management."
destination: GOOGLE_OWNED_SERVICE
}
policy {
cookies_allowed: false
setting:
"Users can disable this feature by toggling 'Let anyone add a "
"person to Chrome' in Chromium settings, under People."
chrome_policy {
SupervisedUserCreationEnabled {
policy_options {mode: MANDATORY}
SupervisedUserCreationEnabled: false
}
}
}
\ No newline at end of file
chrome/browser/supervised_user/legacy/supervised_user_refresh_token_fetcher.cc
OnGetTokenSuccess
166
Definition
supervised_user_refresh_token_fetcher
Semantics {
sender: "Supervised Users"
description:
"Fetches an OAuth2 refresh token scoped down to the Supervised "
"User Sync scope and tied to the given Supervised User ID, "
"identifying the Supervised User Profile to be created."
trigger:
"Called when creating a new Supervised User profile in Chromium "
"to fetch OAuth credentials for using Sync with the new profile."
data:
"The request is authenticated with an OAuth2 access token "
"identifying the Google account and contains the following "
"information:\n* The Supervised User ID, a randomly generated "
"64-bit identifier for the profile.\n* The device name, to "
"identify the refresh token in account management."
destination: GOOGLE_OWNED_SERVICE
}
policy {
cookies_allowed: false
setting:
"Users can disable this feature by toggling 'Let anyone add a "
"person to Chrome' in Chromium settings, under People."
chrome_policy {
SupervisedUserCreationEnabled {
policy_options {mode: MANDATORY}
SupervisedUserCreationEnabled: false
}
}
}
\ No newline at end of file
chrome/browser/supervised_user/legacy/supervised_user_refresh_token_fetcher.cc
OnGetTokenSuccess
166
Definition
supervised_user_refresh_token_fetcher
Semantics {
sender: "Supervised Users
description:
"Fetches an OAuth2 refresh token scoped down to the Supervised "
"User Sync scope and tied to the given Supervised User ID, "
"identifying the Supervised User Profile to be created."
trigger:
"Called when creating a new Supervised User profile in Chromium "
"to fetch OAuth credentials for using Sync with the new profile."
data:
"The request is authenticated with an OAuth2 access token "
"identifying the Google account and contains the following "
"information:\n* The Supervised User ID, a randomly generated "
"64-bit identifier for the profile.\n* The device name, to "
"identify the refresh token in account management."
destination: GOOGLE_OWNED_SERVICE
}
policy {
cookies_allowed: false
setting:
"Users can disable this feature by toggling 'Let anyone add a "
"person to Chrome' in Chromium settings, under People."
chrome_policy {
SupervisedUserCreationEnabled {
policy_options {mode: MANDATORY}
SupervisedUserCreationEnabled: false
}
}
}
\ No newline at end of file
chrome/browser/supervised_user/legacy/supervised_user_refresh_token_fetcher.cc
OnGetTokenSuccess
166
Definition
supervised_user_refresh_token_fetcher
Semantics {
sender: "Supervised Users
description:
"Fetches an OAuth2 refresh token scoped down to the Supervised "
"User Sync scope and tied to the given Supervised User ID, "
"identifying the Supervised User Profile to be created."
trigger:
"Called when creating a new Supervised User profile in Chromium "
"to fetch OAuth credentials for using Sync with the new profile."
data:
"The request is authenticated with an OAuth2 access token "
"identifying the Google account and contains the following "
"information:\n* The Supervised User ID, a randomly generated "
"64-bit identifier for the profile.\n* The device name, to "
"identify the refresh token in account management."
destination: GOOGLE_OWNED_SERVICE
cookies_allowed: false
setting:
"Users can disable this feature by toggling 'Let anyone add a "
"person to Chrome' in Chromium settings, under People."
chrome_policy {
SupervisedUserCreationEnabled {
policy_options {mode: MANDATORY}
SupervisedUserCreationEnabled: false
}
}
}
\ No newline at end of file
chrome/browser/supervised_user/legacy/supervised_user_refresh_token_fetcher.cc
OnGetTokenSuccess
Definition
supervised_user_refresh_token_fetcher
semantics {
sender: "Supervised Users"
description:
"Fetches an OAuth2 refresh token scoped down to the Supervised "
"User Sync scope and tied to the given Supervised User ID, "
"identifying the Supervised User Profile to be created."
trigger:
"Called when creating a new Supervised User profile in Chromium "
"to fetch OAuth credentials for using Sync with the new profile."
data:
"The request is authenticated with an OAuth2 access token "
"identifying the Google account and contains the following "
"information:\n* The Supervised User ID, a randomly generated "
"64-bit identifier for the profile.\n* The device name, to "
"identify the refresh token in account management."
destination: GOOGLE_OWNED_SERVICE
}
policy {
cookies_allowed: false
setting:
"Users can disable this feature by toggling 'Let anyone add a "
"person to Chrome' in Chromium settings, under People."
chrome_policy {
SupervisedUserCreationEnabled {
policy_options {mode: MANDATORY}
SupervisedUserCreationEnabled: false
}
}
}
\ No newline at end of file
chrome/browser/supervised_user/legacy/supervised_user_refresh_token_fetcher.cc
OnGetTokenSuccess
122
definition
supervised_user_refresh_token_fetcher
semantics {
sender: "Supervised Users"
description:
"Fetches an OAuth2 refresh token scoped down to the Supervised "
"User Sync scope and tied to the given Supervised User ID, "
"identifying the Supervised User Profile to be created."
trigger:
"Called when creating a new Supervised User profile in Chromium "
"to fetch OAuth credentials for using Sync with the new profile."
data:
"The request is authenticated with an OAuth2 access token "
"identifying the Google account and contains the following "
"information:\n* The Supervised User ID, a randomly generated "
"64-bit identifier for the profile.\n* The device name, to "
"identify the refresh token in account management."
destination: GOOGLE_OWNED_SERVICE
}
policy {
cookies_allowed: false
setting:
"Users can disable this feature by toggling 'Let anyone add a "
"person to Chrome' in Chromium settings, under People."
chrome_policy {
SupervisedUserCreationEnabled {
policy_options {mode: MANDATORY}
SupervisedUserCreationEnabled: false
}
}
}
\ No newline at end of file
chrome/browser/supervised_user/legacy/supervised_user_refresh_token_fetcher.cc
OnGetTokenSuccess
122
definition
supervised_user_refresh_token_fetcher
chrome/service/cloud_print/cloud_print_url_fetcher.cc
cloud_print::CloudPrintURLFetcher::StartRequestHelper
265
BranchedCompleting
cloud_print
semantics {
sender: "Cloud Print"
destination: GOOGLE_OWNED_SERVICE
}
policy {
cookies_allowed: false
setting:
"This feature cannot be disabled by settings."
chrome_policy {
CloudPrintProxyEnabled {
policy_options {mode: MANDATORY}
CloudPrintProxyEnabled: false
}
}
}
\ No newline at end of file
headless/public/util/http_url_fetcher.cc
headless::HttpURLFetcher::Delegate::Delegate
100
net::URLRequestContext::CreateRequest
1
\ No newline at end of file
chrome/browser/supervised_user/legacy/supervised_user_refresh_token_fetcher.cc
OnGetTokenSuccess
166
Definition
supervised_user_refresh_token_fetcher
semantics {
sender: "Supervised Users"
description:
"Fetches an OAuth2 refresh token scoped down to the Supervised "
"User Sync scope and tied to the given Supervised User ID, "
"identifying the Supervised User Profile to be created."
trigger:
"Called when creating a new Supervised User profile in Chromium "
"to fetch OAuth credentials for using Sync with the new profile."
data:
"The request is authenticated with an OAuth2 access token "
"identifying the Google account and contains the following "
"information:\n* The Supervised User ID, a randomly generated "
"64-bit identifier for the profile.\n* The device name, to "
"identify the refresh token in account management."
destination: GOOGLE_OWNED_SERVICE
}
policy {
cookies_allowed: false
setting:
"Users can disable this feature by toggling 'Let anyone add a "
"person to Chrome' in Chromium settings, under People."
chrome_policy {
SupervisedUserCreationEnabled {
policy_options {mode: MANDATORY}
SupervisedUserCreationEnabled: false
}
}
}
\ No newline at end of file
chrome/service/cloud_print/cloud_print_url_fetcher.cc
cloud_print::CloudPrintURLFetcher::StartRequestHelper
265
Completing
cloud_print
semantics {
sender: "Cloud Print"
destination: GOOGLE_OWNED_SERVICE
}
policy {
cookies_allowed: false
setting:
"This feature cannot be disabled by settings."
chrome_policy {
CloudPrintProxyEnabled {
policy_options {mode: MANDATORY}
CloudPrintProxyEnabled: false
}
}
}
\ No newline at end of file
components/browsing_data/core/counters/history_counter.cc
browsing_data::HistoryCounter::Count
98
Partial
web_history_counter
web_history_service
semantics {
description:
"If history sync is enabled, this queries history.google.com to "
"determine if there is any synced history. This information is "
"displayed in the Clear Browsing Data dialog."
trigger:
"Checking the 'Browsing history' option in the Clear Browsing Data "
"dialog, or enabling history sync while the dialog is open."
data:
"A version info token to resolve transaction conflicts, and an "
"OAuth2 token authenticating the user."
}
policy {
chrome_policy {
SyncDisabled {
SyncDisabled: true
}
}
}
\ No newline at end of file
google_apis/drive/request_sender_unittest.cc
google_apis::(anonymous namespace)::RequestSenderTest::RequestSenderTest
67
Definition
test
Traffic annotation for unit, browser and other tests
\ No newline at end of file
net/url_request/url_request_context.cc
net::URLRequestContext::CreateRequest
120
Definition
missing
Function called without traffic annotation.
components/download/internal/controller_impl.cc
download::ControllerImpl::UpdateDriverState
656
Definition
undefined
Nothing here yet.
\ No newline at end of file
...@@ -506,6 +506,7 @@ bool TrafficAnnotationAuditor::LoadWhiteList() { ...@@ -506,6 +506,7 @@ bool TrafficAnnotationAuditor::LoadWhiteList() {
return false; return false;
} }
// static
const std::map<int, std::string>& const std::map<int, std::string>&
TrafficAnnotationAuditor::GetReservedUniqueIDs() { TrafficAnnotationAuditor::GetReservedUniqueIDs() {
return kReservedAnnotations; return kReservedAnnotations;
......
...@@ -83,9 +83,20 @@ class AuditorResult { ...@@ -83,9 +83,20 @@ class AuditorResult {
int line_; int line_;
}; };
// Base class for Annotation and Call instances.
class InstanceBase {
public:
InstanceBase(){};
virtual ~InstanceBase(){};
virtual AuditorResult Deserialize(
const std::vector<std::string>& serialized_lines,
int start_line,
int end_line) = 0;
};
// Holds an instance of network traffic annotation. // Holds an instance of network traffic annotation.
// TODO(rhalavati): Check if this class can also be reused in clang tool. // TODO(rhalavati): Check if this class can also be reused in clang tool.
class AnnotationInstance { class AnnotationInstance : public InstanceBase {
public: public:
// Annotation Type. // Annotation Type.
enum class AnnotationType { enum class AnnotationType {
...@@ -115,7 +126,7 @@ class AnnotationInstance { ...@@ -115,7 +126,7 @@ class AnnotationInstance {
// FATAL, furthur processing of the text should be stopped. // FATAL, furthur processing of the text should be stopped.
AuditorResult Deserialize(const std::vector<std::string>& serialized_lines, AuditorResult Deserialize(const std::vector<std::string>& serialized_lines,
int start_line, int start_line,
int end_line); int end_line) override;
// Protobuf of the annotation. // Protobuf of the annotation.
traffic_annotation::NetworkTrafficAnnotation proto; traffic_annotation::NetworkTrafficAnnotation proto;
...@@ -134,7 +145,7 @@ class AnnotationInstance { ...@@ -134,7 +145,7 @@ class AnnotationInstance {
// Holds an instance of calling a function that might have a network traffic // Holds an instance of calling a function that might have a network traffic
// annotation argument. // annotation argument.
// TODO(rhalavati): Check if this class can also be reused in clang tool. // TODO(rhalavati): Check if this class can also be reused in clang tool.
class CallInstance { class CallInstance : public InstanceBase {
public: public:
CallInstance(); CallInstance();
CallInstance(const CallInstance& other); CallInstance(const CallInstance& other);
...@@ -152,7 +163,7 @@ class CallInstance { ...@@ -152,7 +163,7 @@ class CallInstance {
// FATAL, further processing of the text should be stopped. // FATAL, further processing of the text should be stopped.
AuditorResult Deserialize(const std::vector<std::string>& serialized_lines, AuditorResult Deserialize(const std::vector<std::string>& serialized_lines,
int start_line, int start_line,
int end_line); int end_line) override;
std::string file_path; std::string file_path;
uint32_t line_number; uint32_t line_number;
...@@ -205,7 +216,7 @@ class TrafficAnnotationAuditor { ...@@ -205,7 +216,7 @@ class TrafficAnnotationAuditor {
// texts. This list includes all unique ids that are defined in // texts. This list includes all unique ids that are defined in
// net/traffic_annotation/network_traffic_annotation.h and // net/traffic_annotation/network_traffic_annotation.h and
// net/traffic_annotation/network_traffic_annotation_test_helper.h // net/traffic_annotation/network_traffic_annotation_test_helper.h
const std::map<int, std::string>& GetReservedUniqueIDs(); static const std::map<int, std::string>& GetReservedUniqueIDs();
std::string clang_tool_raw_output() const { return clang_tool_raw_output_; }; std::string clang_tool_raw_output() const { return clang_tool_raw_output_; };
...@@ -217,14 +228,20 @@ class TrafficAnnotationAuditor { ...@@ -217,14 +228,20 @@ class TrafficAnnotationAuditor {
return extracted_annotations_; return extracted_annotations_;
} }
void SetExtractedAnnotationsForTest(
const std::vector<AnnotationInstance>& annotations) {
extracted_annotations_ = annotations;
}
const std::vector<CallInstance>& extracted_calls() const { const std::vector<CallInstance>& extracted_calls() const {
return extracted_calls_; return extracted_calls_;
} }
const std::vector<AuditorResult>& errors() const { return errors_; } const std::vector<AuditorResult>& errors() const { return errors_; }
private: void ClearErrorsForTest() { errors_.clear(); }
private:
const base::FilePath source_path_; const base::FilePath source_path_;
const base::FilePath build_path_; const base::FilePath build_path_;
......
...@@ -183,7 +183,7 @@ int main(int argc, char* argv[]) { ...@@ -183,7 +183,7 @@ int main(int argc, char* argv[]) {
} }
const std::map<int, std::string> reserved_ids = const std::map<int, std::string> reserved_ids =
auditor.GetReservedUniqueIDs(); TrafficAnnotationAuditor::GetReservedUniqueIDs();
for (const auto& item : reserved_ids) for (const auto& item : reserved_ids)
items.push_back(item); items.push_back(item);
......
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/files/file_util.h" #include "base/files/file_util.h"
#include "base/path_service.h" #include "base/path_service.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "net/traffic_annotation/network_traffic_annotation.h" #include "net/traffic_annotation/network_traffic_annotation.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "tools/traffic_annotation/auditor/traffic_annotation_file_filter.h" #include "tools/traffic_annotation/auditor/traffic_annotation_file_filter.h"
...@@ -37,21 +39,45 @@ class TrafficAnnotationAuditorTest : public ::testing::Test { ...@@ -37,21 +39,45 @@ class TrafficAnnotationAuditorTest : public ::testing::Test {
return; return;
} }
git_list_mock_file_ = source_path_.Append(FILE_PATH_LITERAL("tools")) tests_folder_ = source_path_.Append(FILE_PATH_LITERAL("tools"))
.Append(FILE_PATH_LITERAL("traffic_annotation")) .Append(FILE_PATH_LITERAL("traffic_annotation"))
.Append(FILE_PATH_LITERAL("auditor")) .Append(FILE_PATH_LITERAL("auditor"))
.Append(FILE_PATH_LITERAL("tests")) .Append(FILE_PATH_LITERAL("tests"));
.Append(FILE_PATH_LITERAL("git_list.txt"));
} }
const base::FilePath source_path() const { return source_path_; }
const base::FilePath build_path() const { return build_path_; }
const base::FilePath tests_folder() const { return tests_folder_; };
protected: protected:
// Deserializes an annotation or a call instance from a sample file similar to
// clang tool outputs.
AuditorResult::ResultType Deserialize(const std::string& file_name,
InstanceBase* instance);
private:
base::FilePath source_path_; base::FilePath source_path_;
base::FilePath build_path_; // Currently stays empty. Will be set if access base::FilePath build_path_; // Currently stays empty. Will be set if access
// to a compiled build directory would be // to a compiled build directory would be
// granted. // granted.
base::FilePath git_list_mock_file_; base::FilePath tests_folder_;
}; };
AuditorResult::ResultType TrafficAnnotationAuditorTest::Deserialize(
const std::string& file_name,
InstanceBase* instance) {
std::string file_content;
EXPECT_TRUE(base::ReadFileToString(
tests_folder_.Append(FILE_PATH_LITERAL("extractor_outputs"))
.AppendASCII(file_name),
&file_content));
base::RemoveChars(file_content, "\r", &file_content);
std::vector<std::string> lines = base::SplitString(
file_content, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
return instance->Deserialize(lines, 0, static_cast<int>(lines.size())).type();
}
// Tests if the two hash computation functions have the same result. // Tests if the two hash computation functions have the same result.
TEST_F(TrafficAnnotationAuditorTest, HashFunctionCheck) { TEST_F(TrafficAnnotationAuditorTest, HashFunctionCheck) {
TEST_HASH_CODE("test"); TEST_HASH_CODE("test");
...@@ -67,8 +93,9 @@ TEST_F(TrafficAnnotationAuditorTest, HashFunctionCheck) { ...@@ -67,8 +93,9 @@ TEST_F(TrafficAnnotationAuditorTest, HashFunctionCheck) {
// TrafficAnnotationFileFilter::IsFileRelevant. // TrafficAnnotationFileFilter::IsFileRelevant.
TEST_F(TrafficAnnotationAuditorTest, GetFilesFromGit) { TEST_F(TrafficAnnotationAuditorTest, GetFilesFromGit) {
TrafficAnnotationFileFilter filter; TrafficAnnotationFileFilter filter;
filter.SetGitMockFileForTesting(git_list_mock_file_); filter.SetGitMockFileForTesting(
filter.GetFilesFromGit(source_path_); tests_folder().Append(FILE_PATH_LITERAL("git_list.txt")));
filter.GetFilesFromGit(source_path());
const std::vector<std::string> git_files = filter.git_files(); const std::vector<std::string> git_files = filter.git_files();
...@@ -88,8 +115,9 @@ TEST_F(TrafficAnnotationAuditorTest, GetFilesFromGit) { ...@@ -88,8 +115,9 @@ TEST_F(TrafficAnnotationAuditorTest, GetFilesFromGit) {
// of files, given a mock git list file. // of files, given a mock git list file.
TEST_F(TrafficAnnotationAuditorTest, RelevantFilesReceived) { TEST_F(TrafficAnnotationAuditorTest, RelevantFilesReceived) {
TrafficAnnotationFileFilter filter; TrafficAnnotationFileFilter filter;
filter.SetGitMockFileForTesting(git_list_mock_file_); filter.SetGitMockFileForTesting(
filter.GetFilesFromGit(source_path_); tests_folder().Append(FILE_PATH_LITERAL("git_list.txt")));
filter.GetFilesFromGit(source_path());
unsigned int git_files_count = filter.git_files().size(); unsigned int git_files_count = filter.git_files().size();
...@@ -124,7 +152,7 @@ TEST_F(TrafficAnnotationAuditorTest, RelevantFilesReceived) { ...@@ -124,7 +152,7 @@ TEST_F(TrafficAnnotationAuditorTest, RelevantFilesReceived) {
// Inherently checks if TrafficAnnotationFileFilter::LoadWhiteList works and // Inherently checks if TrafficAnnotationFileFilter::LoadWhiteList works and
// AuditorException rules are correctly deserialized. // AuditorException rules are correctly deserialized.
TEST_F(TrafficAnnotationAuditorTest, IsWhitelisted) { TEST_F(TrafficAnnotationAuditorTest, IsWhitelisted) {
TrafficAnnotationAuditor auditor(source_path_, build_path_); TrafficAnnotationAuditor auditor(source_path(), build_path());
for (unsigned int i = 0; for (unsigned int i = 0;
i < static_cast<unsigned int>( i < static_cast<unsigned int>(
...@@ -148,3 +176,148 @@ TEST_F(TrafficAnnotationAuditorTest, IsWhitelisted) { ...@@ -148,3 +176,148 @@ TEST_F(TrafficAnnotationAuditorTest, IsWhitelisted) {
EXPECT_TRUE(auditor.IsWhitelisted("net/url_request/url_request_context.cc", EXPECT_TRUE(auditor.IsWhitelisted("net/url_request/url_request_context.cc",
AuditorException::ExceptionType::MISSING)); AuditorException::ExceptionType::MISSING));
} }
// Tests if annotation instances are corrrectly deserialized.
TEST_F(TrafficAnnotationAuditorTest, AnnotationDeserialization) {
struct AnnotationSample {
std::string file_name;
AuditorResult::ResultType result_type;
AnnotationInstance::AnnotationType annotation_type;
};
AnnotationSample test_cases[] = {
{"good_complete_annotation.txt", AuditorResult::ResultType::RESULT_OK,
AnnotationInstance::AnnotationType::ANNOTATION_COMPLETE},
{"good_branched_completing_annotation.txt",
AuditorResult::ResultType::RESULT_OK,
AnnotationInstance::AnnotationType::ANNOTATION_BRANCHED_COMPLETING},
{"good_completing_annotation.txt", AuditorResult::ResultType::RESULT_OK,
AnnotationInstance::AnnotationType::ANNOTATION_COMPLETENG},
{"good_partial_annotation.txt", AuditorResult::ResultType::RESULT_OK,
AnnotationInstance::AnnotationType::ANNOTATION_PARTIAL},
{"good_test_annotation.txt", AuditorResult::ResultType::RESULT_IGNORE},
{"missing_annotation.txt", AuditorResult::ResultType::ERROR_MISSING},
{"no_annotation.txt", AuditorResult::ResultType::ERROR_NO_ANNOTATION},
{"fatal_annotation1.txt", AuditorResult::ResultType::ERROR_FATAL},
{"fatal_annotation2.txt", AuditorResult::ResultType::ERROR_FATAL},
{"fatal_annotation3.txt", AuditorResult::ResultType::ERROR_FATAL},
{"bad_syntax_annotation1.txt", AuditorResult::ResultType::ERROR_SYNTAX},
{"bad_syntax_annotation2.txt", AuditorResult::ResultType::ERROR_SYNTAX},
{"bad_syntax_annotation3.txt", AuditorResult::ResultType::ERROR_SYNTAX},
{"bad_syntax_annotation4.txt", AuditorResult::ResultType::ERROR_SYNTAX},
};
for (const auto& test_case : test_cases) {
// Check if deserialization result is as expected.
AnnotationInstance annotation;
AuditorResult::ResultType result_type =
Deserialize(test_case.file_name, &annotation);
EXPECT_EQ(result_type, test_case.result_type);
if (result_type == AuditorResult::ResultType::RESULT_OK)
EXPECT_EQ(annotation.annotation_type, test_case.annotation_type);
// Content checks for one complete sample.
if (test_case.file_name != "good_complete_annotation.txt")
continue;
EXPECT_EQ(annotation.proto.unique_id(),
"supervised_user_refresh_token_fetcher");
EXPECT_EQ(annotation.proto.source().file(),
"chrome/browser/supervised_user/legacy/"
"supervised_user_refresh_token_fetcher.cc");
EXPECT_EQ(annotation.proto.source().function(), "OnGetTokenSuccess");
EXPECT_EQ(annotation.proto.source().line(), 166);
EXPECT_EQ(annotation.proto.semantics().sender(), "Supervised Users");
EXPECT_EQ(annotation.proto.policy().cookies_allowed(), false);
}
}
// Tests if call instances are corrrectly deserialized.
TEST_F(TrafficAnnotationAuditorTest, CallDeserialization) {
struct CallSample {
std::string file_name;
AuditorResult::ResultType result_type;
};
CallSample test_cases[] = {
{"good_call.txt", AuditorResult::ResultType::RESULT_OK},
{"bad_call.txt", AuditorResult::ResultType::ERROR_FATAL},
};
for (const auto& test_case : test_cases) {
// Check if deserialization result is as expected.
CallInstance call;
AuditorResult::ResultType result_type =
Deserialize(test_case.file_name, &call);
EXPECT_EQ(result_type, test_case.result_type);
// Content checks for one complete sample.
if (test_case.file_name != "good_call.txt")
continue;
EXPECT_EQ(call.file_path, "headless/public/util/http_url_fetcher.cc");
EXPECT_EQ(call.line_number, 100u);
EXPECT_EQ(call.function_context,
"headless::HttpURLFetcher::Delegate::Delegate");
EXPECT_EQ(call.function_name, "net::URLRequestContext::CreateRequest");
EXPECT_EQ(call.is_annotated, true);
}
}
// Tests if TrafficAnnotationAuditor::CheckDuplicateHashes works as expected.
TEST_F(TrafficAnnotationAuditorTest, CheckDuplicateHashes) {
// Load a valid annotation.
AnnotationInstance test_case;
EXPECT_EQ(Deserialize("good_complete_annotation.txt", &test_case),
AuditorResult::ResultType::RESULT_OK);
const std::map<int, std::string>& reserved_words =
TrafficAnnotationAuditor::GetReservedUniqueIDs();
TrafficAnnotationAuditor auditor(source_path(), build_path());
std::vector<AnnotationInstance> annotations;
// Check for reserved words hash code duplication errors.
for (const auto& reserved_word : reserved_words) {
test_case.unique_id_hash_code = reserved_word.first;
annotations.push_back(test_case);
}
auditor.SetExtractedAnnotationsForTest(annotations);
auditor.CheckDuplicateHashes();
EXPECT_EQ(auditor.errors().size(), reserved_words.size());
for (const auto& error : auditor.errors()) {
EXPECT_EQ(error.type(),
AuditorResult::ResultType::ERROR_RESERVED_UNIQUE_ID_HASH_CODE);
}
// Check if several different hash codes result in no error.
annotations.clear();
for (int i = 0; i < 10; i++) {
// Ensure that the test id is not a reserved hash code.
EXPECT_EQ(reserved_words.find(i), reserved_words.end());
test_case.unique_id_hash_code = i;
annotations.push_back(test_case);
}
auditor.SetExtractedAnnotationsForTest(annotations);
auditor.ClearErrorsForTest();
auditor.CheckDuplicateHashes();
EXPECT_EQ(auditor.errors().size(), 0u);
// Check if repeating the same hash codes results in errors.
annotations.clear();
for (int i = 0; i < 10; i++) {
test_case.unique_id_hash_code = i;
annotations.push_back(test_case);
annotations.push_back(test_case);
}
auditor.SetExtractedAnnotationsForTest(annotations);
auditor.ClearErrorsForTest();
auditor.CheckDuplicateHashes();
EXPECT_EQ(auditor.errors().size(), 10u);
for (const auto& error : auditor.errors()) {
EXPECT_EQ(error.type(),
AuditorResult::ResultType::ERROR_DUPLICATE_UNIQUE_ID_HASH_CODE);
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment