Do not allow DatabaseSchema name/version to be mutated
[ovsdb.git] / library / impl / src / test / java / org / opendaylight / ovsdb / lib / schema / typed / TyperUtilsTest.java
1 /*
2  * Copyright © 2016 Red Hat, Inc. and others. All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.ovsdb.lib.schema.typed;
10
11 import static org.junit.Assert.assertEquals;
12
13 import com.google.common.collect.ImmutableMap;
14 import java.lang.reflect.InvocationTargetException;
15 import java.lang.reflect.Method;
16 import java.util.Collections;
17 import org.junit.Assert;
18 import org.junit.Test;
19 import org.opendaylight.ovsdb.lib.error.SchemaVersionMismatchException;
20 import org.opendaylight.ovsdb.lib.notation.Version;
21 import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
22 import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25
26 /**
27  * Test class for {@link TyperUtils}.
28  */
29 public class TyperUtilsTest {
30     private static final Logger LOG = LoggerFactory.getLogger(TyperUtilsTest.class);
31
32     @TypedTable(name = "TestTypedTable", database = "Open_vSwitch")
33     private class TestTypedTable {
34
35     }
36
37     private class TestUntypedTable {
38
39     }
40
41     /**
42      * Test that {@link TyperUtils#getTableSchema(DatabaseSchema, Class)} returns the appropriate schema when given a
43      * table containing the appropriate schema, for a typed table (annotated).
44      */
45     @Test
46     public void testGetTableSchemaWithIncludedTypedTable() {
47         // Given ...
48         GenericTableSchema testTableSchema = new GenericTableSchema("TestTypedTable");
49         DatabaseSchema dbSchema = new DatabaseSchema("testDb", Version.NULL,
50             ImmutableMap.of(testTableSchema.getName(), testTableSchema));
51
52         // When ...
53         GenericTableSchema tableSchema = TyperUtils.getTableSchema(dbSchema, TestTypedTable.class);
54
55         // Then ...
56         assertEquals(testTableSchema, tableSchema);
57     }
58
59     /**
60      * Test that {@link TyperUtils#getTableSchema(DatabaseSchema, Class)} returns the appropriate schema when given a
61      * table containing the appropriate schema, for an untyped table (non-annotated).
62      */
63     @Test
64     public void testGetTableSchemaWithIncludedUntypedTable() {
65         // Given ...
66         GenericTableSchema testTableSchema = new GenericTableSchema("TestUntypedTable");
67         DatabaseSchema dbSchema = new DatabaseSchema("testDb", Version.NULL,
68             ImmutableMap.of(testTableSchema.getName(), testTableSchema));
69
70         // When ...
71         GenericTableSchema tableSchema = TyperUtils.getTableSchema(dbSchema, TestUntypedTable.class);
72
73         // Then ...
74         assertEquals(testTableSchema, tableSchema);
75     }
76
77     /**
78      * Test that {@link TyperUtils#getTableSchema(DatabaseSchema, Class)} throws an {@link IllegalArgumentException}
79      * when the appropriate table schema isn't present in the database schema (for a typed table).
80      */
81     @Test(expected = IllegalArgumentException.class)
82     public void testGetTableSchemaWithoutIncludedTypedTable() {
83         // Given ...
84         DatabaseSchema dbSchema = new DatabaseSchema("testDb", Version.NULL, Collections.emptyMap());
85
86         // When ...
87         TyperUtils.getTableSchema(dbSchema, TestTypedTable.class);
88     }
89
90     /**
91      * Test that {@link TyperUtils#getTableSchema(DatabaseSchema, Class)} throws an {@link IllegalArgumentException}
92      * when the appropriate table schema isn't present in the database schema (for an untyped table).
93      */
94     @Test(expected = IllegalArgumentException.class)
95     public void testGetTableSchemaWithoutIncludedUntypedTable() {
96         // Given ...
97         DatabaseSchema dbSchema = new DatabaseSchema("testDb", Version.NULL, Collections.emptyMap());
98
99         // When ...
100         TyperUtils.getTableSchema(dbSchema, TestUntypedTable.class);
101     }
102
103     /**
104      * Test that {@link TyperUtils#checkVersion(Version, Version, Version)} detects an old version. (The aim here isn't
105      * to test {@link Version#compareTo(Version)}, that should be done in
106      * {@link org.opendaylight.ovsdb.lib.notation.VersionTest}).
107      */
108     @Test(expected = SchemaVersionMismatchException.class)
109     public void testCheckOldVersionFails() throws SchemaVersionMismatchException {
110         callCheckVersion(new Version(1, 0, 0), new Version(1, 1, 0), Version.NULL);
111     }
112
113     /**
114      * Test that {@link TyperUtils#checkVersion(Version, Version, Version)} detects a new version.
115      */
116     @Test(expected = SchemaVersionMismatchException.class)
117     public void testCheckNewVersionFails() throws SchemaVersionMismatchException {
118         callCheckVersion(new Version(2, 0, 0), Version.NULL, new Version(1, 1, 0));
119     }
120
121     /**
122      * Test that {@link TyperUtils#checkVersion(Version, Version, Version)} accepts null boundaries.
123      */
124     @Test
125     public void testCheckNullVersionsSucceed() throws SchemaVersionMismatchException {
126         callCheckVersion(new Version(2, 0, 0), Version.NULL, Version.NULL);
127         // This check succeeds in the absence of an exception
128     }
129
130     /**
131      * Test that {@link TyperUtils#checkVersion(Version, Version, Version)} accepts the lower boundary version.
132      */
133     @Test
134     public void testCheckLowerVersionBoundarySucceeds() throws SchemaVersionMismatchException {
135         callCheckVersion(new Version(2, 0, 0), new Version(2, 0, 0), Version.NULL);
136         // This check succeeds in the absence of an exception
137     }
138
139     /**
140      * Test that {@link TyperUtils#checkVersion(Version, Version, Version)} accepts the upper boundary version.
141      */
142     @Test
143     public void testCheckUpperVersionBoundarySucceeds() throws SchemaVersionMismatchException {
144         callCheckVersion(new Version(2, 0, 0), Version.NULL, new Version(2, 0, 0));
145         // This check succeeds in the absence of an exception
146     }
147
148     /**
149      * Test that {@link TyperUtils#checkVersion(Version, Version, Version)} accepts both boundary versions.
150      */
151     @Test
152     public void testCheckSingleVersionBoundarySucceeds() throws SchemaVersionMismatchException {
153         callCheckVersion(new Version(2, 0, 0), new Version(2, 0, 0), new Version(2, 0, 0));
154         // This check succeeds in the absence of an exception
155     }
156
157     /**
158      * Test that {@link TyperUtils#checkVersion(Version, Version, Version)} accepts a version within the boundaries
159      * (strictly).
160      */
161     @Test
162     public void testCheckVersionWithinBoundariesSucceeds() throws SchemaVersionMismatchException {
163         callCheckVersion(new Version(1, 1, 0), new Version(1, 0, 0), new Version(2, 0, 0));
164         // This check succeeds in the absence of an exception
165     }
166
167     /**
168      * Call {@link TyperUtils#checkVersion(Version, Version, Version)}.
169      *
170      * @param schema The schema version (to be checked).
171      * @param from The minimum supported version.
172      * @param to The maximum supported version.
173      * @throws SchemaVersionMismatchException if the schema version isn't supported.
174      */
175     // We extract the real cause, which “loses” the original cause, but that’s fine
176     @SuppressWarnings("checkstyle:AvoidHidingCauseException")
177     private static void callCheckVersion(final Version schema, final Version from, final Version to) {
178         try {
179             Method method =
180                     TyperUtils.class.getDeclaredMethod("checkVersion", Version.class, Version.class, Version.class);
181             method.setAccessible(true);
182             method.invoke(TyperUtils.class, schema, from, to);
183         } catch (NoSuchMethodException e) {
184             LOG.error("Can't find TyperUtils::checkVersion(), TyperUtilsTest::callCheckVersion() may be obsolete", e);
185         } catch (IllegalAccessException e) {
186             LOG.error("Error invoking TyperUtils::checkVersion(), please check TyperUtilsTest::callCheckVersion()", e);
187         } catch (InvocationTargetException e) {
188             final Throwable cause = e.getCause();
189             if (cause instanceof SchemaVersionMismatchException) {
190                 throw (SchemaVersionMismatchException) cause;
191             }
192             LOG.error("Unexpected exception thrown by TyperUtils::checkVersion()", cause);
193             Assert.fail("Unexpected exception thrown by TyperUtils::checkVersion()");
194         }
195     }
196 }