/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you 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.
*/
package org.elasticsearch.index.snapshots.blobstore;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.Version;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.elasticsearch.index.snapshots.blobstore.BlobStoreIndexShardSnapshot.FileInfo;
import org.elasticsearch.index.store.StoreFileMetaData;
import org.elasticsearch.test.ESTestCase;
import java.io.IOException;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
public class FileInfoTests extends ESTestCase {
private static final org.apache.lucene.util.Version MIN_SUPPORTED_LUCENE_VERSION = org.elasticsearch.Version.CURRENT
.minimumIndexCompatibilityVersion().luceneVersion;
public void testToFromXContent() throws IOException {
final int iters = scaledRandomIntBetween(1, 10);
for (int iter = 0; iter < iters; iter++) {
final BytesRef hash = new BytesRef(scaledRandomIntBetween(0, 1024 * 1024));
hash.length = hash.bytes.length;
for (int i = 0; i < hash.length; i++) {
hash.bytes[i] = randomByte();
}
StoreFileMetaData meta = new StoreFileMetaData("foobar", Math.abs(randomLong()), randomAlphaOfLengthBetween(1, 10),
Version.LATEST, hash);
ByteSizeValue size = new ByteSizeValue(Math.abs(randomLong()));
BlobStoreIndexShardSnapshot.FileInfo info = new BlobStoreIndexShardSnapshot.FileInfo("_foobar", meta, size);
XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON).prettyPrint();
BlobStoreIndexShardSnapshot.FileInfo.toXContent(info, builder, ToXContent.EMPTY_PARAMS);
byte[] xcontent = BytesReference.toBytes(shuffleXContent(builder).bytes());
final BlobStoreIndexShardSnapshot.FileInfo parsedInfo;
try (XContentParser parser = createParser(JsonXContent.jsonXContent, xcontent)) {
parser.nextToken();
parsedInfo = BlobStoreIndexShardSnapshot.FileInfo.fromXContent(parser);
}
assertThat(info.name(), equalTo(parsedInfo.name()));
assertThat(info.physicalName(), equalTo(parsedInfo.physicalName()));
assertThat(info.length(), equalTo(parsedInfo.length()));
assertThat(info.checksum(), equalTo(parsedInfo.checksum()));
assertThat(info.partSize(), equalTo(parsedInfo.partSize()));
assertThat(parsedInfo.metadata().hash().length, equalTo(hash.length));
assertThat(parsedInfo.metadata().hash(), equalTo(hash));
assertThat(parsedInfo.metadata().writtenBy(), equalTo(Version.LATEST));
assertThat(parsedInfo.isSame(info.metadata()), is(true));
}
}
public void testInvalidFieldsInFromXContent() throws IOException {
final int iters = scaledRandomIntBetween(1, 10);
for (int iter = 0; iter < iters; iter++) {
final BytesRef hash = new BytesRef(scaledRandomIntBetween(0, 1024 * 1024));
hash.length = hash.bytes.length;
for (int i = 0; i < hash.length; i++) {
hash.bytes[i] = randomByte();
}
String name = "foobar";
String physicalName = "_foobar";
String failure = null;
long length = Math.max(0, Math.abs(randomLong()));
// random corruption
switch (randomIntBetween(0, 3)) {
case 0:
name = "foo,bar";
failure = "missing or invalid file name";
break;
case 1:
physicalName = "_foo,bar";
failure = "missing or invalid physical file name";
break;
case 2:
length = -Math.abs(randomLong());
failure = "missing or invalid file length";
break;
case 3:
break;
default:
fail("shouldn't be here");
}
XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON);
builder.startObject();
builder.field(FileInfo.NAME, name);
builder.field(FileInfo.PHYSICAL_NAME, physicalName);
builder.field(FileInfo.LENGTH, length);
builder.field(FileInfo.WRITTEN_BY, Version.LATEST.toString());
builder.field(FileInfo.CHECKSUM, "666");
builder.endObject();
byte[] xContent = BytesReference.toBytes(builder.bytes());
if (failure == null) {
// No failures should read as usual
final BlobStoreIndexShardSnapshot.FileInfo parsedInfo;
try (XContentParser parser = createParser(JsonXContent.jsonXContent, xContent)) {
parser.nextToken();
parsedInfo = BlobStoreIndexShardSnapshot.FileInfo.fromXContent(parser);
}
assertThat(name, equalTo(parsedInfo.name()));
assertThat(physicalName, equalTo(parsedInfo.physicalName()));
assertThat(length, equalTo(parsedInfo.length()));
assertEquals("666", parsedInfo.checksum());
assertEquals("666", parsedInfo.metadata().checksum());
assertEquals(Version.LATEST, parsedInfo.metadata().writtenBy());
} else {
try (XContentParser parser = createParser(JsonXContent.jsonXContent, xContent)) {
parser.nextToken();
BlobStoreIndexShardSnapshot.FileInfo.fromXContent(parser);
fail("Should have failed with [" + failure + "]");
} catch (ElasticsearchParseException ex) {
assertThat(ex.getMessage(), containsString(failure));
}
}
}
}
public void testGetPartSize() {
BlobStoreIndexShardSnapshot.FileInfo info = new BlobStoreIndexShardSnapshot.FileInfo("foo", new StoreFileMetaData("foo", 36, "666",
MIN_SUPPORTED_LUCENE_VERSION), new ByteSizeValue(6));
int numBytes = 0;
for (int i = 0; i < info.numberOfParts(); i++) {
numBytes += info.partBytes(i);
}
assertEquals(numBytes, 36);
info = new BlobStoreIndexShardSnapshot.FileInfo("foo", new StoreFileMetaData("foo", 35, "666",
MIN_SUPPORTED_LUCENE_VERSION), new ByteSizeValue(6));
numBytes = 0;
for (int i = 0; i < info.numberOfParts(); i++) {
numBytes += info.partBytes(i);
}
assertEquals(numBytes, 35);
final int numIters = randomIntBetween(10, 100);
for (int j = 0; j < numIters; j++) {
StoreFileMetaData metaData = new StoreFileMetaData("foo", randomIntBetween(0, 1000), "666",
MIN_SUPPORTED_LUCENE_VERSION);
info = new BlobStoreIndexShardSnapshot.FileInfo("foo", metaData, new ByteSizeValue(randomIntBetween(1, 1000)));
numBytes = 0;
for (int i = 0; i < info.numberOfParts(); i++) {
numBytes += info.partBytes(i);
}
assertEquals(numBytes, metaData.length());
}
}
}