blob: b3c0dcc8381ab83338688f69b1a9942828f40177 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.apache.ignite.internal.configuration.storage;
import static org.apache.ignite.internal.testframework.flow.TestFlowUtils.fromCursor;
import static org.apache.ignite.internal.testframework.matchers.CompletableFutureMatcher.willCompleteSuccessfully;
import static org.apache.ignite.internal.util.CompletableFutures.nullCompletedFuture;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyCollection;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.Collection;
import java.util.concurrent.CompletableFuture;
import org.apache.ignite.internal.hlc.HybridTimestamp;
import org.apache.ignite.internal.lang.ByteArray;
import org.apache.ignite.internal.metastorage.MetaStorageManager;
import org.apache.ignite.internal.metastorage.dsl.Operation;
import org.apache.ignite.internal.metastorage.dsl.SimpleCondition;
import org.apache.ignite.internal.metastorage.server.Condition;
import org.apache.ignite.internal.metastorage.server.ExistenceCondition;
import org.apache.ignite.internal.metastorage.server.KeyValueStorage;
import org.apache.ignite.internal.metastorage.server.RevisionCondition;
import org.apache.ignite.internal.metastorage.server.SimpleInMemoryKeyValueStorage;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
/**
* Tests for the {@link DistributedConfigurationStorage}.
*/
public class DistributedConfigurationStorageTest extends ConfigurationStorageTest {
private final KeyValueStorage metaStorage = new SimpleInMemoryKeyValueStorage("test");
private final MetaStorageManager metaStorageManager = mockMetaStorageManager();
/**
* Before each.
*/
@BeforeEach
void start() {
metaStorage.start();
assertThat(metaStorageManager.startAsync(), willCompleteSuccessfully());
}
/**
* After each.
*/
@AfterEach
void stop() throws Exception {
assertThat(metaStorageManager.stopAsync(), willCompleteSuccessfully());
metaStorage.close();
}
/** {@inheritDoc} */
@Override
public ConfigurationStorage getStorage() {
return new DistributedConfigurationStorage("test", metaStorageManager);
}
/**
* Creates a mock implementation of a {@link MetaStorageManager}.
*/
private MetaStorageManager mockMetaStorageManager() {
var mock = mock(MetaStorageManager.class);
when(mock.invoke(any(), anyCollection(), anyCollection())).thenAnswer(invocation -> {
SimpleCondition condition = invocation.getArgument(0);
Collection<Operation> success = invocation.getArgument(1);
Collection<Operation> failure = invocation.getArgument(2);
boolean invokeResult = metaStorage.invoke(toServerCondition(condition), success, failure, HybridTimestamp.MIN_VALUE);
return CompletableFuture.completedFuture(invokeResult);
});
when(mock.prefix(any())).thenAnswer(invocation -> {
ByteArray prefix = invocation.getArgument(0);
return fromCursor(metaStorage.range(prefix.bytes(), metaStorage.nextKey(prefix.bytes())));
});
when(mock.startAsync()).thenReturn(nullCompletedFuture());
when(mock.stopAsync()).thenReturn(nullCompletedFuture());
return mock;
}
/**
* Converts a {@link SimpleCondition} to a {@link Condition}.
*/
private static Condition toServerCondition(SimpleCondition condition) {
switch (condition.type()) {
case REV_LESS_OR_EQUAL:
return new RevisionCondition(
RevisionCondition.Type.LESS_OR_EQUAL,
condition.key(),
((SimpleCondition.RevisionCondition) condition).revision()
);
case KEY_NOT_EXISTS:
return new ExistenceCondition(
ExistenceCondition.Type.NOT_EXISTS,
condition.key()
);
default:
throw new UnsupportedOperationException("Unsupported condition type: " + condition.type());
}
}
}