From 5e734eeed030f6919f5a7ac04784f9ff0ad3bddc Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Wed, 30 Dec 2015 19:31:32 +0100 Subject: [PATCH 1/4] Add functional classes for BigQuery datasets jobs and tables --- .../com/google/gcloud/bigquery/Dataset.java | 285 ++++++++++++++++++ .../java/com/google/gcloud/bigquery/Job.java | 117 +++++++ .../com/google/gcloud/bigquery/Table.java | 276 +++++++++++++++++ .../google/gcloud/bigquery/DatasetTest.java | 197 ++++++++++++ .../com/google/gcloud/bigquery/JobTest.java | 141 +++++++++ .../com/google/gcloud/bigquery/TableTest.java | 243 +++++++++++++++ 6 files changed, 1259 insertions(+) create mode 100644 gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Dataset.java create mode 100644 gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Job.java create mode 100644 gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Table.java create mode 100644 gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/DatasetTest.java create mode 100644 gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobTest.java create mode 100644 gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableTest.java diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Dataset.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Dataset.java new file mode 100644 index 000000000000..7c3358fedb99 --- /dev/null +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Dataset.java @@ -0,0 +1,285 @@ +/* + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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.google.gcloud.bigquery; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Function; +import com.google.common.collect.Iterators; +import com.google.gcloud.Page; +import com.google.gcloud.PageImpl; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.Serializable; +import java.util.Iterator; +import java.util.List; +import java.util.Objects; + +/** + * A Google BigQuery Dataset. + * + *

Objects of this class are immutable. Operations that modify the dataset like {@link #update} + * return a new object. To get a {@code Dataset} object with the most recent information use + * {@link #reload}. + *

+ */ +public final class Dataset { + + private final BigQuery bigquery; + private final DatasetInfo info; + + private static class TablePageFetcher implements PageImpl.NextPageFetcher { + + private static final long serialVersionUID = 6906197848579250598L; + + private final BigQueryOptions options; + private final Page infoPage; + + TablePageFetcher(BigQueryOptions options, Page infoPage) { + this.options = options; + this.infoPage = infoPage; + } + + @Override + public Page
nextPage() { + Page nextInfoPage = infoPage.nextPage(); + return new PageImpl<>(new TablePageFetcher(options, nextInfoPage), + nextInfoPage.nextPageCursor(), new LazyTableIterable(options, nextInfoPage.values())); + } + } + + private static class LazyTableIterable implements Iterable
, Serializable { + + private static final long serialVersionUID = 3312744215731674032L; + + private final BigQueryOptions options; + private Iterable infoIterable; + private transient BigQuery bigquery; + + public LazyTableIterable(BigQueryOptions options, Iterable infoIterable) { + this.options = options; + this.infoIterable = infoIterable; + this.bigquery = options.service(); + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + in.defaultReadObject(); + this.bigquery = options.service(); + } + + @Override + public Iterator
iterator() { + return Iterators.transform(infoIterable.iterator(), new Function() { + @Override + public Table apply(BaseTableInfo tableInfo) { + return new Table(bigquery, tableInfo); + } + }); + } + + @Override + public int hashCode() { + return Objects.hash(options, infoIterable); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof LazyTableIterable)) { + return false; + } + LazyTableIterable other = (LazyTableIterable) obj; + return Objects.equals(options, other.options) + && Objects.equals(infoIterable, other.infoIterable); + } + } + + /** + * Constructs a {@code Dataset} object for the provided {@code DatasetInfo}. The BigQuery service + * is used to issue requests. + * + * @param bigquery the BigQuery service used for issuing requests + * @param info dataset's info + */ + public Dataset(BigQuery bigquery, DatasetInfo info) { + this.bigquery = checkNotNull(bigquery); + this.info = checkNotNull(info); + } + + /** + * Creates a {@code Dataset} object for the provided dataset's user-defined id. Performs an RPC + * call to get the latest dataset information. + * + * @param bigquery the BigQuery service used for issuing requests + * @param dataset dataset's user-defined id + * @return the {@code Dataset} object or {@code null} if not found. + * @throws BigQueryException upon failure + */ + public static Dataset load(BigQuery bigquery, String dataset) { + DatasetInfo info = bigquery.getDataset(dataset); + return info != null ? new Dataset(bigquery, info) : null; + } + + /** + * Returns the dataset's information. + */ + public DatasetInfo info() { + return info; + } + + /** + * Checks if this dataset exists. + * + * @return {@code true} if this dataset exists, {@code false} otherwise. + * @throws BigQueryException upon failure + */ + public boolean exists() { + return bigquery.getDataset(info.datasetId(), BigQuery.DatasetOption.fields()) != null; + } + + /** + * Fetches current dataset's latest information. + * + * @param options dataset options + * @return a {@code Dataset} object with latest information. + * @throws BigQueryException upon failure + */ + public Dataset reload(BigQuery.DatasetOption... options) { + return new Dataset(bigquery, bigquery.getDataset(info.datasetId(), options)); + } + + /** + * Updates the dataset's information. Dataset's user-defined id cannot be changed. A new + * {@code Dataset} object is returned. + * + * @param datasetInfo new dataset's information. User-defined id must match the one of the current + * dataset + * @param options dataset options + * @return a {@code Dataset} object with updated information. + * @throws BigQueryException upon failure + */ + public Dataset update(DatasetInfo datasetInfo, BigQuery.DatasetOption... options) { + checkArgument(Objects.equals(datasetInfo.datasetId().dataset(), + info.datasetId().dataset()), "Dataset's user-defined ids must match"); + return new Dataset(bigquery, bigquery.update(datasetInfo, options)); + } + + /** + * Deletes this dataset. + * + * @return {@code true} if dataset was deleted, {@code false} if it was not found. + * @throws BigQueryException upon failure + */ + public boolean delete() { + return bigquery.delete(info.datasetId()); + } + + /** + * Returns the paginated list of tables in this dataset. + * + * @param options options for listing tables + * @throws BigQueryException upon failure + */ + public Page
list(BigQuery.TableListOption... options) { + Page infoPage = bigquery.listTables(info.datasetId(), options); + BigQueryOptions bigqueryOptions = bigquery.options(); + return new PageImpl<>(new TablePageFetcher(bigqueryOptions, infoPage), + infoPage.nextPageCursor(), new LazyTableIterable(bigqueryOptions, infoPage.values())); + } + + /** + * Returns the requested table in this dataset or {@code null} if not found. + * + * @param table user-defined id of the requested table + * @param options table options + * @throws BigQueryException upon failure + */ + public Table get(String table, BigQuery.TableOption... options) { + BaseTableInfo tableInfo = + bigquery.getTable(TableId.of(info.datasetId().dataset(), table), options); + return tableInfo != null ? new Table(bigquery, tableInfo) : null; + } + + /** + * Creates a new simple table in this dataset. + * + * @param table the table's user-defined id + * @param schema the table's schema + * @param options options for table creation + * @return a {@code Table} object for the created table. + * @throws BigQueryException upon failure + */ + public Table create(String table, Schema schema, BigQuery.TableOption... options) { + BaseTableInfo tableInfo = TableInfo.of(TableId.of(info.datasetId().dataset(), table), schema); + return new Table(bigquery, bigquery.create(tableInfo, options)); + } + + /** + * Creates a new view table in this dataset. + * + * @param table the table's user-defined id + * @param query the query used to generate the table + * @param functions user-defined functions that can be used by the query + * @param options options for table creation + * @return a {@code Table} object for the created table. + * @throws BigQueryException upon failure + */ + public Table create(String table, String query, List functions, + BigQuery.TableOption... options) { + BaseTableInfo tableInfo = + ViewInfo.of(TableId.of(info.datasetId().dataset(), table), query, functions); + return new Table(bigquery, bigquery.create(tableInfo, options)); + } + + /** + * Creates a new view table in this dataset. + * + * @param table the table's user-defined id + * @param query the query used to generate the table + * @param options options for table creation + * @return a {@code Table} object for the created table. + * @throws BigQueryException upon failure + */ + public Table create(String table, String query, BigQuery.TableOption... options) { + BaseTableInfo tableInfo = ViewInfo.of(TableId.of(info.datasetId().dataset(), table), query); + return new Table(bigquery, bigquery.create(tableInfo, options)); + } + + /** + * Creates a new external table in this dataset. + * + * @param table the table's user-defined id + * @param configuration data format, location and other properties of an external table + * @param options options for table creation + * @return a {@code Table} object for the created table. + * @throws BigQueryException upon failure + */ + public Table create(String table, ExternalDataConfiguration configuration, + BigQuery.TableOption... options) { + BaseTableInfo tableInfo = + ExternalTableInfo.of(TableId.of(info.datasetId().dataset(), table), configuration); + return new Table(bigquery, bigquery.create(tableInfo, options)); + } + + /** + * Returns the dataset's {@code BigQuery} object used to issue requests. + */ + public BigQuery bigquery() { + return bigquery; + } +} diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Job.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Job.java new file mode 100644 index 000000000000..06e9b1ced569 --- /dev/null +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Job.java @@ -0,0 +1,117 @@ +/* + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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.google.gcloud.bigquery; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * A Google BigQuery Job. + * + *

Objects of this class are immutable. To get a {@code Job} object with the most recent + * information use {@link #reload}. + *

+ */ +public final class Job { + + private final BigQuery bigquery; + private final JobInfo info; + + /** + * Constructs a {@code Job} object for the provided {@code JobInfo}. The BigQuery service + * is used to issue requests. + * + * @param bigquery the BigQuery service used for issuing requests + * @param info jobs's info + */ + public Job(BigQuery bigquery, JobInfo info) { + this.bigquery = checkNotNull(bigquery); + this.info = checkNotNull(info); + } + + /** + * Creates a {@code Job} object for the provided job's user-defined id. Performs an RPC call + * to get the latest job information. + * + * @param bigquery the BigQuery service used for issuing requests + * @param job job's id, either user-defined or picked by the BigQuery service + * @return the {@code Job} object or {@code null} if not found. + * @throws BigQueryException upon failure + */ + public static Job load(BigQuery bigquery, String job) { + JobInfo info = bigquery.getJob(job); + return info != null ? new Job(bigquery, info) : null; + } + + /** + * Returns the job's information. + */ + public JobInfo info() { + return info; + } + + /** + * Checks if this job exists. + * + * @return {@code true} if this job exists, {@code false} otherwise. + * @throws BigQueryException upon failure + */ + public boolean exists() { + return bigquery.getJob(info.jobId(), BigQuery.JobOption.fields()) != null; + } + + /** + * Checks if this job has completed its execution, either failing or succeeding. + * + * @return {@code true} if this job is in {@link JobStatus.State#DONE} state, {@code false} if the + * state is not {@link JobStatus.State#DONE} or the job does not exist. + * @throws BigQueryException upon failure + */ + public boolean isDone() { + JobInfo job = bigquery.getJob(info.jobId(), + BigQuery.JobOption.fields(BigQuery.JobField.STATUS)); + return job != null && job.status().state() == JobStatus.State.DONE; + } + + /** + * Fetches current job's latest information. + * + * @param options job options + * @return a {@code Job} object with latest information. + * @throws BigQueryException upon failure + */ + public Job reload(BigQuery.JobOption... options) { + return new Job(bigquery, bigquery.getJob(info.jobId(), options)); + } + + /** + * Sends a job cancel request. + * + * @return {@code true} if cancel request was sent successfully, {@code false} if job was not + * found. + * @throws BigQueryException upon failure + */ + public boolean cancel() { + return bigquery.cancel(info.jobId()); + } + + /** + * Returns the job's {@code BigQuery} object used to issue requests. + */ + public BigQuery bigquery() { + return bigquery; + } +} diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Table.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Table.java new file mode 100644 index 000000000000..33cbe602033a --- /dev/null +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Table.java @@ -0,0 +1,276 @@ +/* + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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.google.gcloud.bigquery; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.collect.ImmutableList; +import com.google.gcloud.Page; + +import java.util.List; +import java.util.Objects; + +/** + * A Google BigQuery Table. + * + *

Objects of this class are immutable. Operations that modify the table like {@link #update} + * return a new object. To get a {@code Table} object with the most recent information use + * {@link #reload}. + *

+ */ +public final class Table { + + private final BigQuery bigquery; + private final BaseTableInfo info; + + /** + * Constructs a {@code Table} object for the provided {@code TableInfo}. The BigQuery service + * is used to issue requests. + * + * @param bigquery the BigQuery service used for issuing requests + * @param info table's info + */ + public Table(BigQuery bigquery, BaseTableInfo info) { + this.bigquery = checkNotNull(bigquery); + this.info = checkNotNull(info); + } + + /** + * Creates a {@code Table} object for the provided dataset and table's user-defined ids. Performs + * an RPC call to get the latest table information. + * + * @param bigquery the BigQuery service used for issuing requests + * @param dataset the dataset's user-defined id + * @param table the table's user-defined id + * @return the {@code Table} object or {@code null} if not found. + * @throws BigQueryException upon failure + */ + public static Table load(BigQuery bigquery, String dataset, String table) { + return load(bigquery, TableId.of(dataset, table)); + } + + /** + * Creates a {@code Table} object for the provided table identity. Performs an RPC call to get the + * latest table information. + * + * @param bigquery the BigQuery service used for issuing requests + * @param table the table's identity + * @return the {@code Table} object or {@code null} if not found. + * @throws BigQueryException upon failure + */ + public static Table load(BigQuery bigquery, TableId table) { + BaseTableInfo info = bigquery.getTable(table); + return info != null ? new Table(bigquery, info) : null; + } + + /** + * Returns the table's information. + */ + public BaseTableInfo info() { + return info; + } + + /** + * Checks if this table exists. + * + * @return {@code true} if this table exists, {@code false} otherwise. + * @throws BigQueryException upon failure + */ + public boolean exists() { + return bigquery.getTable(info.tableId(), BigQuery.TableOption.fields()) != null; + } + + /** + * Fetches current table's latest information. + * + * @param options table options + * @return a {@code Table} object with latest information. + * @throws BigQueryException upon failure + */ + public Table reload(BigQuery.TableOption... options) { + return new Table(bigquery, bigquery.getTable(info.tableId(), options)); + } + + /** + * Updates the table's information. Dataset's and table's user-defined ids cannot be changed. A + * new {@code Table} object is returned. + * + * @param tableInfo new table's information. Dataset's and table's user-defined ids must match the + * ones of the current table + * @param options dataset options + * @return a {@code Table} object with updated information. + * @throws BigQueryException upon failure + */ + public Table update(BaseTableInfo tableInfo, BigQuery.TableOption... options) { + checkArgument(Objects.equals(tableInfo.tableId().dataset(), + info.tableId().dataset()), "Dataset's user-defined ids must match"); + checkArgument(Objects.equals(tableInfo.tableId().table(), + info.tableId().table()), "Table's user-defined ids must match"); + return new Table(bigquery, bigquery.update(tableInfo, options)); + } + + /** + * Deletes this table. + * + * @return {@code true} if table was deleted, {@code false} if it was not found. + * @throws BigQueryException upon failure + */ + public boolean delete() { + return bigquery.delete(info.tableId()); + } + + /** + * Insert rows into the table. + * + * @param rows rows to be inserted + * @throws BigQueryException upon failure + */ + InsertAllResponse insert(Iterable rows) throws BigQueryException { + return bigquery.insertAll(InsertAllRequest.of(info.tableId(), rows)); + } + + /** + * Insert rows into the table. + * + * @param rows rows to be inserted + * @param skipInvalidRows whether to insert all valid rows, even if invalid rows exist. If not set + * the entire insert operation will fail if rows to be inserted contain an invalid row + * @param ignoreUnknownValues whether to accept rows that contain values that do not match the + * schema. The unknown values are ignored. If not set, rows with unknown values are considered + * to be invalid + * @throws BigQueryException upon failure + */ + InsertAllResponse insert(Iterable rows, boolean skipInvalidRows, + boolean ignoreUnknownValues) throws BigQueryException { + InsertAllRequest request = InsertAllRequest.builder(info.tableId(), rows) + .skipInvalidRows(skipInvalidRows) + .ignoreUnknownValues(ignoreUnknownValues) + .build(); + return bigquery.insertAll(request); + } + + /** + * Returns the paginated list rows in this table. + * + * @param options table data list options + * @throws BigQueryException upon failure + */ + Page> list(BigQuery.TableDataListOption... options) throws BigQueryException { + return bigquery.listTableData(info.tableId(), options); + } + + /** + * Starts a BigQuery Job to copy the current table to the provided destination table. Returns the + * started {@link Job} object. + * + * @param destinationDataset the user-defined id of the destination dataset + * @param destinationTable the user-defined id of the destination table + * @param options job options + * @throws BigQueryException upon failure + */ + Job copy(String destinationDataset, String destinationTable, BigQuery.JobOption... options) + throws BigQueryException { + return copy(TableId.of(destinationDataset, destinationTable), options); + } + + /** + * Starts a BigQuery Job to copy the current table to the provided destination table. Returns the + * started {@link Job} object. + * + * @param destinationTable the destination table of the copy job + * @param options job options + * @throws BigQueryException upon failure + */ + Job copy(TableId destinationTable, BigQuery.JobOption... options) throws BigQueryException { + JobInfo job = bigquery.create(CopyJobInfo.of(destinationTable, info.tableId()), options); + return new Job(bigquery, job); + } + + /** + * Starts a BigQuery Job to extract the current table to the provided destination URI. Returns the + * started {@link Job} object. + * + * @param format the format of the extracted data + * @param destinationUri the fully-qualified Google Cloud Storage URI (e.g. gs://bucket/path) + * where the extracted table should be written + * @param options job options + * @throws BigQueryException upon failure + */ + Job extract(String format, String destinationUri, BigQuery.JobOption... options) + throws BigQueryException { + return extract(format, ImmutableList.of(destinationUri), options); + } + + /** + * Starts a BigQuery Job to extract the current table to the provided destination URIs. Returns + * the started {@link Job} object. + * + * @param format the format of the exported data + * @param destinationUris the fully-qualified Google Cloud Storage URIs (e.g. gs://bucket/path) + * where the extracted table should be written + * @param options job options + * @throws BigQueryException upon failure + */ + Job extract(String format, List destinationUris, BigQuery.JobOption... options) + throws BigQueryException { + ExtractJobInfo job = ExtractJobInfo.builder(info.tableId(), destinationUris) + .format(format) + .build(); + return new Job(bigquery, bigquery.create(job, options)); + } + + /** + * Starts a BigQuery Job to load data into the current table from the provided source URI. Returns + * the started {@link Job} object. + * + * @param format the format of the data to load + * @param sourceUri the fully-qualified Google Cloud Storage URI (e.g. gs://bucket/path) from + * which to load the data + * @param options job options + * @throws BigQueryException upon failure + */ + Job load(FormatOptions format, String sourceUri, BigQuery.JobOption... options) + throws BigQueryException { + return load(format, ImmutableList.of(sourceUri), options); + } + + /** + * Starts a BigQuery Job to load data into the current table from the provided source URIs. + * Returns the started {@link Job} object. + * + * @param format the format of the exported data + * @param sourceUris the fully-qualified Google Cloud Storage URIs (e.g. gs://bucket/path) from + * which to load the data + * @param options job options + * @throws BigQueryException upon failure + */ + Job load(FormatOptions format, List sourceUris, BigQuery.JobOption... options) + throws BigQueryException { + LoadJobInfo job = LoadJobInfo.builder(info.tableId(), sourceUris) + .formatOptions(format) + .build(); + return new Job(bigquery, bigquery.create(job, options)); + } + + /** + * Returns the table's {@code BigQuery} object used to issue requests. + */ + public BigQuery bigquery() { + return bigquery; + } +} diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/DatasetTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/DatasetTest.java new file mode 100644 index 000000000000..6920b6812df3 --- /dev/null +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/DatasetTest.java @@ -0,0 +1,197 @@ +/* + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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.google.gcloud.bigquery; + +import static org.easymock.EasyMock.createStrictMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import com.google.common.collect.ImmutableList; +import com.google.gcloud.Page; +import com.google.gcloud.PageImpl; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.util.Iterator; + +public class DatasetTest { + + private static final DatasetId DATASET_ID = DatasetId.of("dataset"); + private static final DatasetInfo DATASET_INFO = DatasetInfo.builder(DATASET_ID).build(); + private static final Field FIELD = Field.of("FieldName", Field.Type.integer()); + private static final Iterable TABLE_INFO_RESULTS = ImmutableList.of( + TableInfo.builder(TableId.of("dataset", "table1"), Schema.of(FIELD)).build(), + ViewInfo.builder(TableId.of("dataset", "table2"), "QUERY").build(), + ExternalTableInfo.builder(TableId.of("dataset", "table2"), + ExternalDataConfiguration.of(ImmutableList.of("URI"), Schema.of(), FormatOptions.csv())) + .build()); + + private BigQuery bigquery; + private Dataset dataset; + + @Before + public void setUp() throws Exception { + bigquery = createStrictMock(BigQuery.class); + dataset = new Dataset(bigquery, DATASET_INFO); + } + + @After + public void tearDown() throws Exception { + verify(bigquery); + } + + @Test + public void testInfo() throws Exception { + assertEquals(DATASET_INFO, dataset.info()); + replay(bigquery); + } + + @Test + public void testExists_True() throws Exception { + BigQuery.DatasetOption[] expectedOptions = {BigQuery.DatasetOption.fields()}; + expect(bigquery.getDataset(DATASET_ID, expectedOptions)).andReturn(DATASET_INFO); + replay(bigquery); + assertTrue(dataset.exists()); + } + + @Test + public void testExists_False() throws Exception { + BigQuery.DatasetOption[] expectedOptions = {BigQuery.DatasetOption.fields()}; + expect(bigquery.getDataset(DATASET_ID, expectedOptions)).andReturn(null); + replay(bigquery); + assertFalse(dataset.exists()); + } + + @Test + public void testReload() throws Exception { + DatasetInfo updatedInfo = DATASET_INFO.toBuilder().description("Description").build(); + expect(bigquery.getDataset(DATASET_ID)).andReturn(updatedInfo); + replay(bigquery); + Dataset updatedDataset = dataset.reload(); + assertSame(bigquery, updatedDataset.bigquery()); + assertEquals(updatedInfo, updatedDataset.info()); + } + + @Test + public void testUpdate() throws Exception { + DatasetInfo updatedInfo = DATASET_INFO.toBuilder().description("Description").build(); + expect(bigquery.update(updatedInfo)).andReturn(updatedInfo); + replay(bigquery); + Dataset updatedDataset = dataset.update(updatedInfo); + assertSame(bigquery, dataset.bigquery()); + assertEquals(updatedInfo, updatedDataset.info()); + } + + @Test + public void testDelete() throws Exception { + expect(bigquery.delete(DATASET_INFO.datasetId())).andReturn(true); + replay(bigquery); + assertTrue(dataset.delete()); + } + + @Test + public void testList() throws Exception { + BigQueryOptions bigqueryOptions = createStrictMock(BigQueryOptions.class); + PageImpl tableInfoPage = new PageImpl<>(null, "c", TABLE_INFO_RESULTS); + expect(bigquery.listTables(DATASET_INFO.datasetId())).andReturn(tableInfoPage); + expect(bigquery.options()).andReturn(bigqueryOptions); + expect(bigqueryOptions.service()).andReturn(bigquery); + replay(bigquery, bigqueryOptions); + Page
tablePage = dataset.list(); + Iterator tableInfoIterator = tableInfoPage.values().iterator(); + Iterator
tableIterator = tablePage.values().iterator(); + while (tableInfoIterator.hasNext() && tableIterator.hasNext()) { + assertEquals(tableInfoIterator.next(), tableIterator.next().info()); + } + assertFalse(tableInfoIterator.hasNext()); + assertFalse(tableIterator.hasNext()); + assertEquals(tableInfoPage.nextPageCursor(), tablePage.nextPageCursor()); + verify(bigqueryOptions); + } + + @Test + public void testGet() throws Exception { + BaseTableInfo info = TableInfo.builder(TableId.of("dataset", "table1"), Schema.of()).build(); + expect(bigquery.getTable(TableId.of("dataset", "table1"))).andReturn(info); + replay(bigquery); + Table table = dataset.get("table1"); + assertNotNull(table); + assertEquals(info, table.info()); + } + + @Test + public void testGetNull() throws Exception { + expect(bigquery.getTable(TableId.of("dataset", "table1"))).andReturn(null); + replay(bigquery); + assertNull(dataset.get("table1")); + } + + @Test + public void testCreateTable() throws Exception { + TableInfo info = TableInfo.builder(TableId.of("dataset", "table1"), Schema.of(FIELD)).build(); + expect(bigquery.create(info)).andReturn(info); + replay(bigquery); + Table table = dataset.create("table1", Schema.of(FIELD)); + assertEquals(info, table.info()); + } + + @Test + public void testCreateView() throws Exception { + ViewInfo info = ViewInfo.builder(TableId.of("dataset", "table2"), "QUERY").build(); + expect(bigquery.create(info)).andReturn(info); + replay(bigquery); + Table table = dataset.create("table2", "QUERY"); + assertEquals(info, table.info()); + } + + @Test + public void testCreateExternalTable() throws Exception { + ExternalTableInfo info = ExternalTableInfo.builder(TableId.of("dataset", "table3"), + ExternalDataConfiguration.of(ImmutableList.of("URI"), Schema.of(), FormatOptions.csv())) + .build(); + expect(bigquery.create(info)).andReturn(info); + replay(bigquery); + Table table = dataset.create("table3", ExternalDataConfiguration.of( + ImmutableList.of("URI"), Schema.of(), FormatOptions.csv())); + assertEquals(info, table.info()); + } + + @Test + public void testLoad() throws Exception { + expect(bigquery.getDataset(DATASET_INFO.datasetId().dataset())).andReturn(DATASET_INFO); + replay(bigquery); + Dataset loadedDataset = Dataset.load(bigquery, DATASET_INFO.datasetId().dataset()); + assertNotNull(loadedDataset); + assertEquals(DATASET_INFO, loadedDataset.info()); + } + + @Test + public void testLoadNull() throws Exception { + expect(bigquery.getDataset(DATASET_INFO.datasetId().dataset())).andReturn(null); + replay(bigquery); + assertNull(Dataset.load(bigquery, DATASET_INFO.datasetId().dataset())); + } +} diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobTest.java new file mode 100644 index 000000000000..2073adb3dd80 --- /dev/null +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobTest.java @@ -0,0 +1,141 @@ +/* + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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.google.gcloud.bigquery; + +import static org.easymock.EasyMock.createStrictMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class JobTest { + + private static final JobId JOB_ID = JobId.of("dataset", "job"); + private static final TableId TABLE_ID1 = TableId.of("dataset", "table1"); + private static final TableId TABLE_ID2 = TableId.of("dataset", "table2"); + private static final JobInfo JOB_INFO = CopyJobInfo.of(JOB_ID, TABLE_ID1, TABLE_ID2); + + private BigQuery bigquery; + private Job job; + + @Before + public void setUp() throws Exception { + bigquery = createStrictMock(BigQuery.class); + job = new Job(bigquery, JOB_INFO); + } + + @After + public void tearDown() throws Exception { + verify(bigquery); + } + + @Test + public void testInfo() throws Exception { + assertEquals(JOB_INFO, job.info()); + replay(bigquery); + } + + @Test + public void testExists_True() throws Exception { + BigQuery.JobOption[] expectedOptions = {BigQuery.JobOption.fields()}; + expect(bigquery.getJob(JOB_INFO.jobId(), expectedOptions)).andReturn(JOB_INFO); + replay(bigquery); + assertTrue(job.exists()); + } + + @Test + public void testExists_False() throws Exception { + BigQuery.JobOption[] expectedOptions = {BigQuery.JobOption.fields()}; + expect(bigquery.getJob(JOB_INFO.jobId(), expectedOptions)).andReturn(null); + replay(bigquery); + assertFalse(job.exists()); + } + + @Test + public void testIsDone_True() throws Exception { + JobStatus status = createStrictMock(JobStatus.class); + expect(status.state()).andReturn(JobStatus.State.DONE); + BigQuery.JobOption[] expectedOptions = {BigQuery.JobOption.fields(BigQuery.JobField.STATUS)}; + expect(bigquery.getJob(JOB_INFO.jobId(), expectedOptions)) + .andReturn(JOB_INFO.toBuilder().status(status).build()); + replay(status, bigquery); + assertTrue(job.isDone()); + verify(status); + } + + @Test + public void testIsDone_False() throws Exception { + JobStatus status = createStrictMock(JobStatus.class); + expect(status.state()).andReturn(JobStatus.State.RUNNING); + BigQuery.JobOption[] expectedOptions = {BigQuery.JobOption.fields(BigQuery.JobField.STATUS)}; + expect(bigquery.getJob(JOB_INFO.jobId(), expectedOptions)) + .andReturn(JOB_INFO.toBuilder().status(status).build()); + replay(status, bigquery); + assertFalse(job.isDone()); + verify(status); + } + + @Test + public void testIsDone_NotExists() throws Exception { + BigQuery.JobOption[] expectedOptions = {BigQuery.JobOption.fields(BigQuery.JobField.STATUS)}; + expect(bigquery.getJob(JOB_INFO.jobId(), expectedOptions)).andReturn(null); + replay(bigquery); + assertFalse(job.isDone()); + } + + @Test + public void testReload() throws Exception { + JobInfo updatedInfo = JOB_INFO.toBuilder().etag("etag").build(); + expect(bigquery.getJob(JOB_INFO.jobId())).andReturn(updatedInfo); + replay(bigquery); + Job updatedJob = job.reload(); + assertSame(bigquery, updatedJob.bigquery()); + assertEquals(updatedInfo, updatedJob.info()); + } + + @Test + public void testCancel() throws Exception { + expect(bigquery.cancel(JOB_INFO.jobId())).andReturn(true); + replay(bigquery); + assertTrue(job.cancel()); + } + + @Test + public void testLoad() throws Exception { + expect(bigquery.getJob(JOB_INFO.jobId().job())).andReturn(JOB_INFO); + replay(bigquery); + Job loadedJob = Job.load(bigquery, JOB_INFO.jobId().job()); + assertNotNull(loadedJob); + assertEquals(JOB_INFO, loadedJob.info()); + } + + @Test + public void testLoadNull() throws Exception { + expect(bigquery.getJob(JOB_INFO.jobId().job())).andReturn(null); + replay(bigquery); + assertNull(Job.load(bigquery, JOB_INFO.jobId().job())); + } +} diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableTest.java new file mode 100644 index 000000000000..1520dbfcd580 --- /dev/null +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableTest.java @@ -0,0 +1,243 @@ +/* + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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.google.gcloud.bigquery; + +import static org.easymock.EasyMock.createStrictMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Iterators; +import com.google.gcloud.Page; +import com.google.gcloud.PageImpl; +import com.google.gcloud.bigquery.InsertAllRequest.RowToInsert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.util.Iterator; +import java.util.List; + +public class TableTest { + + private static final TableId TABLE_ID1 = TableId.of("dataset", "table1"); + private static final TableId TABLE_ID2 = TableId.of("dataset", "table2"); + private static final JobInfo COPY_JOB_INFO = CopyJobInfo.of(TABLE_ID2, TABLE_ID1); + private static final JobInfo LOAD_JOB_INFO = + LoadJobInfo.builder(TABLE_ID1, ImmutableList.of("URI")) + .formatOptions(FormatOptions.json()) + .build(); + private static final JobInfo EXTRACT_JOB_INFO = + ExtractJobInfo.builder(TABLE_ID1, ImmutableList.of("URI")) + .format("CSV") + .build(); + private static final Field FIELD = Field.of("FieldName", Field.Type.integer()); + private static final TableInfo TABLE_INFO = TableInfo.of(TABLE_ID1, Schema.of(FIELD)); + private static final List ROWS_TO_INSERT = ImmutableList.of( + RowToInsert.of("id1", ImmutableMap.of("key", "val1")), + RowToInsert.of("id2", ImmutableMap.of("key", "val2"))); + private static final InsertAllRequest INSERT_ALL_REQUEST = + InsertAllRequest.of(TABLE_ID1, ROWS_TO_INSERT); + private static final InsertAllRequest INSERT_ALL_REQUEST_COMPLETE = + InsertAllRequest.builder(TABLE_ID1, ROWS_TO_INSERT) + .skipInvalidRows(true) + .ignoreUnknownValues(true) + .build(); + private static final InsertAllResponse EMPTY_INSERT_ALL_RESPONSE = + new InsertAllResponse(ImmutableMap.>of()); + private static final FieldValue FIELD_VALUE1 = + new FieldValue(FieldValue.Attribute.PRIMITIVE, "val1"); + private static final FieldValue FIELD_VALUE2 = + new FieldValue(FieldValue.Attribute.PRIMITIVE, "val1"); + private static final Iterable> ROWS = ImmutableList.of( + (List) ImmutableList.of(FIELD_VALUE1), ImmutableList.of(FIELD_VALUE2)); + + private BigQuery bigquery; + private Table table; + + @Before + public void setUp() throws Exception { + bigquery = createStrictMock(BigQuery.class); + table = new Table(bigquery, TABLE_INFO); + } + + @After + public void tearDown() throws Exception { + verify(bigquery); + } + + @Test + public void testInfo() throws Exception { + assertEquals(TABLE_INFO, table.info()); + replay(bigquery); + } + + @Test + public void testExists_True() throws Exception { + BigQuery.TableOption[] expectedOptions = {BigQuery.TableOption.fields()}; + expect(bigquery.getTable(TABLE_INFO.tableId(), expectedOptions)).andReturn(TABLE_INFO); + replay(bigquery); + assertTrue(table.exists()); + } + + @Test + public void testExists_False() throws Exception { + BigQuery.TableOption[] expectedOptions = {BigQuery.TableOption.fields()}; + expect(bigquery.getTable(TABLE_INFO.tableId(), expectedOptions)).andReturn(null); + replay(bigquery); + assertFalse(table.exists()); + } + + @Test + public void testReload() throws Exception { + TableInfo updatedInfo = TABLE_INFO.toBuilder().description("Description").build(); + expect(bigquery.getTable(TABLE_INFO.tableId())).andReturn(updatedInfo); + replay(bigquery); + Table updatedTable = table.reload(); + assertSame(bigquery, updatedTable.bigquery()); + assertEquals(updatedInfo, updatedTable.info()); + } + + @Test + public void testDelete() throws Exception { + expect(bigquery.delete(TABLE_INFO.tableId())).andReturn(true); + replay(bigquery); + assertTrue(table.delete()); + } + + @Test + public void testInsert() throws Exception { + expect(bigquery.insertAll(INSERT_ALL_REQUEST)).andReturn(EMPTY_INSERT_ALL_RESPONSE); + replay(bigquery); + InsertAllResponse response = table.insert(ROWS_TO_INSERT); + assertSame(EMPTY_INSERT_ALL_RESPONSE, response); + } + + @Test + public void testInsertComplete() throws Exception { + expect(bigquery.insertAll(INSERT_ALL_REQUEST_COMPLETE)).andReturn(EMPTY_INSERT_ALL_RESPONSE); + replay(bigquery); + InsertAllResponse response = table.insert(ROWS_TO_INSERT, true, true); + assertSame(EMPTY_INSERT_ALL_RESPONSE, response); + } + + @Test + public void testList() throws Exception { + PageImpl> tableDataPage = new PageImpl<>(null, "c", ROWS); + expect(bigquery.listTableData(TABLE_ID1)).andReturn(tableDataPage); + replay(bigquery); + Page> dataPage = table.list(); + Iterator> tableDataIterator = tableDataPage.values().iterator(); + Iterator> dataIterator = dataPage.values().iterator(); + assertTrue(Iterators.elementsEqual(tableDataIterator, dataIterator)); + } + + @Test + public void testCopyFromString() throws Exception { + expect(bigquery.create(COPY_JOB_INFO)).andReturn(COPY_JOB_INFO); + replay(bigquery); + Job job = table.copy(TABLE_ID2.dataset(), TABLE_ID2.table()); + assertSame(bigquery, job.bigquery()); + assertEquals(COPY_JOB_INFO, job.info()); + } + + @Test + public void testCopyFromId() throws Exception { + expect(bigquery.create(COPY_JOB_INFO)).andReturn(COPY_JOB_INFO); + replay(bigquery); + Job job = table.copy(TABLE_ID2); + assertSame(bigquery, job.bigquery()); + assertEquals(COPY_JOB_INFO, job.info()); + } + + @Test + public void testLoadDataUri() throws Exception { + expect(bigquery.create(LOAD_JOB_INFO)).andReturn(LOAD_JOB_INFO); + replay(bigquery); + Job job = table.load(FormatOptions.json(), "URI"); + assertSame(bigquery, job.bigquery()); + assertEquals(LOAD_JOB_INFO, job.info()); + } + + @Test + public void testLoadDataUris() throws Exception { + expect(bigquery.create(LOAD_JOB_INFO)).andReturn(LOAD_JOB_INFO); + replay(bigquery); + Job job = table.load(FormatOptions.json(), ImmutableList.of("URI")); + assertSame(bigquery, job.bigquery()); + assertEquals(LOAD_JOB_INFO, job.info()); + } + + @Test + public void testExtractDataUri() throws Exception { + expect(bigquery.create(EXTRACT_JOB_INFO)).andReturn(EXTRACT_JOB_INFO); + replay(bigquery); + Job job = table.extract("CSV", "URI"); + assertSame(bigquery, job.bigquery()); + assertEquals(EXTRACT_JOB_INFO, job.info()); + } + + @Test + public void testExtractDataUris() throws Exception { + expect(bigquery.create(EXTRACT_JOB_INFO)).andReturn(EXTRACT_JOB_INFO); + replay(bigquery); + Job job = table.extract("CSV", ImmutableList.of("URI")); + assertSame(bigquery, job.bigquery()); + assertEquals(EXTRACT_JOB_INFO, job.info()); + } + + @Test + public void testLoadFromId() throws Exception { + expect(bigquery.getTable(TABLE_INFO.tableId())).andReturn(TABLE_INFO); + replay(bigquery); + Table loadedTable = Table.load(bigquery, TABLE_INFO.tableId()); + assertNotNull(loadedTable); + assertEquals(TABLE_INFO, loadedTable.info()); + } + + @Test + public void testLoadFromStrings() throws Exception { + expect(bigquery.getTable(TABLE_INFO.tableId())).andReturn(TABLE_INFO); + replay(bigquery); + Table loadedTable = Table.load(bigquery, TABLE_ID1.dataset(), TABLE_ID1.table()); + assertNotNull(loadedTable); + assertEquals(TABLE_INFO, loadedTable.info()); + } + + @Test + public void testLoadFromIdNull() throws Exception { + expect(bigquery.getTable(TABLE_INFO.tableId())).andReturn(null); + replay(bigquery); + assertNull(Table.load(bigquery, TABLE_INFO.tableId())); + } + + @Test + public void testLoadFromStringsNull() throws Exception { + expect(bigquery.getTable(TABLE_INFO.tableId())).andReturn(null); + replay(bigquery); + assertNull(Table.load(bigquery, TABLE_ID1.dataset(), TABLE_ID1.table())); + } +} From d75f1f458eb983ddf756a74f2db1d59b8575f951 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Mon, 4 Jan 2016 19:28:02 +0100 Subject: [PATCH 2/4] Minor fixes to bigquery functional classes - Remove periods from javadoc return paragraphs - Add options to load methods - Implement reload using load - Document that reload can return null - Add code snippet to Job.isDone - Better unit tests --- .../com/google/gcloud/bigquery/Dataset.java | 26 +++++++------ .../java/com/google/gcloud/bigquery/Job.java | 33 ++++++++++------ .../com/google/gcloud/bigquery/Table.java | 27 +++++++------ .../google/gcloud/bigquery/DatasetTest.java | 31 ++++++++++++++- .../com/google/gcloud/bigquery/JobTest.java | 30 +++++++++++++- .../com/google/gcloud/bigquery/TableTest.java | 39 +++++++++++++++++++ 6 files changed, 148 insertions(+), 38 deletions(-) diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Dataset.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Dataset.java index 7c3358fedb99..dee41fb4b0ea 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Dataset.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Dataset.java @@ -127,11 +127,12 @@ public Dataset(BigQuery bigquery, DatasetInfo info) { * * @param bigquery the BigQuery service used for issuing requests * @param dataset dataset's user-defined id - * @return the {@code Dataset} object or {@code null} if not found. + * @param options dataset options + * @return the {@code Dataset} object or {@code null} if not found * @throws BigQueryException upon failure */ - public static Dataset load(BigQuery bigquery, String dataset) { - DatasetInfo info = bigquery.getDataset(dataset); + public static Dataset load(BigQuery bigquery, String dataset, BigQuery.DatasetOption... options) { + DatasetInfo info = bigquery.getDataset(dataset, options); return info != null ? new Dataset(bigquery, info) : null; } @@ -145,7 +146,7 @@ public DatasetInfo info() { /** * Checks if this dataset exists. * - * @return {@code true} if this dataset exists, {@code false} otherwise. + * @return {@code true} if this dataset exists, {@code false} otherwise * @throws BigQueryException upon failure */ public boolean exists() { @@ -153,14 +154,15 @@ public boolean exists() { } /** - * Fetches current dataset's latest information. + * Fetches current dataset's latest information. Returns {@code null} if the dataset does not + * exist. * * @param options dataset options - * @return a {@code Dataset} object with latest information. + * @return a {@code Dataset} object with latest information or {@code null} if not found * @throws BigQueryException upon failure */ public Dataset reload(BigQuery.DatasetOption... options) { - return new Dataset(bigquery, bigquery.getDataset(info.datasetId(), options)); + return Dataset.load(bigquery, info.datasetId().dataset(), options); } /** @@ -170,7 +172,7 @@ public Dataset reload(BigQuery.DatasetOption... options) { * @param datasetInfo new dataset's information. User-defined id must match the one of the current * dataset * @param options dataset options - * @return a {@code Dataset} object with updated information. + * @return a {@code Dataset} object with updated information * @throws BigQueryException upon failure */ public Dataset update(DatasetInfo datasetInfo, BigQuery.DatasetOption... options) { @@ -221,7 +223,7 @@ public Table get(String table, BigQuery.TableOption... options) { * @param table the table's user-defined id * @param schema the table's schema * @param options options for table creation - * @return a {@code Table} object for the created table. + * @return a {@code Table} object for the created table * @throws BigQueryException upon failure */ public Table create(String table, Schema schema, BigQuery.TableOption... options) { @@ -236,7 +238,7 @@ public Table create(String table, Schema schema, BigQuery.TableOption... options * @param query the query used to generate the table * @param functions user-defined functions that can be used by the query * @param options options for table creation - * @return a {@code Table} object for the created table. + * @return a {@code Table} object for the created table * @throws BigQueryException upon failure */ public Table create(String table, String query, List functions, @@ -252,7 +254,7 @@ public Table create(String table, String query, List functi * @param table the table's user-defined id * @param query the query used to generate the table * @param options options for table creation - * @return a {@code Table} object for the created table. + * @return a {@code Table} object for the created table * @throws BigQueryException upon failure */ public Table create(String table, String query, BigQuery.TableOption... options) { @@ -266,7 +268,7 @@ public Table create(String table, String query, BigQuery.TableOption... options) * @param table the table's user-defined id * @param configuration data format, location and other properties of an external table * @param options options for table creation - * @return a {@code Table} object for the created table. + * @return a {@code Table} object for the created table * @throws BigQueryException upon failure */ public Table create(String table, ExternalDataConfiguration configuration, diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Job.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Job.java index 06e9b1ced569..e6de2a9d7a4a 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Job.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Job.java @@ -43,16 +43,17 @@ public Job(BigQuery bigquery, JobInfo info) { } /** - * Creates a {@code Job} object for the provided job's user-defined id. Performs an RPC call - * to get the latest job information. + * Creates a {@code Job} object for the provided job's user-defined id. Performs an RPC call to + * get the latest job information. * * @param bigquery the BigQuery service used for issuing requests * @param job job's id, either user-defined or picked by the BigQuery service - * @return the {@code Job} object or {@code null} if not found. + * @param options job options + * @return the {@code Job} object or {@code null} if not found * @throws BigQueryException upon failure */ - public static Job load(BigQuery bigquery, String job) { - JobInfo info = bigquery.getJob(job); + public static Job load(BigQuery bigquery, String job, BigQuery.JobOption... options) { + JobInfo info = bigquery.getJob(job, options); return info != null ? new Job(bigquery, info) : null; } @@ -66,7 +67,7 @@ public JobInfo info() { /** * Checks if this job exists. * - * @return {@code true} if this job exists, {@code false} otherwise. + * @return {@code true} if this job exists, {@code false} otherwise * @throws BigQueryException upon failure */ public boolean exists() { @@ -74,10 +75,18 @@ public boolean exists() { } /** - * Checks if this job has completed its execution, either failing or succeeding. + * Checks if this job has completed its execution, either failing or succeeding. If the job does + * not exist this method returns {@code false}. To correctly wait for job's completion check that + * the job exists first, using {@link #exists()}: + *
 {@code
+   * if (job.exists()) {
+   *   while(!job.isDone()) {
+   *     Thread.sleep(1000L);
+   *   }
+   * }}
* * @return {@code true} if this job is in {@link JobStatus.State#DONE} state, {@code false} if the - * state is not {@link JobStatus.State#DONE} or the job does not exist. + * state is not {@link JobStatus.State#DONE} or the job does not exist * @throws BigQueryException upon failure */ public boolean isDone() { @@ -87,21 +96,21 @@ public boolean isDone() { } /** - * Fetches current job's latest information. + * Fetches current job's latest information. Returns {@code null} if the job does not exist. * * @param options job options - * @return a {@code Job} object with latest information. + * @return a {@code Job} object with latest information or {@code null} if not found * @throws BigQueryException upon failure */ public Job reload(BigQuery.JobOption... options) { - return new Job(bigquery, bigquery.getJob(info.jobId(), options)); + return Job.load(bigquery, info.jobId().job(), options); } /** * Sends a job cancel request. * * @return {@code true} if cancel request was sent successfully, {@code false} if job was not - * found. + * found * @throws BigQueryException upon failure */ public boolean cancel() { diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Table.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Table.java index 33cbe602033a..fec3e0c03a90 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Table.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Table.java @@ -57,11 +57,13 @@ public Table(BigQuery bigquery, BaseTableInfo info) { * @param bigquery the BigQuery service used for issuing requests * @param dataset the dataset's user-defined id * @param table the table's user-defined id - * @return the {@code Table} object or {@code null} if not found. + * @param options table options + * @return the {@code Table} object or {@code null} if not found * @throws BigQueryException upon failure */ - public static Table load(BigQuery bigquery, String dataset, String table) { - return load(bigquery, TableId.of(dataset, table)); + public static Table load(BigQuery bigquery, String dataset, String table, + BigQuery.TableOption... options) { + return load(bigquery, TableId.of(dataset, table), options); } /** @@ -70,11 +72,12 @@ public static Table load(BigQuery bigquery, String dataset, String table) { * * @param bigquery the BigQuery service used for issuing requests * @param table the table's identity - * @return the {@code Table} object or {@code null} if not found. + * @param options table options + * @return the {@code Table} object or {@code null} if not found * @throws BigQueryException upon failure */ - public static Table load(BigQuery bigquery, TableId table) { - BaseTableInfo info = bigquery.getTable(table); + public static Table load(BigQuery bigquery, TableId table, BigQuery.TableOption... options) { + BaseTableInfo info = bigquery.getTable(table, options); return info != null ? new Table(bigquery, info) : null; } @@ -88,7 +91,7 @@ public BaseTableInfo info() { /** * Checks if this table exists. * - * @return {@code true} if this table exists, {@code false} otherwise. + * @return {@code true} if this table exists, {@code false} otherwise * @throws BigQueryException upon failure */ public boolean exists() { @@ -96,14 +99,14 @@ public boolean exists() { } /** - * Fetches current table's latest information. + * Fetches current table's latest information. Returns {@code null} if the table does not exist. * * @param options table options - * @return a {@code Table} object with latest information. + * @return a {@code Table} object with latest information or {@code null} if not found * @throws BigQueryException upon failure */ public Table reload(BigQuery.TableOption... options) { - return new Table(bigquery, bigquery.getTable(info.tableId(), options)); + return Table.load(bigquery, info.tableId(), options); } /** @@ -113,7 +116,7 @@ public Table reload(BigQuery.TableOption... options) { * @param tableInfo new table's information. Dataset's and table's user-defined ids must match the * ones of the current table * @param options dataset options - * @return a {@code Table} object with updated information. + * @return a {@code Table} object with updated information * @throws BigQueryException upon failure */ public Table update(BaseTableInfo tableInfo, BigQuery.TableOption... options) { @@ -127,7 +130,7 @@ public Table update(BaseTableInfo tableInfo, BigQuery.TableOption... options) { /** * Deletes this table. * - * @return {@code true} if table was deleted, {@code false} if it was not found. + * @return {@code true} if table was deleted, {@code false} if it was not found * @throws BigQueryException upon failure */ public boolean delete() { diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/DatasetTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/DatasetTest.java index 6920b6812df3..7395d4d18d69 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/DatasetTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/DatasetTest.java @@ -88,13 +88,31 @@ public void testExists_False() throws Exception { @Test public void testReload() throws Exception { DatasetInfo updatedInfo = DATASET_INFO.toBuilder().description("Description").build(); - expect(bigquery.getDataset(DATASET_ID)).andReturn(updatedInfo); + expect(bigquery.getDataset(DATASET_ID.dataset())).andReturn(updatedInfo); replay(bigquery); Dataset updatedDataset = dataset.reload(); assertSame(bigquery, updatedDataset.bigquery()); assertEquals(updatedInfo, updatedDataset.info()); } + @Test + public void testReloadNull() throws Exception { + expect(bigquery.getDataset(DATASET_ID.dataset())).andReturn(null); + replay(bigquery); + assertNull(dataset.reload()); + } + + @Test + public void testReloadWithOptions() throws Exception { + DatasetInfo updatedInfo = DATASET_INFO.toBuilder().description("Description").build(); + expect(bigquery.getDataset(DATASET_ID.dataset(), BigQuery.DatasetOption.fields())) + .andReturn(updatedInfo); + replay(bigquery); + Dataset updatedDataset = dataset.reload(BigQuery.DatasetOption.fields()); + assertSame(bigquery, updatedDataset.bigquery()); + assertEquals(updatedInfo, updatedDataset.info()); + } + @Test public void testUpdate() throws Exception { DatasetInfo updatedInfo = DATASET_INFO.toBuilder().description("Description").build(); @@ -194,4 +212,15 @@ public void testLoadNull() throws Exception { replay(bigquery); assertNull(Dataset.load(bigquery, DATASET_INFO.datasetId().dataset())); } + + @Test + public void testLoadWithOptions() throws Exception { + expect(bigquery.getDataset(DATASET_INFO.datasetId().dataset(), BigQuery.DatasetOption.fields())) + .andReturn(DATASET_INFO); + replay(bigquery); + Dataset loadedDataset = Dataset.load(bigquery, DATASET_INFO.datasetId().dataset(), + BigQuery.DatasetOption.fields()); + assertNotNull(loadedDataset); + assertEquals(DATASET_INFO, loadedDataset.info()); + } } diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobTest.java index 2073adb3dd80..99b3e80a0206 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobTest.java @@ -109,13 +109,31 @@ public void testIsDone_NotExists() throws Exception { @Test public void testReload() throws Exception { JobInfo updatedInfo = JOB_INFO.toBuilder().etag("etag").build(); - expect(bigquery.getJob(JOB_INFO.jobId())).andReturn(updatedInfo); + expect(bigquery.getJob(JOB_INFO.jobId().job())).andReturn(updatedInfo); replay(bigquery); Job updatedJob = job.reload(); assertSame(bigquery, updatedJob.bigquery()); assertEquals(updatedInfo, updatedJob.info()); } + @Test + public void testReloadNull() throws Exception { + expect(bigquery.getJob(JOB_INFO.jobId().job())).andReturn(null); + replay(bigquery); + assertNull(job.reload()); + } + + @Test + public void testReloadWithOptions() throws Exception { + JobInfo updatedInfo = JOB_INFO.toBuilder().etag("etag").build(); + expect(bigquery.getJob(JOB_INFO.jobId().job(), BigQuery.JobOption.fields())) + .andReturn(updatedInfo); + replay(bigquery); + Job updatedJob = job.reload(BigQuery.JobOption.fields()); + assertSame(bigquery, updatedJob.bigquery()); + assertEquals(updatedInfo, updatedJob.info()); + } + @Test public void testCancel() throws Exception { expect(bigquery.cancel(JOB_INFO.jobId())).andReturn(true); @@ -138,4 +156,14 @@ public void testLoadNull() throws Exception { replay(bigquery); assertNull(Job.load(bigquery, JOB_INFO.jobId().job())); } + + @Test + public void testLoadWithOptions() throws Exception { + expect(bigquery.getJob(JOB_INFO.jobId().job(), BigQuery.JobOption.fields())) + .andReturn(JOB_INFO); + replay(bigquery); + Job loadedJob = Job.load(bigquery, JOB_INFO.jobId().job(), BigQuery.JobOption.fields()); + assertNotNull(loadedJob); + assertEquals(JOB_INFO, loadedJob.info()); + } } diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableTest.java index 1520dbfcd580..fb022cb13b40 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableTest.java @@ -121,6 +121,24 @@ public void testReload() throws Exception { assertEquals(updatedInfo, updatedTable.info()); } + @Test + public void testReloadNull() throws Exception { + expect(bigquery.getTable(TABLE_INFO.tableId())).andReturn(null); + replay(bigquery); + assertNull(table.reload()); + } + + @Test + public void testReloadWithOptions() throws Exception { + TableInfo updatedInfo = TABLE_INFO.toBuilder().description("Description").build(); + expect(bigquery.getTable(TABLE_INFO.tableId(), BigQuery.TableOption.fields())) + .andReturn(updatedInfo); + replay(bigquery); + Table updatedTable = table.reload(BigQuery.TableOption.fields()); + assertSame(bigquery, updatedTable.bigquery()); + assertEquals(updatedInfo, updatedTable.info()); + } + @Test public void testDelete() throws Exception { expect(bigquery.delete(TABLE_INFO.tableId())).andReturn(true); @@ -240,4 +258,25 @@ public void testLoadFromStringsNull() throws Exception { replay(bigquery); assertNull(Table.load(bigquery, TABLE_ID1.dataset(), TABLE_ID1.table())); } + + @Test + public void testLoadFromIdWithOptions() throws Exception { + expect(bigquery.getTable(TABLE_INFO.tableId(), BigQuery.TableOption.fields())) + .andReturn(TABLE_INFO); + replay(bigquery); + Table loadedTable = Table.load(bigquery, TABLE_INFO.tableId(), BigQuery.TableOption.fields()); + assertNotNull(loadedTable); + assertEquals(TABLE_INFO, loadedTable.info()); + } + + @Test + public void testLoadFromStringsWithOptions() throws Exception { + expect(bigquery.getTable(TABLE_INFO.tableId(), BigQuery.TableOption.fields())) + .andReturn(TABLE_INFO); + replay(bigquery); + Table loadedTable = + Table.load(bigquery, TABLE_ID1.dataset(), TABLE_ID1.table(), BigQuery.TableOption.fields()); + assertNotNull(loadedTable); + assertEquals(TABLE_INFO, loadedTable.info()); + } } From dce12315ed472414cf63dc2fa2418550610c2fd1 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Mon, 4 Jan 2016 19:29:58 +0100 Subject: [PATCH 3/4] Minor fixes to storage functional classes - Remove periods from javadoc return paragraphs - Add options to load methods - Implement reload using load - Document that reload can return null - Better unit tests --- .../java/com/google/gcloud/storage/Blob.java | 31 +++++----- .../com/google/gcloud/storage/Bucket.java | 19 +++--- .../com/google/gcloud/storage/BlobTest.java | 59 ++++++++++++++++++- .../com/google/gcloud/storage/BucketTest.java | 39 +++++++++++- 4 files changed, 121 insertions(+), 27 deletions(-) diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java index c39a0aa73871..b85cbba7d869 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java @@ -156,29 +156,32 @@ public Blob(Storage storage, BlobInfo info) { /** * Creates a {@code Blob} object for the provided bucket and blob names. Performs an RPC call to - * get the latest blob information. + * get the latest blob information. Returns {@code null} if the blob does not exist. * * @param storage the storage service used for issuing requests * @param bucket bucket's name + * @param options blob get options * @param blob blob's name - * @return the {@code Blob} object or {@code null} if not found. + * @return the {@code Blob} object or {@code null} if not found * @throws StorageException upon failure */ - public static Blob load(Storage storage, String bucket, String blob) { - return load(storage, BlobId.of(bucket, blob)); + public static Blob load(Storage storage, String bucket, String blob, + Storage.BlobGetOption... options) { + return load(storage, BlobId.of(bucket, blob), options); } /** * Creates a {@code Blob} object for the provided {@code blobId}. Performs an RPC call to get the - * latest blob information. + * latest blob information. Returns {@code null} if the blob does not exist. * * @param storage the storage service used for issuing requests * @param blobId blob's identifier - * @return the {@code Blob} object or {@code null} if not found. + * @param options blob get options + * @return the {@code Blob} object or {@code null} if not found * @throws StorageException upon failure */ - public static Blob load(Storage storage, BlobId blobId) { - BlobInfo info = storage.get(blobId); + public static Blob load(Storage storage, BlobId blobId, Storage.BlobGetOption... options) { + BlobInfo info = storage.get(blobId, options); return info != null ? new Blob(storage, info) : null; } @@ -221,14 +224,14 @@ public byte[] content(Storage.BlobSourceOption... options) { } /** - * Fetches current blob's latest information. + * Fetches current blob's latest information. Returns {@code null} if the blob does not exist. * * @param options blob read options - * @return a {@code Blob} object with latest information + * @return a {@code Blob} object with latest information or {@code null} if not found * @throws StorageException upon failure */ public Blob reload(BlobSourceOption... options) { - return new Blob(storage, storage.get(info.blobId(), toGetOptions(info, options))); + return Blob.load(storage, info.blobId(), toGetOptions(info, options)); } /** @@ -368,7 +371,7 @@ public Storage storage() { * @param storage the storage service used to issue the request * @param blobs the blobs to get * @return an immutable list of {@code Blob} objects. If a blob does not exist or access to it has - * been denied the corresponding item in the list is {@code null}. + * been denied the corresponding item in the list is {@code null} * @throws StorageException upon failure */ public static List get(final Storage storage, BlobId... blobs) { @@ -397,7 +400,7 @@ public Blob apply(BlobInfo blobInfo) { * @param storage the storage service used to issue the request * @param infos the blobs to update * @return an immutable list of {@code Blob} objects. If a blob does not exist or access to it has - * been denied the corresponding item in the list is {@code null}. + * been denied the corresponding item in the list is {@code null} * @throws StorageException upon failure */ public static List update(final Storage storage, BlobInfo... infos) { @@ -422,7 +425,7 @@ public Blob apply(BlobInfo blobInfo) { * @param blobs the blobs to delete * @return an immutable list of booleans. If a blob has been deleted the corresponding item in the * list is {@code true}. If a blob was not found, deletion failed or access to the resource - * was denied the corresponding item is {@code false}. + * was denied the corresponding item is {@code false} * @throws StorageException upon failure */ public static List delete(Storage storage, BlobId... blobs) { diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java index 8a90de143100..ca24d1442103 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java @@ -210,11 +210,12 @@ public Bucket(Storage storage, BucketInfo info) { * * @param storage the storage service used for issuing requests * @param bucket bucket's name - * @return the {@code Bucket} object or {@code null} if not found. + * @param options blob get options + * @return the {@code Bucket} object or {@code null} if not found * @throws StorageException upon failure */ - public static Bucket load(Storage storage, String bucket) { - BucketInfo info = storage.get(bucket); + public static Bucket load(Storage storage, String bucket, Storage.BucketGetOption... options) { + BucketInfo info = storage.get(bucket, options); return info != null ? new Bucket(storage, info) : null; } @@ -239,14 +240,14 @@ public boolean exists(BucketSourceOption... options) { } /** - * Fetches current bucket's latest information. + * Fetches current bucket's latest information. Returns {@code null} if the bucket does not exist. * * @param options bucket read options - * @return a {@code Bucket} object with latest information + * @return a {@code Bucket} object with latest information or {@code null} if not found * @throws StorageException upon failure */ public Bucket reload(BucketSourceOption... options) { - return new Bucket(storage, storage.get(info.name(), toGetOptions(info, options))); + return Bucket.load(storage, info.name(), toGetOptions(info, options)); } /** @@ -307,7 +308,7 @@ public Blob get(String blob, BlobGetOption... options) { * @param blobName1 first blob to get * @param blobName2 second blob to get * @param blobNames other blobs to get - * @return an immutable list of {@code Blob} objects. + * @return an immutable list of {@code Blob} objects * @throws StorageException upon failure */ public List get(String blobName1, String blobName2, String... blobNames) { @@ -337,7 +338,7 @@ public List get(String blobName1, String blobName2, String... blobNames) { * @param contentType the blob content type. If {@code null} then * {@value com.google.gcloud.storage.Storage#DEFAULT_CONTENT_TYPE} is used. * @param options options for blob creation - * @return a complete blob information. + * @return a complete blob information * @throws StorageException upon failure */ public Blob create(String blob, byte[] content, String contentType, BlobTargetOption... options) { @@ -356,7 +357,7 @@ public Blob create(String blob, byte[] content, String contentType, BlobTargetOp * @param contentType the blob content type. If {@code null} then * {@value com.google.gcloud.storage.Storage#DEFAULT_CONTENT_TYPE} is used. * @param options options for blob creation - * @return a complete blob information. + * @return a complete blob information * @throws StorageException upon failure */ public Blob create(String blob, InputStream content, String contentType, diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobTest.java index 4f5eb4022744..45cf79e01278 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobTest.java @@ -45,7 +45,7 @@ public class BlobTest { - private static final BlobInfo BLOB_INFO = BlobInfo.builder("b", "n").build(); + private static final BlobInfo BLOB_INFO = BlobInfo.builder("b", "n").metageneration(42L).build(); private static final BlobId[] BLOB_ID_ARRAY = {BlobId.of("b1", "n1"), BlobId.of("b2", "n2"), BlobId.of("b3", "n3")}; private static final BlobInfo[] BLOB_INFO_ARRAY = {BlobInfo.builder("b1", "n1").build(), @@ -105,6 +105,24 @@ public void testReload() throws Exception { assertEquals(updatedInfo, updatedBlob.info()); } + @Test + public void testReloadNull() throws Exception { + expect(storage.get(BLOB_INFO.blobId(), new Storage.BlobGetOption[0])).andReturn(null); + replay(storage); + assertNull(blob.reload()); + } + + @Test + public void testReloadWithOptions() throws Exception { + BlobInfo updatedInfo = BLOB_INFO.toBuilder().cacheControl("c").build(); + Storage.BlobGetOption[] options = {Storage.BlobGetOption.metagenerationMatch(42L)}; + expect(storage.get(BLOB_INFO.blobId(), options)).andReturn(updatedInfo); + replay(storage); + Blob updatedBlob = blob.reload(Blob.BlobSourceOption.metagenerationMatch()); + assertSame(storage, updatedBlob.storage()); + assertEquals(updatedInfo, updatedBlob.info()); + } + @Test public void testUpdate() throws Exception { BlobInfo updatedInfo = BLOB_INFO.toBuilder().cacheControl("c").build(); @@ -285,7 +303,7 @@ public void testDeleteSome() throws Exception { @Test public void testLoadFromString() throws Exception { - expect(storage.get(BLOB_INFO.blobId())).andReturn(BLOB_INFO); + expect(storage.get(BLOB_INFO.blobId(), new Storage.BlobGetOption[0])).andReturn(BLOB_INFO); replay(storage); Blob loadedBlob = Blob.load(storage, BLOB_INFO.bucket(), BLOB_INFO.name()); assertEquals(BLOB_INFO, loadedBlob.info()); @@ -293,10 +311,45 @@ public void testLoadFromString() throws Exception { @Test public void testLoadFromId() throws Exception { - expect(storage.get(BLOB_INFO.blobId())).andReturn(BLOB_INFO); + expect(storage.get(BLOB_INFO.blobId(), new Storage.BlobGetOption[0])).andReturn(BLOB_INFO); replay(storage); Blob loadedBlob = Blob.load(storage, BLOB_INFO.blobId()); assertNotNull(loadedBlob); assertEquals(BLOB_INFO, loadedBlob.info()); } + + @Test + public void testLoadFromStringNull() throws Exception { + expect(storage.get(BLOB_INFO.blobId(), new Storage.BlobGetOption[0])).andReturn(null); + replay(storage); + assertNull(Blob.load(storage, BLOB_INFO.bucket(), BLOB_INFO.name())); + } + + @Test + public void testLoadFromIdNull() throws Exception { + expect(storage.get(BLOB_INFO.blobId(), new Storage.BlobGetOption[0])).andReturn(null); + replay(storage); + assertNull(Blob.load(storage, BLOB_INFO.blobId())); + } + + @Test + public void testLoadFromStringWithOptions() throws Exception { + expect(storage.get(BLOB_INFO.blobId(), Storage.BlobGetOption.generationMatch(42L))) + .andReturn(BLOB_INFO); + replay(storage); + Blob loadedBlob = Blob.load(storage, BLOB_INFO.bucket(), BLOB_INFO.name(), + Storage.BlobGetOption.generationMatch(42L)); + assertEquals(BLOB_INFO, loadedBlob.info()); + } + + @Test + public void testLoadFromIdWithOptions() throws Exception { + expect(storage.get(BLOB_INFO.blobId(), Storage.BlobGetOption.generationMatch(42L))) + .andReturn(BLOB_INFO); + replay(storage); + Blob loadedBlob = + Blob.load(storage, BLOB_INFO.blobId(), Storage.BlobGetOption.generationMatch(42L)); + assertNotNull(loadedBlob); + assertEquals(BLOB_INFO, loadedBlob.info()); + } } diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BucketTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BucketTest.java index 81e7a68b2465..f1644bd8ea37 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BucketTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BucketTest.java @@ -24,6 +24,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; @@ -47,7 +48,7 @@ public class BucketTest { - private static final BucketInfo BUCKET_INFO = BucketInfo.of("b"); + private static final BucketInfo BUCKET_INFO = BucketInfo.builder("b").metageneration(42L).build(); private static final Iterable BLOB_INFO_RESULTS = ImmutableList.of( BlobInfo.builder("b", "n1").build(), BlobInfo.builder("b", "n2").build(), @@ -100,6 +101,24 @@ public void testReload() throws Exception { assertEquals(updatedInfo, updatedBucket.info()); } + @Test + public void testReloadNull() throws Exception { + expect(storage.get(BUCKET_INFO.name())).andReturn(null); + replay(storage); + assertNull(bucket.reload()); + } + + @Test + public void testReloadWithOptions() throws Exception { + BucketInfo updatedInfo = BUCKET_INFO.toBuilder().notFoundPage("p").build(); + expect(storage.get(updatedInfo.name(), Storage.BucketGetOption.metagenerationMatch(42L))) + .andReturn(updatedInfo); + replay(storage); + Bucket updatedBucket = bucket.reload(Bucket.BucketSourceOption.metagenerationMatch()); + assertSame(storage, updatedBucket.storage()); + assertEquals(updatedInfo, updatedBucket.info()); + } + @Test public void testUpdate() throws Exception { BucketInfo updatedInfo = BUCKET_INFO.toBuilder().notFoundPage("p").build(); @@ -223,4 +242,22 @@ public void testLoad() throws Exception { assertNotNull(loadedBucket); assertEquals(BUCKET_INFO, loadedBucket.info()); } + + @Test + public void testLoadNull() throws Exception { + expect(storage.get(BUCKET_INFO.name())).andReturn(null); + replay(storage); + assertNull(Bucket.load(storage, BUCKET_INFO.name())); + } + + @Test + public void testLoadWithOptions() throws Exception { + expect(storage.get(BUCKET_INFO.name(), Storage.BucketGetOption.fields())) + .andReturn(BUCKET_INFO); + replay(storage); + Bucket loadedBucket = + Bucket.load(storage, BUCKET_INFO.name(), Storage.BucketGetOption.fields()); + assertNotNull(loadedBucket); + assertEquals(BUCKET_INFO, loadedBucket.info()); + } } From d58930eb7bbff659bed22f3019b16b848130ccfc Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Tue, 5 Jan 2016 10:57:08 +0100 Subject: [PATCH 4/4] Add better tests for bigquery functional classes --- .../google/gcloud/bigquery/DatasetTest.java | 108 +++++++++++++++++- .../com/google/gcloud/bigquery/JobTest.java | 6 + .../com/google/gcloud/bigquery/TableTest.java | 64 +++++++++++ 3 files changed, 177 insertions(+), 1 deletion(-) diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/DatasetTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/DatasetTest.java index 7395d4d18d69..05be4df39773 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/DatasetTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/DatasetTest.java @@ -33,9 +33,12 @@ import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import java.util.Iterator; +import java.util.List; public class DatasetTest { @@ -48,7 +51,12 @@ public class DatasetTest { ExternalTableInfo.builder(TableId.of("dataset", "table2"), ExternalDataConfiguration.of(ImmutableList.of("URI"), Schema.of(), FormatOptions.csv())) .build()); + private static final UserDefinedFunction FUNCTION1 = UserDefinedFunction.inline("inline"); + private static final UserDefinedFunction FUNCTION2 = UserDefinedFunction.inline("gs://b/f"); + private static final List FUNCTIONS = ImmutableList.of(FUNCTION1, FUNCTION2); + @Rule + public ExpectedException thrown = ExpectedException.none(); private BigQuery bigquery; private Dataset dataset; @@ -69,6 +77,12 @@ public void testInfo() throws Exception { replay(bigquery); } + @Test + public void testBigQuery() throws Exception { + assertSame(bigquery, dataset.bigquery()); + replay(bigquery); + } + @Test public void testExists_True() throws Exception { BigQuery.DatasetOption[] expectedOptions = {BigQuery.DatasetOption.fields()}; @@ -119,7 +133,28 @@ public void testUpdate() throws Exception { expect(bigquery.update(updatedInfo)).andReturn(updatedInfo); replay(bigquery); Dataset updatedDataset = dataset.update(updatedInfo); - assertSame(bigquery, dataset.bigquery()); + assertSame(bigquery, updatedDataset.bigquery()); + assertEquals(updatedInfo, updatedDataset.info()); + } + + @Test + public void testUpdateWithDifferentId() throws Exception { + DatasetInfo updatedInfo = DATASET_INFO.toBuilder() + .datasetId(DatasetId.of("dataset2")) + .description("Description") + .build(); + replay(bigquery); + thrown.expect(IllegalArgumentException.class); + dataset.update(updatedInfo); + } + + @Test + public void testUpdateWithOptions() throws Exception { + DatasetInfo updatedInfo = DATASET_INFO.toBuilder().description("Description").build(); + expect(bigquery.update(updatedInfo, BigQuery.DatasetOption.fields())).andReturn(updatedInfo); + replay(bigquery); + Dataset updatedDataset = dataset.update(updatedInfo, BigQuery.DatasetOption.fields()); + assertSame(bigquery, updatedDataset.bigquery()); assertEquals(updatedInfo, updatedDataset.info()); } @@ -150,6 +185,27 @@ public void testList() throws Exception { verify(bigqueryOptions); } + @Test + public void testListWithOptions() throws Exception { + BigQueryOptions bigqueryOptions = createStrictMock(BigQueryOptions.class); + PageImpl tableInfoPage = new PageImpl<>(null, "c", TABLE_INFO_RESULTS); + expect(bigquery.listTables(DATASET_INFO.datasetId(), BigQuery.TableListOption.maxResults(10L))) + .andReturn(tableInfoPage); + expect(bigquery.options()).andReturn(bigqueryOptions); + expect(bigqueryOptions.service()).andReturn(bigquery); + replay(bigquery, bigqueryOptions); + Page
tablePage = dataset.list(BigQuery.TableListOption.maxResults(10L)); + Iterator tableInfoIterator = tableInfoPage.values().iterator(); + Iterator
tableIterator = tablePage.values().iterator(); + while (tableInfoIterator.hasNext() && tableIterator.hasNext()) { + assertEquals(tableInfoIterator.next(), tableIterator.next().info()); + } + assertFalse(tableInfoIterator.hasNext()); + assertFalse(tableIterator.hasNext()); + assertEquals(tableInfoPage.nextPageCursor(), tablePage.nextPageCursor()); + verify(bigqueryOptions); + } + @Test public void testGet() throws Exception { BaseTableInfo info = TableInfo.builder(TableId.of("dataset", "table1"), Schema.of()).build(); @@ -167,6 +223,17 @@ public void testGetNull() throws Exception { assertNull(dataset.get("table1")); } + @Test + public void testGetWithOptions() throws Exception { + BaseTableInfo info = TableInfo.builder(TableId.of("dataset", "table1"), Schema.of()).build(); + expect(bigquery.getTable(TableId.of("dataset", "table1"), BigQuery.TableOption.fields())) + .andReturn(info); + replay(bigquery); + Table table = dataset.get("table1", BigQuery.TableOption.fields()); + assertNotNull(table); + assertEquals(info, table.info()); + } + @Test public void testCreateTable() throws Exception { TableInfo info = TableInfo.builder(TableId.of("dataset", "table1"), Schema.of(FIELD)).build(); @@ -176,6 +243,15 @@ public void testCreateTable() throws Exception { assertEquals(info, table.info()); } + @Test + public void testCreateTableWithOptions() throws Exception { + TableInfo info = TableInfo.builder(TableId.of("dataset", "table1"), Schema.of(FIELD)).build(); + expect(bigquery.create(info, BigQuery.TableOption.fields())).andReturn(info); + replay(bigquery); + Table table = dataset.create("table1", Schema.of(FIELD), BigQuery.TableOption.fields()); + assertEquals(info, table.info()); + } + @Test public void testCreateView() throws Exception { ViewInfo info = ViewInfo.builder(TableId.of("dataset", "table2"), "QUERY").build(); @@ -185,6 +261,24 @@ public void testCreateView() throws Exception { assertEquals(info, table.info()); } + @Test + public void testCreateViewWithUserDefinedFunctions() throws Exception { + ViewInfo info = ViewInfo.builder(TableId.of("dataset", "table2"), "QUERY", FUNCTIONS).build(); + expect(bigquery.create(info)).andReturn(info); + replay(bigquery); + Table table = dataset.create("table2", "QUERY", FUNCTIONS); + assertEquals(info, table.info()); + } + + @Test + public void testCreateViewWithOptions() throws Exception { + ViewInfo info = ViewInfo.builder(TableId.of("dataset", "table2"), "QUERY").build(); + expect(bigquery.create(info, BigQuery.TableOption.fields())).andReturn(info); + replay(bigquery); + Table table = dataset.create("table2", "QUERY", BigQuery.TableOption.fields()); + assertEquals(info, table.info()); + } + @Test public void testCreateExternalTable() throws Exception { ExternalTableInfo info = ExternalTableInfo.builder(TableId.of("dataset", "table3"), @@ -197,6 +291,18 @@ public void testCreateExternalTable() throws Exception { assertEquals(info, table.info()); } + @Test + public void testCreateExternalTableWithOptions() throws Exception { + ExternalTableInfo info = ExternalTableInfo.builder(TableId.of("dataset", "table3"), + ExternalDataConfiguration.of(ImmutableList.of("URI"), Schema.of(), FormatOptions.csv())) + .build(); + expect(bigquery.create(info, BigQuery.TableOption.fields())).andReturn(info); + replay(bigquery); + Table table = dataset.create("table3", ExternalDataConfiguration.of( + ImmutableList.of("URI"), Schema.of(), FormatOptions.csv()), BigQuery.TableOption.fields()); + assertEquals(info, table.info()); + } + @Test public void testLoad() throws Exception { expect(bigquery.getDataset(DATASET_INFO.datasetId().dataset())).andReturn(DATASET_INFO); diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobTest.java index 99b3e80a0206..d99176b6904c 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobTest.java @@ -58,6 +58,12 @@ public void testInfo() throws Exception { replay(bigquery); } + @Test + public void testBigQuery() throws Exception { + assertSame(bigquery, job.bigquery()); + replay(bigquery); + } + @Test public void testExists_True() throws Exception { BigQuery.JobOption[] expectedOptions = {BigQuery.JobOption.fields()}; diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableTest.java index fb022cb13b40..e5b152a91a5f 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableTest.java @@ -36,7 +36,9 @@ import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import java.util.Iterator; import java.util.List; @@ -75,6 +77,8 @@ public class TableTest { private static final Iterable> ROWS = ImmutableList.of( (List) ImmutableList.of(FIELD_VALUE1), ImmutableList.of(FIELD_VALUE2)); + @Rule + public ExpectedException thrown = ExpectedException.none(); private BigQuery bigquery; private Table table; @@ -95,6 +99,12 @@ public void testInfo() throws Exception { replay(bigquery); } + @Test + public void testBigQuery() throws Exception { + assertSame(bigquery, table.bigquery()); + replay(bigquery); + } + @Test public void testExists_True() throws Exception { BigQuery.TableOption[] expectedOptions = {BigQuery.TableOption.fields()}; @@ -139,6 +149,48 @@ public void testReloadWithOptions() throws Exception { assertEquals(updatedInfo, updatedTable.info()); } + @Test + public void testUpdate() throws Exception { + BaseTableInfo updatedInfo = TABLE_INFO.toBuilder().description("Description").build(); + expect(bigquery.update(updatedInfo)).andReturn(updatedInfo); + replay(bigquery); + Table updatedTable = table.update(updatedInfo); + assertSame(bigquery, updatedTable.bigquery()); + assertEquals(updatedInfo, updatedTable.info()); + } + + @Test + public void testUpdateWithDifferentId() throws Exception { + TableInfo updatedInfo = TABLE_INFO.toBuilder() + .tableId(TableId.of("dataset", "table3")) + .description("Description") + .build(); + replay(bigquery); + thrown.expect(IllegalArgumentException.class); + table.update(updatedInfo); + } + + @Test + public void testUpdateWithDifferentDatasetId() throws Exception { + TableInfo updatedInfo = TABLE_INFO.toBuilder() + .tableId(TableId.of("dataset1", "table1")) + .description("Description") + .build(); + replay(bigquery); + thrown.expect(IllegalArgumentException.class); + table.update(updatedInfo); + } + + @Test + public void testUpdateWithOptions() throws Exception { + BaseTableInfo updatedInfo = TABLE_INFO.toBuilder().description("Description").build(); + expect(bigquery.update(updatedInfo, BigQuery.TableOption.fields())).andReturn(updatedInfo); + replay(bigquery); + Table updatedTable = table.update(updatedInfo, BigQuery.TableOption.fields()); + assertSame(bigquery, updatedTable.bigquery()); + assertEquals(updatedInfo, updatedTable.info()); + } + @Test public void testDelete() throws Exception { expect(bigquery.delete(TABLE_INFO.tableId())).andReturn(true); @@ -173,6 +225,18 @@ public void testList() throws Exception { assertTrue(Iterators.elementsEqual(tableDataIterator, dataIterator)); } + @Test + public void testListWithOptions() throws Exception { + PageImpl> tableDataPage = new PageImpl<>(null, "c", ROWS); + expect(bigquery.listTableData(TABLE_ID1, BigQuery.TableDataListOption.maxResults(10L))) + .andReturn(tableDataPage); + replay(bigquery); + Page> dataPage = table.list(BigQuery.TableDataListOption.maxResults(10L)); + Iterator> tableDataIterator = tableDataPage.values().iterator(); + Iterator> dataIterator = dataPage.values().iterator(); + assertTrue(Iterators.elementsEqual(tableDataIterator, dataIterator)); + } + @Test public void testCopyFromString() throws Exception { expect(bigquery.create(COPY_JOB_INFO)).andReturn(COPY_JOB_INFO);