blob: 9ab64b778ca6d3fabcb260c9f1758dfdd28b23e6 [file] [log] [blame]
/*
* Copyright 2010 Google Inc.
*
* 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.
*/
// Author: jmarantz@google.com (Joshua Marantz)
#include "net/instaweb/rewriter/public/resource_namer.h"
#include "pagespeed/kernel/base/gtest.h"
#include "pagespeed/kernel/base/md5_hasher.h"
#include "pagespeed/kernel/base/mock_hasher.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/base/string_util.h"
namespace net_instaweb {
namespace {
class ResourceNamerTest : public testing::Test {
protected:
ResourceNamerTest() { }
void TestCopyAndSize(int signature_length) {
MockHasher mock_hasher(full_name_.hash());
ResourceNamer copy;
copy.CopyFrom(full_name_);
EXPECT_STREQ(copy.Encode(), full_name_.Encode());
EXPECT_EQ(
full_name_.EventualSize(mock_hasher, signature_length),
full_name_.Encode().size());
}
ResourceNamer full_name_;
};
TEST_F(ResourceNamerTest, TestEncode) {
// Stand up a minimal resource manager that only has the
// resources we should need to encode.
full_name_.set_id("id");
full_name_.set_name("name.ext.as.many.as.I.like");
full_name_.set_hash("hash");
full_name_.set_ext("ext");
TestCopyAndSize(0);
EXPECT_STREQ("name.ext.as.many.as.I.like.pagespeed.id.hash.ext",
full_name_.Encode());
EXPECT_STREQ("id.name.ext.as.many.as.I.like",
full_name_.EncodeIdName());
full_name_.set_experiment("q");
TestCopyAndSize(0);
EXPECT_STREQ("name.ext.as.many.as.I.like.pagespeed.q.id.hash.ext",
full_name_.Encode());
full_name_.set_options("a=b");
full_name_.set_experiment("");
TestCopyAndSize(0);
EXPECT_STREQ("name.ext.as.many.as.I.like.pagespeed.a=b.id.hash.ext",
full_name_.Encode());
full_name_.set_name("name.ext");
full_name_.set_options("options.with.dots");
TestCopyAndSize(0);
EXPECT_STREQ("name.ext.pagespeed.options.with.dots.id.hash.ext",
full_name_.Encode());
full_name_.set_options("options/with/slashes");
EXPECT_STREQ("name.ext.pagespeed.options,_with,_slashes.id.hash.ext",
full_name_.Encode());
TestCopyAndSize(0);
}
TEST_F(ResourceNamerTest, TestDecode) {
EXPECT_TRUE(
full_name_.Decode("name.ext.as.many.as.I.like.pagespeed.id.hash.ext",
4 /*hash size*/, 0 /*signature size*/));
EXPECT_FALSE(full_name_.has_experiment());
EXPECT_STREQ("id", full_name_.id());
EXPECT_STREQ("name.ext.as.many.as.I.like", full_name_.name());
EXPECT_STREQ("hash", full_name_.hash());
EXPECT_STREQ("ext", full_name_.ext());
TestCopyAndSize(0);
}
TEST_F(ResourceNamerTest, TestDecodeExperiment) {
EXPECT_TRUE(
full_name_.Decode("name.ext.as.many.as.I.like.pagespeed.d.id.hash.ext",
4 /*hash size*/, 0 /*signature_size*/));
TestCopyAndSize(0);
EXPECT_STREQ("d", full_name_.experiment());
EXPECT_TRUE(full_name_.has_experiment());
EXPECT_STREQ("id", full_name_.id());
EXPECT_STREQ("name.ext.as.many.as.I.like", full_name_.name());
EXPECT_STREQ("hash", full_name_.hash());
EXPECT_STREQ("ext", full_name_.ext());
EXPECT_TRUE(
full_name_.Decode("name.ext.as.many.as.I.like.pagespeed.de.id.hash.ext",
4 /*hash size*/, 0 /*signature size*/));
TestCopyAndSize(0);
EXPECT_STREQ("", full_name_.experiment());
EXPECT_STREQ("de", full_name_.options());
EXPECT_FALSE(
full_name_.Decode("name.ext.as.many.as.I.like.pagespeed..id.hash.ext",
4 /*hash size*/, 0 /*signature size*/));
EXPECT_FALSE(
full_name_.Decode("name.ext.as.many.as.I.like.pagespeed.D.id.hash.ext",
4 /*hash size*/, 0 /*signature size*/));
EXPECT_FALSE(
full_name_.Decode("name.ext.as.many.as.I.like.pagespeed.`.id.hash.ext",
4 /*hash size*/, 0 /*signature size*/));
EXPECT_FALSE(
full_name_.Decode("name.ext.as.many.as.I.like.pagespeed.{.id.hash.ext",
4 /*hash size*/, 0 /*signature size*/));
EXPECT_TRUE(
full_name_.Decode("name.ext.as.many.as.I.like.pagespeed.a.id.hash.ext",
4 /*hash size*/, 0 /*signature size*/));
TestCopyAndSize(0);
EXPECT_TRUE(
full_name_.Decode("name.ext.as.many.as.I.like.pagespeed.z.id.hash.ext",
4 /*hash size*/, 0 /*signature size*/));
TestCopyAndSize(0);
EXPECT_TRUE(
full_name_.Decode("name.ext.as.many.as.I.like.pagespeed.z.id.hash.ext",
4 /*hash size*/, 0 /*signature size*/));
TestCopyAndSize(0);
EXPECT_STREQ("", full_name_.options());
EXPECT_TRUE(full_name_.Decode("name.ext.pagespeed.opts.id.hash.ext",
4 /*hash size*/, 0 /*signature size*/));
TestCopyAndSize(0);
EXPECT_STREQ("opts", full_name_.options());
// Make sure a decode without options clears them.
EXPECT_TRUE(
full_name_.Decode("name.ext.as.many.as.I.like.pagespeed.z.id.hash.ext",
4 /*hash size*/, 0 /*signature size*/));
TestCopyAndSize(0);
EXPECT_STREQ("", full_name_.options());
}
TEST_F(ResourceNamerTest, TestDecodeOptions) {
EXPECT_TRUE(full_name_.Decode("name.ext.pagespeed.options.id.hash.ext",
4 /*hash size*/, 0 /*signature size*/));
TestCopyAndSize(0);
EXPECT_STREQ("id", full_name_.id());
EXPECT_STREQ("options", full_name_.options());
EXPECT_TRUE(
full_name_.Decode("name.ext.pagespeed.options,_with,_slashes.id.hash.ext",
4 /*hash size*/, 0 /*signature size*/));
TestCopyAndSize(0);
EXPECT_STREQ("options/with/slashes", full_name_.options());
EXPECT_TRUE(
full_name_.Decode("name.ext.pagespeed.options,_with,_slashes.id.hash.ext",
4 /*hash size*/, 0 /*signature size*/));
EXPECT_STREQ("options/with/slashes", full_name_.options());
TestCopyAndSize(0);
EXPECT_TRUE(full_name_.Decode(
"name.ext.pagespeed.options,qwith,aquery=params.id.hash.ext",
4 /*hash size*/, 0 /*signature size*/));
EXPECT_STREQ("options?with&query=params", full_name_.options());
TestCopyAndSize(0);
}
TEST_F(ResourceNamerTest, TestDecodeTooMany) {
EXPECT_TRUE(full_name_.Decode("name.extra_dot.pagespeed.id.hash.ext",
4 /*hash size*/, 0 /*signature size*/));
}
TEST_F(ResourceNamerTest, TestDecodeNotEnough) {
EXPECT_FALSE(
full_name_.Decode("id.name.hash", 4 /*hash size*/, 0 /*signature size*/));
}
TEST_F(ResourceNamerTest, TestLegacyDecode) {
// Legacydecode doesn't include signature at all, and will not use the same
// decode function. Putting -1, -1 because that piece of the code should not
// be hit.
EXPECT_TRUE(full_name_.Decode("id.0123456789abcdef0123456789ABCDEF.name.js",
-1 /*hash size*/, -1 /*signature size*/));
EXPECT_STREQ("id", full_name_.id());
EXPECT_STREQ("name", full_name_.name());
EXPECT_STREQ("0123456789abcdef0123456789ABCDEF", full_name_.hash());
EXPECT_STREQ("js", full_name_.ext());
}
TEST_F(ResourceNamerTest, TestEventualSize) {
MockHasher mock_hasher;
GoogleString file = "some_name.pagespeed.idn.0.extension";
EXPECT_TRUE(full_name_.Decode(file, 1 /*hash size*/, 0 /*signature size*/));
EXPECT_EQ(file.size(),
full_name_.EventualSize(mock_hasher, 0 /*signature size*/));
}
TEST_F(ResourceNamerTest, TestEventualSizeExperiment) {
MockHasher mock_hasher;
GoogleString file = "some_name.pagespeed.c.idn.0.extension";
EXPECT_TRUE(full_name_.Decode(file, 1 /*hash size*/, 0 /*signature size*/));
EXPECT_EQ(file.size(),
full_name_.EventualSize(mock_hasher, 0 /*signature size*/));
}
TEST_F(ResourceNamerTest, TestEventualSizeSignature) {
MockHasher mock_hasher;
GoogleString file = "some_name.pagespeed.idn.0sig.extension";
EXPECT_TRUE(full_name_.Decode(file, 1 /*hash size*/, 3 /*signature size*/));
EXPECT_EQ(file.size(),
full_name_.EventualSize(mock_hasher, 3 /*signature size*/));
EXPECT_STREQ("sig", full_name_.signature());
EXPECT_STREQ("extension", full_name_.ext());
EXPECT_STREQ("0", full_name_.hash());
}
TEST_F(ResourceNamerTest, TestAllSignaturePossibilites) {
// Test with the signature on.
full_name_.set_id("id");
full_name_.set_name("name.ext.as.many.as.I.like");
full_name_.set_hash("hash");
full_name_.set_ext("ext");
full_name_.set_signature("sig");
TestCopyAndSize(3);
EXPECT_STREQ("name.ext.as.many.as.I.like.pagespeed.id.hashsig.ext",
full_name_.Encode());
// Test with the signature off.
full_name_.set_signature("");
TestCopyAndSize(0);
EXPECT_STREQ("name.ext.as.many.as.I.like.pagespeed.id.hash.ext",
full_name_.Encode());
// Test with experiment on and signature on.
full_name_.set_signature("sig");
full_name_.set_experiment("q");
EXPECT_STREQ("name.ext.as.many.as.I.like.pagespeed.q.id.hashsig.ext",
full_name_.Encode());
// Test with experiment on and signature off.
full_name_.set_signature("");
EXPECT_STREQ("name.ext.as.many.as.I.like.pagespeed.q.id.hash.ext",
full_name_.Encode());
// Test with experiment and options on and signature on can't be done.
// Test with experiment and options on and signature off can't be done.
// Test with options on and signature on.
full_name_.set_experiment("");
full_name_.set_options("a=b");
full_name_.set_signature("sig");
EXPECT_STREQ("name.ext.as.many.as.I.like.pagespeed.a=b.id.hashsig.ext",
full_name_.Encode());
// Test with options on and signature off.
full_name_.set_signature("");
EXPECT_STREQ("name.ext.as.many.as.I.like.pagespeed.a=b.id.hash.ext",
full_name_.Encode());
}
TEST_F(ResourceNamerTest, TestSizeWithoutHash_HashNotSet) {
MD5Hasher md5_hasher;
full_name_.set_name("file.css");
full_name_.set_id("id");
full_name_.set_ext("ext");
EXPECT_EQ(STATIC_STRLEN("file.css") + STATIC_STRLEN("id") +
STATIC_STRLEN("ext") + ResourceNamer::kOverhead +
md5_hasher.HashSizeInChars(),
full_name_.EventualSize(md5_hasher, 0 /*signature size*/));
}
} // namespace
} // namespace net_instaweb