Skip to content

Commit 43aa188

Browse files
committed
Added state simulations
1 parent 88347e1 commit 43aa188

File tree

2 files changed

+263
-26
lines changed

2 files changed

+263
-26
lines changed

transport/transport-runtime/src/test/java/com/google/android/datatransport/runtime/scheduling/persistence/SchemaManagerMigrationTest.java

Lines changed: 81 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,73 +13,128 @@
1313
// limitations under the License.
1414
package com.google.android.datatransport.runtime.scheduling.persistence;
1515

16+
import android.content.ContentValues;
17+
import android.database.sqlite.SQLiteDatabase;
18+
1619
import static com.google.android.datatransport.runtime.scheduling.persistence.SchemaManager.DB_NAME;
1720
import static com.google.android.datatransport.runtime.scheduling.persistence.SchemaManager.SCHEMA_VERSION;
1821
import static com.google.common.truth.Truth.assertThat;
1922

20-
import android.content.ContentValues;
21-
import android.database.sqlite.SQLiteDatabase;
2223
import androidx.test.core.app.ApplicationProvider;
23-
import com.google.android.datatransport.Encoding;
24-
import com.google.android.datatransport.Priority;
25-
import com.google.android.datatransport.runtime.EncodedPayload;
24+
2625
import com.google.android.datatransport.runtime.EventInternal;
2726
import com.google.android.datatransport.runtime.TransportContext;
28-
import com.google.android.datatransport.runtime.time.TestClock;
29-
import com.google.android.datatransport.runtime.time.UptimeClock;
3027
import com.google.android.datatransport.runtime.util.PriorityMapping;
31-
import java.nio.charset.Charset;
28+
3229
import java.util.ArrayList;
33-
import java.util.Arrays;
3430
import java.util.Collection;
31+
import java.util.HashMap;
32+
import java.util.List;
3533
import java.util.Map;
36-
import org.junit.Assert;
34+
3735
import org.junit.Test;
3836
import org.junit.runner.RunWith;
3937
import org.robolectric.ParameterizedRobolectricTestRunner;
40-
import org.robolectric.RobolectricTestRunner;
4138

