From 74d139f5f3c19ce4dca74ae5cde6105fef25d1f5 Mon Sep 17 00:00:00 2001 From: Nikita Smirnov <46124551+Nikita-Smirnov-Exactpro@users.noreply.github.com> Date: Wed, 20 Sep 2023 11:33:58 +0400 Subject: [PATCH] =?UTF-8?q?[TH2-5015]=20Fixed=20NPE=20when=20book=20cache?= =?UTF-8?q?=20loads=20pages=20with=20removed=20field=20n=E2=80=A6=20(#252)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cassandra/ReadThroughBookCache.java | 2 +- .../cassandra/ReadThroughBookCacheTest.java | 145 ++++++++++++++++++ gradle.properties | 2 +- 3 files changed, 147 insertions(+), 2 deletions(-) create mode 100644 cradle-cassandra/src/test/java/com/exactpro/cradle/cassandra/ReadThroughBookCacheTest.java diff --git a/cradle-cassandra/src/main/java/com/exactpro/cradle/cassandra/ReadThroughBookCache.java b/cradle-cassandra/src/main/java/com/exactpro/cradle/cassandra/ReadThroughBookCache.java index d527a595..27408046 100644 --- a/cradle-cassandra/src/main/java/com/exactpro/cradle/cassandra/ReadThroughBookCache.java +++ b/cradle-cassandra/src/main/java/com/exactpro/cradle/cassandra/ReadThroughBookCache.java @@ -73,7 +73,7 @@ public boolean checkBook(BookId bookId) { public Collection loadPageInfo(BookId bookId, boolean loadRemoved) { Collection result = new ArrayList<>(); for (PageEntity pageEntity : operators.getPageOperator().getAll(bookId.getName(), readAttrs)) { - if (loadRemoved || pageEntity.getRemoved().equals(DEFAULT_PAGE_REMOVE_TIME)) { + if (loadRemoved || pageEntity.getRemoved() == null || pageEntity.getRemoved().equals(DEFAULT_PAGE_REMOVE_TIME)) { result.add(pageEntity.toPageInfo()); } } diff --git a/cradle-cassandra/src/test/java/com/exactpro/cradle/cassandra/ReadThroughBookCacheTest.java b/cradle-cassandra/src/test/java/com/exactpro/cradle/cassandra/ReadThroughBookCacheTest.java new file mode 100644 index 00000000..6f5570c3 --- /dev/null +++ b/cradle-cassandra/src/test/java/com/exactpro/cradle/cassandra/ReadThroughBookCacheTest.java @@ -0,0 +1,145 @@ +/* + * Copyright 2023 Exactpro (Exactpro Systems Limited) + * + * 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. + */ + +package com.exactpro.cradle.cassandra; + +import com.datastax.oss.driver.api.core.PagingIterable; +import com.datastax.oss.driver.api.core.cql.BoundStatementBuilder; +import com.exactpro.cradle.BookId; +import com.exactpro.cradle.cassandra.dao.CassandraOperators; +import com.exactpro.cradle.cassandra.dao.books.BookEntity; +import com.exactpro.cradle.cassandra.dao.books.BookOperator; +import com.exactpro.cradle.cassandra.dao.books.PageEntity; +import com.exactpro.cradle.cassandra.dao.books.PageOperator; +import com.exactpro.cradle.errors.BookNotFoundException; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.util.List; +import java.util.function.Function; + +import static com.exactpro.cradle.cassandra.CassandraStorageSettings.DEFAULT_PAGE_REMOVE_TIME; +import static org.mockito.ArgumentMatchers.same; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.testng.Assert.assertEquals; + +@SuppressWarnings("unchecked") +public class ReadThroughBookCacheTest { + private final Instant currentTime = Instant.now(); + private final ZoneId zoneId = ZoneOffset.UTC; + private final BookId bookId = new BookId("test-book"); + private final String schemaVersion = "test-schema-version"; + private final BookEntity bookEntity = new BookEntity(bookId.getName(), + "test-book-full-name", + "test-description", + currentTime, + schemaVersion); + private final PagingIterable pagingIterable = mock(PagingIterable.class); + private final PageOperator pageOperator = mock(PageOperator.class); + private final BookOperator bookOperator = mock(BookOperator.class); + private final CassandraOperators operators = mock(CassandraOperators.class); + private final Function readAttrs = mock(Function.class); + private final ReadThroughBookCache cache = new ReadThroughBookCache(operators, readAttrs, schemaVersion); + + List previousFormatPages = List.of( + new PageEntity(bookId.getName(), + LocalDate.ofInstant(currentTime.minusSeconds(1), zoneId), + LocalTime.ofInstant(currentTime.minusSeconds(1), zoneId), + "test-page-1", + null, + LocalDate.ofInstant(currentTime, zoneId), + LocalTime.ofInstant(currentTime, zoneId), + null, + null), + new PageEntity(bookId.getName(), + LocalDate.ofInstant(currentTime, zoneId), + LocalTime.ofInstant(currentTime, zoneId), + "test-page-2", + null, + null, + null, + null, + null) + ); + List newFormatPages = List.of( + new PageEntity(bookId.getName(), + LocalDate.ofInstant(currentTime.minusSeconds(1), zoneId), + LocalTime.ofInstant(currentTime.minusSeconds(1), zoneId), + "test-page-1", + null, + LocalDate.ofInstant(currentTime, zoneId), + LocalTime.ofInstant(currentTime, zoneId), + null, + DEFAULT_PAGE_REMOVE_TIME), + new PageEntity(bookId.getName(), + LocalDate.ofInstant(currentTime, zoneId), + LocalTime.ofInstant(currentTime, zoneId), + "test-page-2", + null, + null, + null, + null, + DEFAULT_PAGE_REMOVE_TIME) + ); + + @BeforeMethod + public void beforeMethod() { + doReturn(pageOperator).when(operators).getPageOperator(); + doReturn(bookOperator).when(operators).getBookOperator(); + doReturn(pagingIterable).when(pageOperator).getAll(same(bookId.getName()), same(readAttrs)); + doReturn(bookEntity).when(bookOperator).get(same(bookId.getName()), same(readAttrs)); + } + + @Test(dataProvider = "loadRemoved") + public void testLoadPageInfoPreviousFormat(boolean loadRemoved) { + doReturn(previousFormatPages.iterator()).when(pagingIterable).iterator(); + + assertEquals(cache.loadPageInfo(bookId, loadRemoved).size(), 2); + } + + @Test(dataProvider = "loadRemoved") + public void testLoadPageInfoNewFormat(boolean loadRemoved) { + doReturn(newFormatPages.iterator()).when(pagingIterable).iterator(); + + assertEquals(cache.loadPageInfo(bookId, loadRemoved).size(), 2); + } + + @Test + public void testGetBookPreviousFormat() throws BookNotFoundException { + doReturn(previousFormatPages.iterator()).when(pagingIterable).iterator(); + + assertEquals(cache.getBook(bookId).getId(), bookId); + } + + @Test + public void testGetBookNewFormat() throws BookNotFoundException { + doReturn(newFormatPages.iterator()).when(pagingIterable).iterator(); + + assertEquals(cache.getBook(bookId).getId(), bookId); + } + + @DataProvider(name = "loadRemoved") + public static Object[][] loadRemovedProvider() { + return new Object[][]{{Boolean.TRUE}, {Boolean.FALSE}}; + } +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index de81e4a5..60a79290 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ -release_version=5.1.3 +release_version=5.1.4 description='Cradle API' vcs_url=https://github.com/th2-net/cradleapi