/** * Copyright (C) 2009-2013 FoundationDB, LLC * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.foundationdb.server.test.it.bugs.bug696096; import java.text.MessageFormat; import com.foundationdb.qp.row.Row; import com.foundationdb.server.api.dml.scan.NewRow; import com.foundationdb.server.error.DuplicateKeyException; import com.foundationdb.server.error.ErrorCode; import com.foundationdb.server.error.InvalidOperationException; import com.foundationdb.server.test.it.ITBase; import org.junit.After; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.*; public final class DuplicateKeyValueMessageIT extends ITBase { private int tableId; @Before public void setUp() throws InvalidOperationException { tableId = createTable("sa", "ta", "c0 INT NOT NULL PRIMARY KEY", "c1 int", "c2 int", "c3 int", "name varchar(32)", "UNIQUE (c1, c2)", "CONSTRAINT my_key UNIQUE(c3)" ); writeRows( row(tableId, 10, 11, 12, 13, "from setup"), row(tableId, 20, 21, 22, 23, "from setup") ); } @After public void tearDown() throws InvalidOperationException { expectRows(tableId, row(tableId, 10, 11, 12, 13, "from setup"), row(tableId, 20, 21, 22, 23, "from setup") ); } @Test public void writeDuplicatesPrimary() { duplicateOnWrite("PRIMARY", 10, 91, 92, 93); } @Test public void writeDuplicatesC1() { duplicateOnWrite("c1", 90, 11, 12, 93); } @Test public void writeDuplicatesMyKey() { duplicateOnWrite("my_key", 90, 91, 92, 13); } @Test public void writeDuplicatesMultiple() { duplicateOnWrite("PRIMARY", 10, 11, 12, 13); } @Test public void updateDuplicatesPrimary() { duplicateOnUpdate("PRIMARY", 10, 91, 92, 93); } @Test public void updateDuplicatesC1() { duplicateOnUpdate("c1", 90, 11, 12, 93); } @Test public void updateDuplicatesMyKey() { duplicateOnUpdate("my_key", 90, 91, 92, 13); } @Test public void updateDuplicatesMultiple() { duplicateOnUpdate("PRIMARY", 10, 11, 12, 13); } private static void dupMessageValid(DuplicateKeyException e, String indexName) { final String message = MessageFormat.format(ErrorCode.DUPLICATE_KEY.getMessage(), "sa", "ta", indexName); final String expectedMessagePrefix = message.substring(0, message.length()-5); boolean messageIsValid = e.getShortMessage().startsWith(expectedMessagePrefix); if (!messageIsValid) { String errString = String.format("expected message to start with <%s>, but was <%s>", expectedMessagePrefix, e.getMessage() ); e.printStackTrace(); fail(errString); } } private void duplicateOnWrite(String indexName, int c0, int c1, int c2, int c3) { try { writeRows(row(tableId, c0, c1, c2, c3, "from write")); } catch (DuplicateKeyException e) { dupMessageValid(e, indexName); return; } catch (InvalidOperationException e) { throw new TestException("unexpected exception", e); } fail("Excpected DuplicateKeyExcepton"); } private void duplicateOnUpdate(String indexName, int c0, int c1, int c2, int c3) { try { Row oldRow = row(tableId, 20, 21, 22, 23, "from setup"); Row newRow = row(tableId, c0, c1, c2, c3, "from update"); updateRow(oldRow, newRow); } catch (DuplicateKeyException e) { dupMessageValid(e, indexName); return; } catch (InvalidOperationException e) { throw new TestException("unexpected exception", e); } fail("Excpected DuplicateKeyExcepton"); } }