4239
@RunWith(ParameterizedRobolectricTestRunner.class)
4340
public class SchemaManagerMigrationTest {
44-
private final int toVersion;
45-
private final int fromVersion;
41+
private final int highVersion;
42+
private final int lowVersion;
4643

44+
private static Map<Integer, StateSimulations.StateSimulator> simulatorMap = new HashMap<>();
45+
static {
46+
simulatorMap.put(1, new StateSimulations.V1());
47+
simulatorMap.put(2, new StateSimulations.V2());
48+
simulatorMap.put(3, new StateSimulations.V3());
49+
simulatorMap.put(4, new StateSimulations.V4());
50+
}
4751
@ParameterizedRobolectricTestRunner.Parameters(name = "lowVersion = {0}, highVersion = {1}")
4852
public static Collection<Object[]> data() {
4953
Collection<Object[]> params = new ArrayList<>();
50-
for(int fromVersion = 1 ; fromVersion < SCHEMA_VERSION; fromVersion ++) {
51-
for (int toVersion = fromVersion + 1; toVersion <= SCHEMA_VERSION; toVersion++) {
52-
params.add(new Object[]{fromVersion, toVersion});
54+
for(int lowVersion = 1 ; lowVersion < SCHEMA_VERSION; lowVersion ++) {
55+
for (int highVersion = lowVersion + 1; highVersion <= SCHEMA_VERSION; highVersion++) {
56+
params.add(new Object[]{lowVersion, highVersion});
5357
}
5458
}
5559
return params;
5660
}
5761

58-
public SchemaManagerMigrationTest(int fromVersion, int toVersion) {
59-
this.fromVersion = fromVersion;
60-
this.toVersion = toVersion;
62+
public SchemaManagerMigrationTest(int lowVersion, int highVersion) {
63+
this.lowVersion = lowVersion;
64+
this.highVersion = highVersion;
6165
}
6266

6367
@Test
6468
public void upgrade_migratesSuccessfully() {
6569
SchemaManager schemaManager =
66-
new SchemaManager(ApplicationProvider.getApplicationContext(), DB_NAME, fromVersion);
67-
schemaManager.onUpgrade(schemaManager.getWritableDatabase(), fromVersion, toVersion);
70+
new SchemaManager(ApplicationProvider.getApplicationContext(), DB_NAME, lowVersion);
71+
schemaManager.onUpgrade(schemaManager.getWritableDatabase(), lowVersion, highVersion);
72+
simulatorMap.get(highVersion).simulate(schemaManager);
6873
}
6974

7075
@Test
7176
public void downgrade_migratesSuccessfully() {
7277
SchemaManager schemaManager =
73-
new SchemaManager(ApplicationProvider.getApplicationContext(), DB_NAME, toVersion);
74-
schemaManager.onDowngrade(schemaManager.getWritableDatabase(), toVersion, fromVersion);
78+
new SchemaManager(ApplicationProvider.getApplicationContext(), DB_NAME, highVersion);
79+
schemaManager.onDowngrade(schemaManager.getWritableDatabase(), highVersion, lowVersion);
80+
simulatorMap.get(lowVersion).simulate(schemaManager);
7581
}
7682

7783
@Test
7884
public void downgrade_upgrade_migratesSuccessfully() {
7985
SchemaManager schemaManager =
80-
new SchemaManager(ApplicationProvider.getApplicationContext(), DB_NAME, toVersion);
86+
new SchemaManager(ApplicationProvider.getApplicationContext(), DB_NAME, highVersion);
87+
88+
schemaManager.onDowngrade(schemaManager.getWritableDatabase(), highVersion, lowVersion);
89+
simulatorMap.get(lowVersion).simulate(schemaManager);
90+
91+
schemaManager.onUpgrade(schemaManager.getWritableDatabase(), lowVersion, highVersion);
92+
simulatorMap.get(highVersion).simulate(schemaManager);
93+
}
94+
95+
@Test
96+
public void upgrade_downgrade_upgrade_migratesSuccessfully() {
97+
SchemaManager schemaManager =
98+
new SchemaManager(ApplicationProvider.getApplicationContext(), DB_NAME, lowVersion);
99+
100+
schemaManager.onUpgrade(schemaManager.getWritableDatabase(), lowVersion, highVersion);
101+
simulatorMap.get(highVersion).simulate(schemaManager);
102+
103+
schemaManager.onDowngrade(schemaManager.getWritableDatabase(), highVersion, lowVersion);
104+
simulatorMap.get(lowVersion).simulate(schemaManager);
105+
106+
schemaManager.onUpgrade(schemaManager.getWritableDatabase(), lowVersion, highVersion);
107+
simulatorMap.get(highVersion).simulate(schemaManager);
108+
}
109+
110+
private PersistedEvent simulatedPersistOnV1Database(
111+
SchemaManager schemaManager, TransportContext transportContext, EventInternal eventInternal) {
112+
SQLiteDatabase db = schemaManager.getWritableDatabase();
113+
114+
ContentValues record = new ContentValues();
115+
record.put("backend_name", transportContext.getBackendName());
116+
record.put("priority", PriorityMapping.toInt(transportContext.getPriority()));
117+
record.put("next_request_ms", 0);
118+
long contextId = db.insert("transport_contexts", null, record);
119+
120+
ContentValues values = new ContentValues();
121+
values.put("context_id", contextId);
122+
values.put("transport_name", eventInternal.getTransportName());
123+
values.put("timestamp_ms", eventInternal.getEventMillis());
124+
values.put("uptime_ms", eventInternal.getUptimeMillis());
125+
values.put("payload", eventInternal.getPayload());
126+
values.put("code", eventInternal.getCode());
127+
values.put("num_attempts", 0);
128+
long newEventId = db.insert("events", null, values);
129+
130+
for (Map.Entry<String, String> entry : eventInternal.getMetadata().entrySet()) {
131+
ContentValues metadata = new ContentValues();
132+
metadata.put("event_id", newEventId);
133+
metadata.put("name", entry.getKey());
134+
metadata.put("value", entry.getValue());
135+
db.insert("event_metadata", null, metadata);
136+
}
81137

82-
schemaManager.onDowngrade(schemaManager.getWritableDatabase(), toVersion, fromVersion);
83-
schemaManager.onUpgrade(schemaManager.getWritableDatabase(), fromVersion, toVersion);
138+
return PersistedEvent.create(newEventId, transportContext, eventInternal);
84139
}
85140
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
// Copyright 2020 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package com.google.android.datatransport.runtime.scheduling.persistence;
16+
17+
import android.content.ContentValues;
18+
import android.database.sqlite.SQLiteDatabase;
19+
20+
import com.google.android.datatransport.Encoding;
21+
import com.google.android.datatransport.Priority;
22+
import com.google.android.datatransport.runtime.EncodedPayload;
23+
import com.google.android.datatransport.runtime.util.PriorityMapping;
24+
25+
import java.nio.charset.Charset;
26+
import java.util.Random;
27+
28+
import static com.google.common.truth.Truth.assertThat;
29+
30+
class StateSimulations {
31+
private static final Encoding PROTOBUF_ENCODING = Encoding.of("proto");
32+
33+
interface StateSimulator {
34+
void simulate(SchemaManager schemaManager);
35+
}
36+
static class V1 implements StateSimulator {
37+
@Override
38+
public void simulate(SchemaManager schemaManager) {
39+
SQLiteDatabase db = schemaManager.getWritableDatabase();
40+
41+
ContentValues record = new ContentValues();
42+
record.put("backend_name", "b1");
43+
record.put("priority", PriorityMapping.toInt(Priority.DEFAULT));
44+
record.put("next_request_ms", 0);
45+
long contextId = db.insert("transport_contexts", null, record);
46+
assertThat(contextId).isNotEqualTo(-1);
47+
48+
ContentValues values = new ContentValues();
49+
values.put("context_id", contextId);
50+
values.put("transport_name", "42");
51+
values.put("timestamp_ms", 1);
52+
values.put("uptime_ms", 2);
53+
values.put("payload", new EncodedPayload(PROTOBUF_ENCODING, "Hello".getBytes(Charset.defaultCharset())).getBytes());
54+
values.put("code", 1);
55+
values.put("num_attempts", 0);
56+
long newEventId = db.insert("events", null, values);
57+
assertThat(newEventId).isNotEqualTo(-1);
58+
59+
ContentValues metadata = new ContentValues();
60+
metadata.put("event_id", newEventId);
61+
metadata.put("name", "key1");
62+
metadata.put("value", "value1");
63+
long metadataId = db.insert("event_metadata", null, metadata);
64+
assertThat(metadataId).isNotEqualTo(-1);
65+
}
66+
}
67+
68+
static class V2 implements StateSimulator {
69+
@Override
70+
public void simulate(SchemaManager schemaManager) {
71+
SQLiteDatabase db = schemaManager.getWritableDatabase();
72+
Random rd = new Random();
73+
byte[] arr = new byte[7];
74+
rd.nextBytes(arr);
75+
76+
ContentValues record = new ContentValues();
77+
record.put("backend_name", "b1");
78+
record.put("priority", PriorityMapping.toInt(Priority.DEFAULT));
79+
record.put("next_request_ms", 0);
80+
record.put("extras", arr);
81+
long contextId = db.insert("transport_contexts", null, record);
82+
assertThat(contextId).isNotEqualTo(-1);
83+
84+
ContentValues values = new ContentValues();
85+
values.put("context_id", contextId);
86+
values.put("transport_name", "42");
87+
values.put("timestamp_ms", 1);
88+
values.put("uptime_ms", 2);
89+
values.put("payload", new EncodedPayload(PROTOBUF_ENCODING, "Hello".getBytes(Charset.defaultCharset())).getBytes());
90+
values.put("code", 1);
91+
values.put("num_attempts", 0);
92+
long newEventId = db.insert("events", null, values);
93+
assertThat(newEventId).isNotEqualTo(-1);
94+
95+
ContentValues metadata = new ContentValues();
96+
metadata.put("event_id", newEventId);
97+
metadata.put("name", "key1");
98+
metadata.put("value", "value1");
99+
long metadataId = db.insert("event_metadata", null, metadata);
100+
assertThat(metadataId).isNotEqualTo(-1);
101+
}
102+
}
103+
static class V3 implements StateSimulator {
104+
@Override
105+
public void simulate(SchemaManager schemaManager) {
106+
SQLiteDatabase db = schemaManager.getWritableDatabase();
107+
Random rd = new Random();
108+
byte[] arr = new byte[7];
109+
rd.nextBytes(arr);
110+
111+
ContentValues record = new ContentValues();
112+
record.put("backend_name", "b1");
113+
record.put("priority", PriorityMapping.toInt(Priority.DEFAULT));
114+
record.put("next_request_ms", 0);
115+
record.put("extras", arr);
116+
long contextId = db.insert("transport_contexts", null, record);
117+
assertThat(contextId).isNotEqualTo(-1);
118+
119+
ContentValues values = new ContentValues();
120+
values.put("context_id", contextId);
121+
values.put("transport_name", "42");
122+
values.put("timestamp_ms", 1);
123+
values.put("uptime_ms", 2);
124+
values.put("payload", new EncodedPayload(PROTOBUF_ENCODING, "Hello".getBytes(Charset.defaultCharset())).getBytes());
125+
values.put("code", 1);
126+
values.put("num_attempts", 0);
127+
values.put("payload_encoding" ,"encoding");
128+
long newEventId = db.insert("events", null, values);
129+
assertThat(newEventId).isNotEqualTo(-1);
130+
131+
ContentValues metadata = new ContentValues();
132+
metadata.put("event_id", newEventId);
133+
metadata.put("name", "key1");
134+
metadata.put("value", "value1");
135+
long metadataId = db.insert("event_metadata", null, metadata);
136+
assertThat(metadataId).isNotEqualTo(-1);
137+
}
138+
}
139+
static class V4 implements StateSimulator {
140+
@Override
141+
public void simulate(SchemaManager schemaManager) {
142+
SQLiteDatabase db = schemaManager.getWritableDatabase();
143+
Random rd = new Random();
144+
byte[] arr = new byte[7];
145+
rd.nextBytes(arr);
146+
147+
ContentValues record = new ContentValues();
148+
record.put("backend_name", "b1");
149+
record.put("priority", PriorityMapping.toInt(Priority.DEFAULT));
150+
record.put("next_request_ms", 0);
151+
record.put("extras", arr);
152+
long contextId = db.insert("transport_contexts", null, record);
153+
assertThat(contextId).isNotEqualTo(-1);
154+
155+
ContentValues values = new ContentValues();
156+
values.put("context_id", contextId);
157+
values.put("transport_name", "42");
158+
values.put("timestamp_ms", 1);
159+
values.put("uptime_ms", 2);
160+
values.put("payload", new EncodedPayload(PROTOBUF_ENCODING, "Hello".getBytes(Charset.defaultCharset())).getBytes());
161+
values.put("code", 1);
162+
values.put("num_attempts", 0);
163+
values.put("payload_encoding" ,"encoding");
164+
values.put("inline" ,true);
165+
long newEventId = db.insert("events", null, values);
166+
assertThat(newEventId).isNotEqualTo(-1);
167+
168+
ContentValues payloads = new ContentValues();
169+
values.put("sequence_num", newEventId);
170+
values.put("event_id", "42");
171+
values.put("bytes", "event".getBytes());
172+
long payloadId = db.insert("event_payloads", null, payloads);
173+
174+
ContentValues metadata = new ContentValues();
175+
metadata.put("event_id", newEventId);
176+
metadata.put("name", "key1");
177+
metadata.put("value", "value1");
178+
long metadataId = db.insert("event_metadata", null, metadata);
179+
assertThat(metadataId).isNotEqualTo(-1);
180+
}
181+
}
182+
}

0 commit comments

Comments
 (0)