1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "net/spdy/hpack_string_util.h" 6 7#include <cstddef> 8#include <cstring> 9 10#include "base/basictypes.h" 11#include "base/logging.h" 12#include "base/strings/string_piece.h" 13#include "testing/gtest/include/gtest/gtest.h" 14 15namespace net { 16 17namespace { 18 19using std::string; 20 21// Make sure StringPiecesEqualConstantTime() behaves like the regular 22// string equality operator. 23TEST(HpackStringUtilTest, StringPiecesEqualConstantTime) { 24 EXPECT_TRUE(StringPiecesEqualConstantTime("foo", "foo")); 25 EXPECT_FALSE(StringPiecesEqualConstantTime("foo", "foox")); 26 EXPECT_FALSE(StringPiecesEqualConstantTime("foo", "bar")); 27} 28 29// TODO(jgraettinger): Support this benchmark. 30/* 31enum BM_StringPieceEqualityType { 32 STRCMP_EQUAL, 33 STRCMP_FIRST_CHAR_DIFFERS, 34 STRING_PIECES_EQUAL_CONSTANT_TIME_EQUAL, 35 STRING_PIECES_EQUAL_CONSTANT_TIME_FIRST_CHAR_DIFFERS, 36}; 37 38void BM_StringPieceEquality(int iters, int size, int type_int) { 39 BM_StringPieceEqualityType type = 40 static_cast<BM_StringPieceEqualityType>(type_int); 41 string str_a(size, 'x'); 42 string str_b(size, 'x'); 43 int result = 0; 44 switch (type) { 45 case STRCMP_EQUAL: 46 for (int i = 0; i < iters; ++i) { 47 result |= std::strcmp(str_a.c_str(), str_b.c_str()); 48 } 49 CHECK_EQ(result, 0); 50 return; 51 52 case STRCMP_FIRST_CHAR_DIFFERS: 53 str_b[0] = 'y'; 54 for (int i = 0; i < iters; ++i) { 55 result |= std::strcmp(str_a.c_str(), str_b.c_str()); 56 } 57 CHECK_LT(result, 0); 58 return; 59 60 case STRING_PIECES_EQUAL_CONSTANT_TIME_EQUAL: 61 for (int i = 0; i < iters; ++i) { 62 result |= StringPiecesEqualConstantTime(str_a, str_b); 63 } 64 CHECK_EQ(result, 1); 65 return; 66 67 case STRING_PIECES_EQUAL_CONSTANT_TIME_FIRST_CHAR_DIFFERS: 68 str_b[0] = 'y'; 69 for (int i = 0; i < iters; ++i) { 70 result |= StringPiecesEqualConstantTime(str_a, str_b); 71 } 72 CHECK_EQ(result, 0); 73 return; 74 } 75 76 DCHECK(false); 77} 78 79// Results should resemble the table below, where 0 and 1 are clearly 80// different (STRCMP), but 2 and 3 are roughly the same 81// (STRING_PIECES_EQUAL_CONSTANT_TIME). 82// 83// DEBUG: Benchmark Time(ns) CPU(ns) Iterations 84// ------------------------------------------------------------------- 85// DEBUG: BM_StringPieceEquality/1M/0 77796 77141 7778 86// DEBUG: BM_StringPieceEquality/1M/1 10 10 70000000 87// DEBUG: BM_StringPieceEquality/1M/2 7729735 7700000 100 88// DEBUG: BM_StringPieceEquality/1M/3 7803051 7800000 100 89BENCHMARK(BM_StringPieceEquality) 90 ->ArgPair(1<<20, STRCMP_EQUAL) 91 ->ArgPair(1<<20, STRCMP_FIRST_CHAR_DIFFERS) 92 ->ArgPair(1<<20, STRING_PIECES_EQUAL_CONSTANT_TIME_EQUAL) 93 ->ArgPair(1<<20, STRING_PIECES_EQUAL_CONSTANT_TIME_FIRST_CHAR_DIFFERS); 94*/ 95 96} // namespace 97 98} // namespace net 99