// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // History unit tests come in two flavors: // // 1. The more complicated style is that the unit test creates a full history // service. This spawns a background thread for the history backend, and // all communication is asynchronous. This is useful for testing more // complicated things or end-to-end behavior. // // 2. The simpler style is to create a history backend on this thread and // access it directly without a HistoryService object. This is much simpler // because communication is synchronous. Generally, sets should go through // the history backend (since there is a lot of logic) but gets can come // directly from the HistoryDatabase. This is because the backend generally // has no logic in the getter except threading stuff, which we don't want // to run. #include "components/history/core/browser/history_backend.h" #include #include "base/macros.h" #include "components/history/core/test/history_backend_db_base_test.h" namespace history { namespace { // This must be outside the anonymous namespace for the friend statement in // HistoryBackend to work. class ContentHistoryBackendDBTest : public HistoryBackendDBBaseTest { public: ContentHistoryBackendDBTest() {} ~ContentHistoryBackendDBTest() override {} }; struct InterruptReasonAssociation { std::string name; int value; }; // Test is dependent on interrupt reasons being listed in header file // in order. const InterruptReasonAssociation current_reasons[] = { #define INTERRUPT_REASON(a, b) { #a, b }, #include "content/public/browser/download_interrupt_reason_values.h" #undef INTERRUPT_REASON }; // This represents a list of all reasons we've previously used; // Do Not Remove Any Entries From This List. const InterruptReasonAssociation historical_reasons[] = { {"FILE_FAILED", 1}, {"FILE_ACCESS_DENIED", 2}, {"FILE_NO_SPACE", 3}, {"FILE_NAME_TOO_LONG", 5}, {"FILE_TOO_LARGE", 6}, {"FILE_VIRUS_INFECTED", 7}, {"FILE_TRANSIENT_ERROR", 10}, {"FILE_BLOCKED", 11}, {"FILE_SECURITY_CHECK_FAILED", 12}, {"FILE_TOO_SHORT", 13}, {"FILE_HASH_MISMATCH", 14}, {"NETWORK_FAILED", 20}, {"NETWORK_TIMEOUT", 21}, {"NETWORK_DISCONNECTED", 22}, {"NETWORK_SERVER_DOWN", 23}, {"NETWORK_INVALID_REQUEST", 24}, {"SERVER_FAILED", 30}, {"SERVER_NO_RANGE", 31}, {"SERVER_PRECONDITION", 32}, {"SERVER_BAD_CONTENT", 33}, {"SERVER_UNAUTHORIZED", 34}, {"SERVER_CERT_PROBLEM", 35}, {"SERVER_FORBIDDEN", 36}, {"SERVER_UNREACHABLE", 37}, {"USER_CANCELED", 40}, {"USER_SHUTDOWN", 41}, {"CRASH", 50}, }; // Make sure no one has changed a DownloadInterruptReason we've previously // persisted. TEST_F(ContentHistoryBackendDBTest, ConfirmDownloadInterruptReasonBackwardsCompatible) { // Are there any cases in which a historical number has been repurposed // for an error other than it's original? for (size_t i = 0; i < arraysize(current_reasons); i++) { const InterruptReasonAssociation& cur_reason(current_reasons[i]); bool found = false; for (size_t j = 0; j < arraysize(historical_reasons); ++j) { const InterruptReasonAssociation& hist_reason(historical_reasons[j]); if (hist_reason.value == cur_reason.value) { EXPECT_EQ(cur_reason.name, hist_reason.name) << "Same integer value used for old error \"" << hist_reason.name << "\" as for new error \"" << cur_reason.name << "\"." << std::endl << "**This will cause database conflicts with persisted values**" << std::endl << "Please assign a new, non-conflicting value for the new error."; } if (hist_reason.name == cur_reason.name) { EXPECT_EQ(cur_reason.value, hist_reason.value) << "Same name (\"" << hist_reason.name << "\") maps to a different value historically (" << hist_reason.value << ") and currently (" << cur_reason.value << ")" << std::endl << "This may cause database conflicts with persisted values" << std::endl << "If this error is the same as the old one, you should" << std::endl << "use the old value, and if it is different, you should" << std::endl << "use a new name."; found = true; } } EXPECT_TRUE(found) << "Error \"" << cur_reason.name << "\" not found in historical list." << std::endl << "Please add it."; } } } // namespace } // namespace history