Skip to content

Crashlytics ndk datatransport #1356

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 27 commits into from
Mar 19, 2020
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
54ab654
Add FilesPayload for NDK reports
mrwillis21 Mar 5, 2020
3a1d179
WIP
mrwillis21 Mar 10, 2020
9d5bc02
Implement strategy pattern for native sessions
mrwillis21 Mar 11, 2020
aae1642
Prep for next iteration
mrwillis21 Mar 12, 2020
84c793c
Refactor datatransport abstractions to support polymorphic handling o…
jakeouellette Mar 13, 2020
70be19a
Address feedback
jakeouellette Mar 17, 2020
867e464
style
jakeouellette Mar 17, 2020
89e196e
remove UTF-8
jakeouellette Mar 17, 2020
8371820
Add test classes
jakeouellette Mar 17, 2020
7a76a10
Add tests
jakeouellette Mar 17, 2020
745cd56
Add tests and serialization of ndkpayload
jakeouellette Mar 17, 2020
1d16106
Add settings field for NDK sessions through DataTransport
mrwillis21 Mar 17, 2020
d533e8b
Wire up settings to send procedure
jakeouellette Mar 17, 2020
a924bb2
Interleave native and non-native high priority sessions
jakeouellette Mar 17, 2020
fcc5426
Add session ID abstraction to facilitate deleting NDK reports
jakeouellette Mar 17, 2020
1796c16
Add tests for session coordinator and report persistence
jakeouellette Mar 18, 2020
bcacb59
Make Firebase session ID for native sessions
mrwillis21 Mar 18, 2020
56a4eeb
Add support for sending/deleting native crashes based on the settings…
mrwillis21 Mar 18, 2020
75257bf
Cleanup
mrwillis21 Mar 18, 2020
21313d7
Remove undone testS
jakeouellette Mar 18, 2020
9173669
Cleanup
mrwillis21 Mar 18, 2020
3d231e2
Base ndk sessions on non-ndk sessions
jakeouellette Mar 18, 2020
365d773
Update paths to allow firelog to go to a different filename.
jakeouellette Mar 19, 2020
cba4bff
Make try { } catches less wide
jakeouellette Mar 19, 2020
8d54a9c
Remove old withUserId method
mrwillis21 Mar 19, 2020
f2f3db3
Add null check for withSessionEndFields
mrwillis21 Mar 19, 2020
5c3f488
Replace builder with simpler create method
mrwillis21 Mar 19, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"app": {
"status": "activated",
"report_upload_variant": 2,
"native_report_upload_variant": 2,
"update_required": true
},
"fabric": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"app": {
"status": "new",
"report_upload_variant": 2,
"native_report_upload_variant": 2,
"update_required": true
},
"fabric": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright 2020 Google LLC
//
// 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.firebase.crashlytics.internal.common;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;

import com.google.firebase.crashlytics.internal.model.CrashlyticsReport;
import java.io.IOException;
import org.junit.Test;

