Merge "[Thread] fix ot-daemon state consistency issues" into main

This commit is contained in:
Treehugger Robot 2024-03-22 06:31:18 +00:00 • committed by Gerrit Code Review
commit 3a9d363bdf
4 changed files with 38 additions and 5 deletions

View file

@ -346,8 +346,8 @@ final class ThreadNetworkControllerService extends IThreadNetworkController.Stub
mTunIfController.getTunFd(),
isEnabled(),
mNsdPublisher,
getMeshcopTxtAttributes(mResources.get()));
otDaemon.registerStateCallback(mOtDaemonCallbackProxy, -1);
getMeshcopTxtAttributes(mResources.get()),
mOtDaemonCallbackProxy);
otDaemon.asBinder().linkToDeath(() -> mHandler.post(this::onOtDaemonDied), 0);
mOtDaemon = otDaemon;
return mOtDaemon;
@ -1358,8 +1358,11 @@ final class ThreadNetworkControllerService extends IThreadNetworkController.Stub
return;
}
final int deviceRole = mState.deviceRole;
mState = null;
// If this device is already STOPPED or DETACHED, do nothing
if (!ThreadNetworkController.isAttached(mState.deviceRole)) {
if (!ThreadNetworkController.isAttached(deviceRole)) {
return;
}

View file

@ -97,13 +97,16 @@ public class ThreadIntegrationTest {
}
@Test
public void otDaemonRestart_JoinedNetworkAndStopped_autoRejoined() throws Exception {
public void otDaemonRestart_JoinedNetworkAndStopped_autoRejoinedAndTunIfStateConsistent()
throws Exception {
mController.joinAndWait(DEFAULT_DATASET);
runShellCommand("stop ot-daemon");
mController.waitForRole(DEVICE_ROLE_DETACHED, CALLBACK_TIMEOUT);
mController.waitForRole(DEVICE_ROLE_LEADER, RESTART_JOIN_TIMEOUT);
assertThat(mOtCtl.isInterfaceUp()).isTrue();
assertThat(runShellCommand("ifconfig thread-wpan")).contains("UP POINTOPOINT RUNNING");
}
@Test
@ -120,8 +123,8 @@ public class ThreadIntegrationTest {
mController.joinAndWait(DEFAULT_DATASET);
mOtCtl.factoryReset();
String ifconfig = runShellCommand("ifconfig thread-wpan");
String ifconfig = runShellCommand("ifconfig thread-wpan");
assertThat(ifconfig).doesNotContain("inet6 addr");
}

View file

@ -62,6 +62,12 @@ public final class OtDaemonController {
.toList();
}
/** Returns {@code true} if the Thread interface is up. */
public boolean isInterfaceUp() {
String output = executeCommand("ifconfig");
return output.contains("up");
}
public String executeCommand(String cmd) {
return SystemUtil.runShellCommand(OT_CTL + " " + cmd);
}

View file

@ -78,7 +78,9 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import java.util.concurrent.CompletableFuture;
@ -489,4 +491,23 @@ public final class ThreadNetworkControllerServiceTest {
assertThat(mFakeOtDaemon.isInitialized()).isTrue();
verify(mockJoinReceiver, times(1)).onSuccess();
}
@Test
public void onOtDaemonDied_joinedNetwork_interfaceStateBackToUp() throws Exception {
mService.initialize();
final IOperationReceiver mockReceiver = mock(IOperationReceiver.class);
mService.join(DEFAULT_ACTIVE_DATASET, mockReceiver);
mTestLooper.dispatchAll();
mTestLooper.moveTimeForward(FakeOtDaemon.JOIN_DELAY.toMillis() + 100);
mTestLooper.dispatchAll();
Mockito.reset(mMockInfraIfController);
mFakeOtDaemon.terminate();
mTestLooper.dispatchAll();
verify(mMockTunIfController, times(1)).onOtDaemonDied();
InOrder inOrder = Mockito.inOrder(mMockTunIfController);
inOrder.verify(mMockTunIfController, times(1)).setInterfaceUp(false);
inOrder.verify(mMockTunIfController, times(1)).setInterfaceUp(true);
}
}