public class BytesBackedNativeSessionFileTest {
byte[] testBytes = {0, 2, 20, 10};
byte[] emptyBytes = {};

@Test
public void testAsStream_convertsToStream() throws IOException {
BytesBackedNativeSessionFile nativeSessionFile =
new BytesBackedNativeSessionFile("file", testBytes);
byte[] readBytes = new byte[4];
nativeSessionFile.getStream().read(readBytes);
assertArrayEquals(testBytes, readBytes);
}

@Test
public void testAsStreamWhenEmpty_returnsNull() {
BytesBackedNativeSessionFile nativeSessionFile =
new BytesBackedNativeSessionFile("file", emptyBytes);
assertNull(nativeSessionFile.getStream());
}

@Test
public void testAsFilePayload_convertsToFilePayload() {
BytesBackedNativeSessionFile nativeSessionFile =
new BytesBackedNativeSessionFile("file", testBytes);
CrashlyticsReport.FilesPayload.File filesPayload = nativeSessionFile.asFilePayload();
assertNotNull(filesPayload);
assertArrayEquals(testBytes, filesPayload.getContents());
assertEquals("file", filesPayload.getFilename());
}

@Test
public void testAsFilePayloadWhenEmpty_convertsToNull() {
BytesBackedNativeSessionFile nativeSessionFile =
new BytesBackedNativeSessionFile("file", emptyBytes);
assertNull(nativeSessionFile.asFilePayload());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;

Expand Down Expand Up @@ -116,7 +117,10 @@ protected void setUp() throws Exception {
when(mockFileStore.getFilesDirPath()).thenReturn(testFilesDirectory.getPath());

final SettingsData testSettingsData =
new TestSettingsData(3, CrashlyticsController.REPORT_UPLOAD_VARIANT_LEGACY);
new TestSettingsData(
3,
DataTransportState.REPORT_UPLOAD_VARIANT_LEGACY,
DataTransportState.REPORT_UPLOAD_VARIANT_LEGACY);
appSettingsData = testSettingsData.appData;
sessionSettingsData = testSettingsData.sessionData;

Expand Down Expand Up @@ -563,6 +567,16 @@ public void testLargestFileNameFirst() {
assertTrue(Arrays.equals(expectedOrder, testOrder));
}

@Test
public void testFinalizePreviousNativeSession_finalizesPreviousNativeSession() {
final CrashlyticsController controller = createController();
}

@Test
public void testGetNativeSessionFiles_getsNativeSessionFiles() {
// FIXME:
}

// TODO: There's only ever one open session now that we can close sessions while offline.
// Is that the behavior we want?
/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -610,7 +610,10 @@ private Task<CrashlyticsCore> startCoreAsync(CrashlyticsCore crashlyticsCore) {

SettingsController mockSettingsController = mock(SettingsController.class);
final SettingsData settings =
new TestSettingsData(3, CrashlyticsController.REPORT_UPLOAD_VARIANT_LEGACY);
new TestSettingsData(
3,
DataTransportState.REPORT_UPLOAD_VARIANT_LEGACY,
DataTransportState.REPORT_UPLOAD_VARIANT_LEGACY);
when(mockSettingsController.getSettings()).thenReturn(settings);
when(mockSettingsController.getAppSettings()).thenReturn(Tasks.forResult(settings.appData));

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// Copyright 2020 Google LLC
//
// 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.firebase.crashlytics.internal.common;

import static org.junit.Assert.assertArrayEquals;

import android.content.Context;
import com.google.firebase.crashlytics.internal.CrashlyticsTestCase;
import com.google.firebase.crashlytics.internal.model.CrashlyticsReport;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import org.junit.Test;

public class FileBackedNativeSessionFileTest extends CrashlyticsTestCase {
byte[] testContents = {0, 2, 20, 10};
byte[] emptyContents = {};
File testFile;
File emptyFile;
File missingFile;

@Override
protected void setUp() throws Exception {
super.setUp();
final Context context = getContext();
testFile = new File(context.getFilesDir(), "testFile");
try (FileOutputStream fout = new FileOutputStream(testFile);
ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
stream.write(testContents);
stream.writeTo(fout);
}
emptyFile = new File(context.getFilesDir(), "emptyFile");
emptyFile.createNewFile();
missingFile = new File(context.getFilesDir(), "missingFile");
}

@Override
protected void tearDown() throws Exception {
super.tearDown();
testFile.delete();
emptyFile.delete();
}

@Test
public void testAsStream_convertsToStream() throws IOException {
FileBackedNativeSessionFile nativeSessionFile =
new FileBackedNativeSessionFile("file", testFile);
byte[] readBytes = new byte[4];
nativeSessionFile.getStream().read(readBytes);
assertArrayEquals(testContents, readBytes);
}

@Test
public void testAsStreamWhenEmpty_returnsEmpty() throws IOException {
FileBackedNativeSessionFile nativeSessionFile =
new FileBackedNativeSessionFile("file", emptyFile);
byte[] readBytes = new byte[0];
nativeSessionFile.getStream().read(readBytes);
assertArrayEquals(emptyContents, readBytes);
}

@Test
public void testAsStreamWhenMissing_returnsNull() {
FileBackedNativeSessionFile nativeSessionFile =
new FileBackedNativeSessionFile("file", missingFile);
assertNull(nativeSessionFile.getStream());
}

@Test
public void testAsFilePayload_convertsToFilePayload() {
FileBackedNativeSessionFile nativeSessionFile =
new FileBackedNativeSessionFile("file", testFile);
CrashlyticsReport.FilesPayload.File filesPayload = nativeSessionFile.asFilePayload();
assertNotNull(filesPayload);
assertArrayEquals(testContents, filesPayload.getContents());
assertEquals("file", filesPayload.getFilename());
}

@Test
public void testAsFilePayloadWhenEmpty_returnsEmptyPayload() {
FileBackedNativeSessionFile nativeSessionFile =
new FileBackedNativeSessionFile("file", emptyFile);
CrashlyticsReport.FilesPayload.File filesPayload = nativeSessionFile.asFilePayload();
assertNotNull(filesPayload);
assertArrayEquals(emptyContents, filesPayload.getContents());
assertEquals("file", filesPayload.getFilename());
}

@Test
public void testAsFilePayloadWhenMissing_convertsToNull() {
FileBackedNativeSessionFile nativeSessionFile =
new FileBackedNativeSessionFile("file", missingFile);
assertNull(nativeSessionFile.asFilePayload());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Copyright 2020 Google LLC
//
// 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.firebase.crashlytics.internal.common;

import android.content.Context;
import com.google.firebase.crashlytics.internal.CrashlyticsTestCase;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import org.junit.Test;
import org.mockito.internal.util.collections.Sets;

public class NativeSessionFileGzipperTest extends CrashlyticsTestCase {
byte[] testContents = {0, 2, 20, 10};
File testFile;
File missingFile;
File gzipDir;

@Override
protected void setUp() throws Exception {
super.setUp();
final Context context = getContext();
testFile = new File(context.getFilesDir(), "testFile");
try (FileOutputStream fout = new FileOutputStream(testFile);
ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
stream.write(testContents);
stream.writeTo(fout);
}
File baseDirectory = context.getFilesDir();
missingFile = new File(baseDirectory, "missingFile");
gzipDir = new File(baseDirectory, "gzip");
gzipDir.mkdirs();
}

@Test
public void testProcessNativeSessions_putsFilesInCorrectLocation() throws IOException {
String fileBackedSessionName = "file";
String byteBackedSessionName = "byte";
FileBackedNativeSessionFile fileSession =
new FileBackedNativeSessionFile(fileBackedSessionName, testFile);
BytesBackedNativeSessionFile byteSession =
new BytesBackedNativeSessionFile(byteBackedSessionName, testContents);
List<NativeSessionFile> files = Arrays.asList(fileSession, byteSession);
NativeSessionFileGzipper.processNativeSessions(gzipDir, files);

assertEquals(
Sets.newSet(
new File(gzipDir, fileBackedSessionName), new File(gzipDir, byteBackedSessionName)),
Sets.newSet(gzipDir.listFiles()));
}

@Test
public void testProcessNativeSessionsWhenDataIsNull_putsFilesInCorrectLocation() {
String fileBackedSessionName = "file";
String byteBackedSessionName = "byte";
FileBackedNativeSessionFile fileSession =
new FileBackedNativeSessionFile(fileBackedSessionName, missingFile);
BytesBackedNativeSessionFile byteSession =
new BytesBackedNativeSessionFile(byteBackedSessionName, testContents);
List<NativeSessionFile> files = Arrays.asList(fileSession, byteSession);
NativeSessionFileGzipper.processNativeSessions(gzipDir, files);

assertEquals(
Sets.newSet(new File(gzipDir, byteBackedSessionName)), Sets.newSet(gzipDir.listFiles()));
}
}
Loading